Commit 8ff238b5 authored by michael's avatar michael

subs.diff fixes a couple of minor bugs in my DVB subtitle decoder, and also fixes a few

problems in the DVD decoder (the palette entries were being read
back-to-front, and the timing conversions were slighly off)
patch by (Ian Caulfield: imc25, cam ac uk)


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@4520 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 9ab81b21
...@@ -1310,9 +1310,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf, ...@@ -1310,9 +1310,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf,
sub->num_rects = ctx->display_list_size; sub->num_rects = ctx->display_list_size;
if (sub->num_rects == 0) if (sub->num_rects > 0)
return 0;
sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects); sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects);
i = 0; i = 0;
...@@ -1447,7 +1445,7 @@ static int dvbsub_decode(AVCodecContext *avctx, ...@@ -1447,7 +1445,7 @@ static int dvbsub_decode(AVCodecContext *avctx,
return -1; return -1;
} }
return 0; return buf_size;
} }
......
...@@ -107,20 +107,21 @@ static void guess_palette(uint32_t *rgba_palette, ...@@ -107,20 +107,21 @@ static void guess_palette(uint32_t *rgba_palette,
if (nb_opaque_colors == 0) if (nb_opaque_colors == 0)
return; return;
j = 0; j = nb_opaque_colors;
memset(color_used, 0, 16); memset(color_used, 0, 16);
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
if (alpha[i] != 0) { if (alpha[i] != 0) {
if (!color_used[palette[i]]) { if (!color_used[palette[i]]) {
level = (0xff * (j + 1)) / nb_opaque_colors; level = (0xff * j) / nb_opaque_colors;
r = (((subtitle_color >> 16) & 0xff) * level) >> 8; r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
g = (((subtitle_color >> 8) & 0xff) * level) >> 8; g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
b = (((subtitle_color >> 0) & 0xff) * level) >> 8; b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
rgba_palette[i] = b | (g << 8) | (r << 16) | (0xff << 24); rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24);
color_used[palette[i]] = (i + 1); color_used[palette[i]] = (i + 1);
j++; j--;
} else { } else {
rgba_palette[i] = rgba_palette[color_used[palette[i]] - 1]; rgba_palette[i] = (rgba_palette[color_used[palette[i]] - 1] & 0x00ffffff) |
((alpha[i] * 17) << 24);
} }
} }
} }
...@@ -133,6 +134,7 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, ...@@ -133,6 +134,7 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header,
uint8_t palette[4], alpha[4]; uint8_t palette[4], alpha[4];
int date; int date;
int i; int i;
int is_menu = 0;
if (buf_size < 4) if (buf_size < 4)
return -1; return -1;
...@@ -160,35 +162,39 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, ...@@ -160,35 +162,39 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header,
#endif #endif
switch(cmd) { switch(cmd) {
case 0x00: case 0x00:
/* force display */ /* menu subpicture */
is_menu = 1;
break; break;
case 0x01: case 0x01:
/* set start date */ /* set start date */
sub_header->start_display_time = date * 10; sub_header->start_display_time = (date << 10) / 90;
break; break;
case 0x02: case 0x02:
/* set end date */ /* set end date */
sub_header->end_display_time = date * 10; sub_header->end_display_time = (date << 10) / 90;
break; break;
case 0x03: case 0x03:
/* set palette */ /* set palette */
if ((buf_size - pos) < 2) if ((buf_size - pos) < 2)
goto fail; goto fail;
palette[0] = buf[pos] >> 4; palette[3] = buf[pos] >> 4;
palette[1] = buf[pos] & 0x0f; palette[2] = buf[pos] & 0x0f;
palette[2] = buf[pos + 1] >> 4; palette[1] = buf[pos + 1] >> 4;
palette[3] = buf[pos + 1] & 0x0f; palette[0] = buf[pos + 1] & 0x0f;
pos += 2; pos += 2;
break; break;
case 0x04: case 0x04:
/* set alpha */ /* set alpha */
if ((buf_size - pos) < 2) if ((buf_size - pos) < 2)
goto fail; goto fail;
alpha[0] = buf[pos] >> 4; alpha[3] = buf[pos] >> 4;
alpha[1] = buf[pos] & 0x0f; alpha[2] = buf[pos] & 0x0f;
alpha[2] = buf[pos + 1] >> 4; alpha[1] = buf[pos + 1] >> 4;
alpha[3] = buf[pos + 1] & 0x0f; alpha[0] = buf[pos + 1] & 0x0f;
pos += 2; pos += 2;
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]);
#endif
break; break;
case 0x05: case 0x05:
if ((buf_size - pos) < 6) if ((buf_size - pos) < 6)
...@@ -264,7 +270,7 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, ...@@ -264,7 +270,7 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header,
cmd_pos = next_cmd_pos; cmd_pos = next_cmd_pos;
} }
if (sub_header->num_rects > 0) if (sub_header->num_rects > 0)
return 0; return is_menu;
fail: fail:
return -1; return -1;
} }
...@@ -282,7 +288,7 @@ static int is_transp(const uint8_t *buf, int pitch, int n, ...@@ -282,7 +288,7 @@ static int is_transp(const uint8_t *buf, int pitch, int n,
} }
/* return 0 if empty rectangle, 1 if non empty */ /* return 0 if empty rectangle, 1 if non empty */
static int find_smallest_bouding_rectangle(AVSubtitle *s) static int find_smallest_bounding_rectangle(AVSubtitle *s)
{ {
uint8_t transp_color[256]; uint8_t transp_color[256];
int y1, y2, x1, x2, y, w, h, i; int y1, y2, x1, x2, y, w, h, i;
...@@ -375,14 +381,17 @@ static int dvdsub_decode(AVCodecContext *avctx, ...@@ -375,14 +381,17 @@ static int dvdsub_decode(AVCodecContext *avctx,
uint8_t *buf, int buf_size) uint8_t *buf, int buf_size)
{ {
AVSubtitle *sub = (void *)data; AVSubtitle *sub = (void *)data;
int is_menu;
is_menu = decode_dvd_subtitles(sub, buf, buf_size);
if (decode_dvd_subtitles(sub, buf, buf_size) < 0) { if (is_menu < 0) {
no_subtitle: no_subtitle:
*data_size = 0; *data_size = 0;
return buf_size; return buf_size;
} }
if (find_smallest_bouding_rectangle(sub) == 0) if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)
goto no_subtitle; goto no_subtitle;
#if defined(DEBUG) #if defined(DEBUG)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment