X-Git-Url: https://git.piment-noir.org/?p=deb_ffmpeg.git;a=blobdiff_plain;f=ffmpeg%2Flibavcodec%2Fdvdsubdec.c;h=39604f3adae5d3d720e133622af4ccf084a2f92d;hp=7355c03ec2b1903257b14b2ed530d99f57bf4b2b;hb=f6fa7814ccfe3e76514b36cf04f5cd3cb657c8cf;hpb=2ba45a602cbfa7b771effba9b11bb4245c21bc00 diff --git a/ffmpeg/libavcodec/dvdsubdec.c b/ffmpeg/libavcodec/dvdsubdec.c index 7355c03..39604f3 100644 --- a/ffmpeg/libavcodec/dvdsubdec.c +++ b/ffmpeg/libavcodec/dvdsubdec.c @@ -28,17 +28,20 @@ #include "libavutil/opt.h" #include "libavutil/imgutils.h" #include "libavutil/avstring.h" +#include "libavutil/bswap.h" typedef struct DVDSubContext { AVClass *class; uint32_t palette[16]; char *palette_str; + char *ifo_str; int has_palette; uint8_t colormap[4]; uint8_t alpha[256]; uint8_t *buf; int buf_size; + int forced_subs_only; #ifdef DEBUG int sub_id; #endif @@ -548,6 +551,9 @@ static int dvdsub_decode(AVCodecContext *avctx, if (!is_menu && find_smallest_bounding_rectangle(sub) == 0) goto no_subtitle; + if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED)) + goto no_subtitle; + #if defined(DEBUG) { char ppm_name[32]; @@ -579,10 +585,71 @@ static void parse_palette(DVDSubContext *ctx, char *p) } } +static int parse_ifo_palette(DVDSubContext *ctx, char *p) +{ + FILE *ifo; + char ifostr[12]; + uint32_t sp_pgci, pgci, off_pgc, pgc; + uint8_t r, g, b, yuv[65], *buf; + int i, y, cb, cr, r_add, g_add, b_add; + int ret = 0; + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; + + ctx->has_palette = 0; + if ((ifo = fopen(p, "r")) == NULL) { + av_log(ctx, AV_LOG_WARNING, "Unable to open IFO file \"%s\": %s\n", p, strerror(errno)); + return AVERROR_EOF; + } + if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr, "DVDVIDEO-VTS", 12)) { + av_log(ctx, AV_LOG_WARNING, "\"%s\" is not a proper IFO file\n", p); + ret = AVERROR_INVALIDDATA; + goto end; + } + if (fseek(ifo, 0xCC, SEEK_SET) == -1) { + ret = AVERROR(errno); + goto end; + } + if (fread(&sp_pgci, 4, 1, ifo) == 1) { + pgci = av_be2ne32(sp_pgci) * 2048; + if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) { + ret = AVERROR(errno); + goto end; + } + if (fread(&off_pgc, 4, 1, ifo) == 1) { + pgc = pgci + av_be2ne32(off_pgc); + if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) { + ret = AVERROR(errno); + goto end; + } + if (fread(yuv, 64, 1, ifo) == 1) { + buf = yuv; + for(i=0; i<16; i++) { + y = *++buf; + cr = *++buf; + cb = *++buf; + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + ctx->palette[i] = (r << 16) + (g << 8) + b; + buf++; + } + ctx->has_palette = 1; + } + } + } + if (ctx->has_palette == 0) { + av_log(ctx, AV_LOG_WARNING, "Failed to read palette from IFO file \"%s\"\n", p); + ret = AVERROR_INVALIDDATA; + } +end: + fclose(ifo); + return ret; +} + static int dvdsub_parse_extradata(AVCodecContext *avctx) { DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data; char *dataorig, *data; + int ret = 1; if (!avctx->extradata || !avctx->extradata_size) return 1; @@ -603,11 +670,9 @@ static int dvdsub_parse_extradata(AVCodecContext *avctx) } else if (strncmp("size:", data, 5) == 0) { int w, h; if (sscanf(data + 5, "%dx%d", &w, &h) == 2) { - int ret = ff_set_dimensions(avctx, w, h); - if (ret < 0) { - av_free(dataorig); - return ret; - } + ret = ff_set_dimensions(avctx, w, h); + if (ret < 0) + goto fail; } } @@ -615,8 +680,9 @@ static int dvdsub_parse_extradata(AVCodecContext *avctx) data += strspn(data, "\n\r"); } +fail: av_free(dataorig); - return 1; + return ret; } static av_cold int dvdsub_init(AVCodecContext *avctx) @@ -627,6 +693,8 @@ static av_cold int dvdsub_init(AVCodecContext *avctx) if ((ret = dvdsub_parse_extradata(avctx)) < 0) return ret; + if (ctx->ifo_str) + parse_ifo_palette(ctx, ctx->ifo_str); if (ctx->palette_str) parse_palette(ctx, ctx->palette_str); if (ctx->has_palette) { @@ -649,9 +717,11 @@ static av_cold int dvdsub_close(AVCodecContext *avctx) } #define OFFSET(field) offsetof(DVDSubContext, field) -#define VD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM +#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD }, + { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD }, + { "ifo_palette", "obtain the global palette from .IFO file", OFFSET(ifo_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD }, + { "forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD}, { NULL } }; static const AVClass dvdsub_class = {