Mercurial > mplayer.hg
comparison spudec.c @ 31762:da0bfd02286c
Support for image highlights for dvdnav menus.
Does not work 100% reliably and needs -sid 0.
author | reimar |
---|---|
date | Mon, 26 Jul 2010 19:41:04 +0000 |
parents | 54f1eb233db9 |
children | e9458f705c3f |
comparison
equal
deleted
inserted
replaced
31761:54f1eb233db9 | 31762:da0bfd02286c |
---|---|
74 unsigned int width, height, stride; | 74 unsigned int width, height, stride; |
75 unsigned int start_pts, end_pts; | 75 unsigned int start_pts, end_pts; |
76 packet_t *next; | 76 packet_t *next; |
77 }; | 77 }; |
78 | 78 |
79 struct palette_crop_cache { | |
80 int valid; | |
81 uint32_t palette; | |
82 int sx, sy, ex, ey; | |
83 int result; | |
84 }; | |
85 | |
79 typedef struct { | 86 typedef struct { |
80 packet_t *queue_head; | 87 packet_t *queue_head; |
81 packet_t *queue_tail; | 88 packet_t *queue_tail; |
82 unsigned int global_palette[16]; | 89 unsigned int global_palette[16]; |
83 unsigned int orig_frame_width, orig_frame_height; | 90 unsigned int orig_frame_width, orig_frame_height; |
96 unsigned int start_row; | 103 unsigned int start_row; |
97 unsigned int width, height, stride; | 104 unsigned int width, height, stride; |
98 size_t image_size; /* Size of the image buffer */ | 105 size_t image_size; /* Size of the image buffer */ |
99 unsigned char *image; /* Grayscale value */ | 106 unsigned char *image; /* Grayscale value */ |
100 unsigned char *aimage; /* Alpha value */ | 107 unsigned char *aimage; /* Alpha value */ |
108 unsigned int pal_start_col, pal_start_row; | |
109 unsigned int pal_width, pal_height; | |
101 unsigned char *pal_image; /* palette entry value */ | 110 unsigned char *pal_image; /* palette entry value */ |
102 unsigned int scaled_frame_width, scaled_frame_height; | 111 unsigned int scaled_frame_width, scaled_frame_height; |
103 unsigned int scaled_start_col, scaled_start_row; | 112 unsigned int scaled_start_col, scaled_start_row; |
104 unsigned int scaled_width, scaled_height, scaled_stride; | 113 unsigned int scaled_width, scaled_height, scaled_stride; |
105 size_t scaled_image_size; | 114 size_t scaled_image_size; |
109 int font_start_level; /* Darkest value used for the computed font */ | 118 int font_start_level; /* Darkest value used for the computed font */ |
110 const vo_functions_t *hw_spu; | 119 const vo_functions_t *hw_spu; |
111 int spu_changed; | 120 int spu_changed; |
112 unsigned int forced_subs_only; /* flag: 0=display all subtitle, !0 display only forced subtitles */ | 121 unsigned int forced_subs_only; /* flag: 0=display all subtitle, !0 display only forced subtitles */ |
113 unsigned int is_forced_sub; /* true if current subtitle is a forced subtitle */ | 122 unsigned int is_forced_sub; /* true if current subtitle is a forced subtitle */ |
123 | |
124 struct palette_crop_cache palette_crop_cache; | |
114 } spudec_handle_t; | 125 } spudec_handle_t; |
115 | 126 |
116 static void spudec_queue_packet(spudec_handle_t *this, packet_t *packet) | 127 static void spudec_queue_packet(spudec_handle_t *this, packet_t *packet) |
117 { | 128 { |
118 if (this->queue_head == NULL) | 129 if (this->queue_head == NULL) |
217 if (this->image_size < this->stride * this->height) { | 228 if (this->image_size < this->stride * this->height) { |
218 if (this->image != NULL) { | 229 if (this->image != NULL) { |
219 free(this->image); | 230 free(this->image); |
220 free(this->pal_image); | 231 free(this->pal_image); |
221 this->image_size = 0; | 232 this->image_size = 0; |
233 this->pal_width = this->pal_height = 0; | |
222 } | 234 } |
223 this->image = malloc(2 * this->stride * this->height); | 235 this->image = malloc(2 * this->stride * this->height); |
224 if (this->image) { | 236 if (this->image) { |
225 this->image_size = this->stride * this->height; | 237 this->image_size = this->stride * this->height; |
226 this->aimage = this->image + this->image_size; | 238 this->aimage = this->image + this->image_size; |
252 *dsta++ = *dst++ = 0; | 264 *dsta++ = *dst++ = 0; |
253 src += src_stride; | 265 src += src_stride; |
254 } | 266 } |
255 } | 267 } |
256 | 268 |
257 static void spudec_process_data(spudec_handle_t *this, packet_t *packet) | 269 static int apply_palette_crop(spudec_handle_t *this, |
258 { | 270 unsigned crop_x, unsigned crop_y, |
271 unsigned crop_w, unsigned crop_h) | |
272 { | |
273 int i; | |
274 uint8_t *src; | |
259 uint16_t pal[4]; | 275 uint16_t pal[4]; |
260 unsigned int i, x, y; | 276 unsigned stride = (crop_w + 7) & ~7; |
261 uint8_t *dst; | 277 if (crop_x > this->pal_width || crop_y > this->pal_height || |
262 | 278 crop_w > this->pal_width - crop_x || crop_h > this->pal_width - crop_y || |
263 this->scaled_frame_width = 0; | 279 crop_w > 0x8000 || crop_h > 0x8000 || |
264 this->scaled_frame_height = 0; | 280 stride * crop_h > this->image_size) { |
265 this->start_col = packet->start_col; | 281 return 0; |
266 this->start_row = packet->start_row; | 282 } |
267 this->height = packet->height; | |
268 this->width = packet->width; | |
269 this->stride = packet->stride; | |
270 for (i = 0; i < 4; ++i) { | 283 for (i = 0; i < 4; ++i) { |
271 int color; | 284 int color; |
272 int alpha = packet->alpha[i]; | 285 int alpha = this->alpha[i]; |
273 // extend 4 -> 8 bit | 286 // extend 4 -> 8 bit |
274 alpha |= alpha << 4; | 287 alpha |= alpha << 4; |
275 if (this->custom && (this->cuspal[i] >> 31) != 0) | 288 if (this->custom && (this->cuspal[i] >> 31) != 0) |
276 alpha = 0; | 289 alpha = 0; |
277 color = this->custom ? this->cuspal[i] : | 290 color = this->custom ? this->cuspal[i] : |
278 this->global_palette[packet->palette[i]]; | 291 this->global_palette[this->palette[i]]; |
279 color = (color >> 16) & 0xff; | 292 color = (color >> 16) & 0xff; |
280 // convert to MPlayer-style gray/alpha palette | 293 // convert to MPlayer-style gray/alpha palette |
281 color = FFMIN(color, alpha); | 294 color = FFMIN(color, alpha); |
282 pal[i] = (-alpha << 8) | color; | 295 pal[i] = (-alpha << 8) | color; |
283 } | 296 } |
284 | 297 src = this->pal_image + crop_y * this->pal_width + crop_x; |
285 if (!spudec_alloc_image(this, this->stride, this->height)) | 298 pal2gray_alpha(pal, src, this->pal_width, |
299 this->image, this->aimage, stride, | |
300 crop_w, crop_h); | |
301 this->width = crop_w; | |
302 this->height = crop_h; | |
303 this->stride = stride; | |
304 this->start_col = this->pal_start_col + crop_x; | |
305 this->start_row = this->pal_start_row + crop_y; | |
306 spudec_cut_image(this); | |
307 | |
308 // reset scaled image | |
309 this->scaled_frame_width = 0; | |
310 this->scaled_frame_height = 0; | |
311 this->palette_crop_cache.valid = 0; | |
312 return 1; | |
313 } | |
314 | |
315 int spudec_apply_palette_crop(void *this, uint32_t palette, | |
316 int sx, int sy, int ex, int ey) | |
317 { | |
318 spudec_handle_t *spu = this; | |
319 struct palette_crop_cache *c = &spu->palette_crop_cache; | |
320 if (c->valid && c->palette == palette && | |
321 c->sx == sx && c->sy == sy && c->ex == ex && c->ey == ey) | |
322 return c->result; | |
323 spu->palette[0] = (palette >> 28) & 0xf; | |
324 spu->palette[1] = (palette >> 24) & 0xf; | |
325 spu->palette[2] = (palette >> 20) & 0xf; | |
326 spu->palette[3] = (palette >> 16) & 0xf; | |
327 spu->alpha[0] = (palette >> 12) & 0xf; | |
328 spu->alpha[1] = (palette >> 8) & 0xf; | |
329 spu->alpha[2] = (palette >> 4) & 0xf; | |
330 spu->alpha[3] = palette & 0xf; | |
331 spu->spu_changed = 1; | |
332 c->result = apply_palette_crop(spu, | |
333 sx - spu->pal_start_col, sy - spu->pal_start_row, | |
334 ex - sx, ey - sy); | |
335 c->palette = palette; | |
336 c->sx = sx; c->sy = sy; | |
337 c->ex = ex; c->ey = ey; | |
338 c->valid = 1; | |
339 return c->result; | |
340 } | |
341 | |
342 static void spudec_process_data(spudec_handle_t *this, packet_t *packet) | |
343 { | |
344 unsigned int i, x, y; | |
345 uint8_t *dst; | |
346 | |
347 if (!spudec_alloc_image(this, packet->stride, packet->height)) | |
286 return; | 348 return; |
349 | |
350 this->pal_start_col = packet->start_col; | |
351 this->pal_start_row = packet->start_row; | |
352 this->pal_height = packet->height; | |
353 this->pal_width = packet->width; | |
354 this->stride = packet->stride; | |
355 memcpy(this->palette, packet->palette, sizeof(this->palette)); | |
356 memcpy(this->alpha, packet->alpha, sizeof(this->alpha)); | |
287 | 357 |
288 i = packet->current_nibble[1]; | 358 i = packet->current_nibble[1]; |
289 x = 0; | 359 x = 0; |
290 y = 0; | 360 y = 0; |
291 dst = this->pal_image; | 361 dst = this->pal_image; |
292 while (packet->current_nibble[0] < i | 362 while (packet->current_nibble[0] < i |
293 && packet->current_nibble[1] / 2 < packet->control_start | 363 && packet->current_nibble[1] / 2 < packet->control_start |
294 && y < this->height) { | 364 && y < this->pal_height) { |
295 unsigned int len, color; | 365 unsigned int len, color; |
296 unsigned int rle = 0; | 366 unsigned int rle = 0; |
297 rle = get_nibble(packet); | 367 rle = get_nibble(packet); |
298 if (rle < 0x04) { | 368 if (rle < 0x04) { |
299 if (rle == 0) { | 369 if (rle == 0) { |
304 rle = (rle << 4) | get_nibble(packet); | 374 rle = (rle << 4) | get_nibble(packet); |
305 } | 375 } |
306 color = 3 - (rle & 0x3); | 376 color = 3 - (rle & 0x3); |
307 len = rle >> 2; | 377 len = rle >> 2; |
308 x += len; | 378 x += len; |
309 if (len == 0 || x >= this->width) { | 379 if (len == 0 || x >= this->pal_width) { |
310 len += this->width - x; | 380 len += this->pal_width - x; |
311 next_line(packet); | 381 next_line(packet); |
312 x = 0; | 382 x = 0; |
313 ++y; | 383 ++y; |
314 } | 384 } |
315 memset(dst, color, len); | 385 memset(dst, color, len); |
316 dst += len; | 386 dst += len; |
317 } | 387 } |
318 pal2gray_alpha(pal, this->pal_image, this->width, | 388 apply_palette_crop(this, 0, 0, this->pal_width, this->pal_height); |
319 this->image, this->aimage, this->stride, | |
320 this->width, this->height); | |
321 spudec_cut_image(this); | |
322 } | 389 } |
323 | 390 |
324 | 391 |
325 /* | 392 /* |
326 This function tries to create a usable palette. | 393 This function tries to create a usable palette. |
1255 spu->image = NULL; | 1322 spu->image = NULL; |
1256 spu->aimage = NULL; | 1323 spu->aimage = NULL; |
1257 free(spu->pal_image); | 1324 free(spu->pal_image); |
1258 spu->pal_image = NULL; | 1325 spu->pal_image = NULL; |
1259 spu->image_size = 0; | 1326 spu->image_size = 0; |
1327 spu->pal_width = spu->pal_height = 0; | |
1260 free(spu); | 1328 free(spu); |
1261 } | 1329 } |
1262 } | 1330 } |
1263 | 1331 |
1264 void spudec_set_hw_spu(void *this, const vo_functions_t *hw_spu) | 1332 void spudec_set_hw_spu(void *this, const vo_functions_t *hw_spu) |