# HG changeset patch # User michael # Date 1123982127 0 # Node ID 1f117208d20f9ef68de177953578cd25432fa100 # Parent 89b92f0800ab45742784138c831ed4581520ff72 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) diff -r 89b92f0800ab -r 1f117208d20f dvbsubdec.c --- a/dvbsubdec.c Sat Aug 13 21:34:24 2005 +0000 +++ b/dvbsubdec.c Sun Aug 14 01:15:27 2005 +0000 @@ -1310,10 +1310,8 @@ sub->num_rects = ctx->display_list_size; - if (sub->num_rects == 0) - return 0; - - sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects); + if (sub->num_rects > 0) + sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects); i = 0; @@ -1447,7 +1445,7 @@ return -1; } - return 0; + return buf_size; } diff -r 89b92f0800ab -r 1f117208d20f dvdsub.c --- a/dvdsub.c Sat Aug 13 21:34:24 2005 +0000 +++ b/dvdsub.c Sun Aug 14 01:15:27 2005 +0000 @@ -107,20 +107,21 @@ if (nb_opaque_colors == 0) return; - j = 0; + j = nb_opaque_colors; memset(color_used, 0, 16); for(i = 0; i < 4; i++) { if (alpha[i] != 0) { 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; g = (((subtitle_color >> 8) & 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); - j++; + j--; } 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 @@ uint8_t palette[4], alpha[4]; int date; int i; + int is_menu = 0; if (buf_size < 4) return -1; @@ -160,35 +162,39 @@ #endif switch(cmd) { case 0x00: - /* force display */ + /* menu subpicture */ + is_menu = 1; break; case 0x01: /* set start date */ - sub_header->start_display_time = date * 10; + sub_header->start_display_time = (date << 10) / 90; break; case 0x02: /* set end date */ - sub_header->end_display_time = date * 10; + sub_header->end_display_time = (date << 10) / 90; break; case 0x03: /* set palette */ if ((buf_size - pos) < 2) goto fail; - palette[0] = buf[pos] >> 4; - palette[1] = buf[pos] & 0x0f; - palette[2] = buf[pos + 1] >> 4; - palette[3] = buf[pos + 1] & 0x0f; + palette[3] = buf[pos] >> 4; + palette[2] = buf[pos] & 0x0f; + palette[1] = buf[pos + 1] >> 4; + palette[0] = buf[pos + 1] & 0x0f; pos += 2; break; case 0x04: /* set alpha */ if ((buf_size - pos) < 2) goto fail; - alpha[0] = buf[pos] >> 4; - alpha[1] = buf[pos] & 0x0f; - alpha[2] = buf[pos + 1] >> 4; - alpha[3] = buf[pos + 1] & 0x0f; + alpha[3] = buf[pos] >> 4; + alpha[2] = buf[pos] & 0x0f; + alpha[1] = buf[pos + 1] >> 4; + alpha[0] = buf[pos + 1] & 0x0f; 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; case 0x05: if ((buf_size - pos) < 6) @@ -264,7 +270,7 @@ cmd_pos = next_cmd_pos; } if (sub_header->num_rects > 0) - return 0; + return is_menu; fail: return -1; } @@ -282,7 +288,7 @@ } /* 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]; int y1, y2, x1, x2, y, w, h, i; @@ -375,14 +381,17 @@ uint8_t *buf, int buf_size) { AVSubtitle *sub = (void *)data; + int is_menu; - if (decode_dvd_subtitles(sub, buf, buf_size) < 0) { + is_menu = decode_dvd_subtitles(sub, buf, buf_size); + + if (is_menu < 0) { no_subtitle: *data_size = 0; return buf_size; } - if (find_smallest_bouding_rectangle(sub) == 0) + if (!is_menu && find_smallest_bounding_rectangle(sub) == 0) goto no_subtitle; #if defined(DEBUG)