diff options
Diffstat (limited to 'lib/ffmpeg/patches/0012-dvdsub-hacks.patch')
-rw-r--r-- | lib/ffmpeg/patches/0012-dvdsub-hacks.patch | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/lib/ffmpeg/patches/0012-dvdsub-hacks.patch b/lib/ffmpeg/patches/0012-dvdsub-hacks.patch new file mode 100644 index 0000000000..df3bccf6f9 --- /dev/null +++ b/lib/ffmpeg/patches/0012-dvdsub-hacks.patch @@ -0,0 +1,181 @@ +From 61baf585e90935869b4c71b406f5ba70a75211e8 Mon Sep 17 00:00:00 2001 +From: Cory Fields <theuni-nospam-@xbmc.org> +Date: Mon, 28 Jun 2010 02:50:45 -0400 +Subject: [PATCH 12/36] dvdsub hacks + +--- + libavcodec/dvdsubdec.c | 99 ++++++++++++++++++++++++++++++++++++++++++----- + 1 files changed, 88 insertions(+), 11 deletions(-) + +diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c +index bea2646..e713e24 100644 +--- a/libavcodec/dvdsubdec.c ++++ b/libavcodec/dvdsubdec.c +@@ -25,6 +25,14 @@ + + //#define DEBUG + ++typedef struct DVDSubContext ++{ ++ uint8_t colormap[4]; ++ uint8_t alpha[4]; ++ uint32_t palette[16]; ++ int has_palette; ++} DVDSubContext; ++ + static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values) + { + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; +@@ -42,6 +50,24 @@ static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t * + } + } + ++static void ayvu_to_argb(const uint8_t *ayvu, uint32_t *argb, int num_values) ++{ ++ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; ++ uint8_t r, g, b; ++ int i, y, cb, cr, a; ++ int r_add, g_add, b_add; ++ ++ for (i = num_values; i > 0; i--) { ++ a = *ayvu++; ++ y = *ayvu++; ++ cr = *ayvu++; ++ cb = *ayvu++; ++ YUV_TO_RGB1_CCIR(cb, cr); ++ YUV_TO_RGB2_CCIR(r, g, b, y); ++ *argb++ = (a << 24) | (r << 16) | (g << 8) | b; ++ } ++} ++ + static int decode_run_2bit(GetBitContext *gb, int *color) + { + unsigned int v, t; +@@ -115,13 +141,21 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, + return 0; + } + +-static void guess_palette(uint32_t *rgba_palette, +- uint8_t *colormap, +- uint8_t *alpha, +- uint32_t subtitle_color) ++static void fill_palette(DVDSubContext* ctx, ++ uint32_t *rgba_palette, ++ uint32_t subtitle_color) + { + uint8_t color_used[16]; + int nb_opaque_colors, i, level, j, r, g, b; ++ uint8_t *colormap = ctx->colormap; ++ uint8_t *alpha = ctx->alpha; ++ ++ if(ctx->has_palette) { ++ for(i = 0; i < 4; i++) ++ rgba_palette[i] = (ctx->palette[ctx->colormap[i]] & 0x00ffffff) ++ | ((alpha[i] * 17) << 24); ++ return; ++ } + + for(i = 0; i < 4; i++) + rgba_palette[i] = 0; +@@ -160,13 +194,14 @@ static void guess_palette(uint32_t *rgba_palette, + + #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) + +-static int decode_dvd_subtitles(AVSubtitle *sub_header, ++static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, + const uint8_t *buf, int buf_size) + { + int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; + int big_offsets, offset_size, is_8bit = 0; + const uint8_t *yuv_palette = 0; +- uint8_t colormap[4], alpha[256]; ++ uint8_t *colormap = ctx->colormap; ++ uint8_t *alpha = ctx->alpha; + int date; + int i; + int is_menu = 0; +@@ -326,8 +361,7 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, + yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256); + } else { + sub_header->rects[0]->nb_colors = 4; +- guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1], +- colormap, alpha, 0xffff00); ++ fill_palette(ctx, sub_header->rects[0]->pict.data[1], 0xffff00); + } + sub_header->rects[0]->x = x1; + sub_header->rects[0]->y = y1; +@@ -458,12 +492,13 @@ static int dvdsub_decode(AVCodecContext *avctx, + void *data, int *data_size, + AVPacket *avpkt) + { ++ DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + AVSubtitle *sub = data; + int is_menu; + +- is_menu = decode_dvd_subtitles(sub, buf, buf_size); ++ is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size); + + if (is_menu < 0) { + no_subtitle: +@@ -486,12 +521,54 @@ static int dvdsub_decode(AVCodecContext *avctx, + return buf_size; + } + ++static int dvdsub_init(AVCodecContext *avctx) ++{ ++ DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data; ++ char *data = avctx->extradata; ++ ++ if (!avctx->extradata || !avctx->extradata_size) ++ return 1; ++ ++ data[avctx->extradata_size] = '\0'; ++ ++ for(;;) { ++ int pos = strcspn(data, "\n\r"); ++ if (pos==0 && *data==0) ++ break; ++ ++ if (strncmp("palette:", data, 8) == 0) { ++ int i; ++ char *p = data+8; ++ ctx->has_palette = 1; ++ for(i=0;i<16;i++) { ++ ctx->palette[i] = strtoul(p, &p, 16); ++ while(*p == ',' || isspace(*p)) ++ p++; ++ } ++#if defined(DEBUG) ++ av_log(avctx, AV_LOG_INFO, "palette:"); ++ for(i=0;i<16;i++) ++ av_log(avctx, AV_LOG_WARNING, " 0x%06x", ctx->palette[i]); ++ av_log(avctx, AV_LOG_INFO, "\n"); ++#endif ++ } ++ ++ data += pos; ++ data += strspn(data, "\n\r"); ++ } ++ ++ if(!ctx->has_palette && avctx->extradata_size == 64) ++ ayvu_to_argb((uint8_t*)avctx->extradata, ctx->palette, 16); ++ ++ return 1; ++} ++ + AVCodec ff_dvdsub_decoder = { + "dvdsub", + AVMEDIA_TYPE_SUBTITLE, + CODEC_ID_DVD_SUBTITLE, +- 0, +- NULL, ++ sizeof(DVDSubContext), ++ dvdsub_init, + NULL, + NULL, + dvdsub_decode, +-- +1.7.3 + |