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)