From c69ff12dc3b420cce327c23d06437a831a439316 Mon Sep 17 00:00:00 2001 From: Rodger Combs Date: Mon, 13 Apr 2015 01:17:28 -0500 Subject: lavf/mpeg: vobsub add an option to specify the .sub's URI Signed-off-by: Michael Niedermayer --- libavformat/mpeg.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'libavformat/mpeg.c') diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index c29291db9f..1c5bbed4aa 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -26,6 +26,7 @@ #if CONFIG_VOBSUB_DEMUXER # include "subtitles.h" # include "libavutil/bprint.h" +# include "libavutil/opt.h" #endif #include "libavutil/avassert.h" @@ -121,6 +122,7 @@ static int mpegps_probe(AVProbeData *p) } typedef struct MpegDemuxContext { + AVClass *class; int32_t header_state; unsigned char psm_es_type[256]; int sofdec; @@ -129,6 +131,7 @@ typedef struct MpegDemuxContext { #if CONFIG_VOBSUB_DEMUXER AVFormatContext *sub_ctx; FFDemuxSubtitlesQueue q[32]; + char *sub_name; #endif } MpegDemuxContext; @@ -684,9 +687,8 @@ static int vobsub_read_header(AVFormatContext *s) { int i, ret = 0, header_parsed = 0, langidx = 0; MpegDemuxContext *vobsub = s->priv_data; - char *sub_name = NULL; size_t fname_len; - char *ext, *header_str; + char *header_str; AVBPrint header; int64_t delay = 0; AVStream *st = NULL; @@ -695,17 +697,25 @@ static int vobsub_read_header(AVFormatContext *s) char alt[MAX_LINE_SIZE] = {0}; AVInputFormat *iformat; - sub_name = av_strdup(s->filename); - fname_len = strlen(sub_name); - ext = sub_name - 3 + fname_len; - if (fname_len < 4 || *(ext - 1) != '.') { - av_log(s, AV_LOG_ERROR, "The input index filename is too short " - "to guess the associated .SUB file\n"); - ret = AVERROR_INVALIDDATA; - goto end; + if (!vobsub->sub_name) { + char *ext; + vobsub->sub_name = av_strdup(s->filename); + if (!vobsub->sub_name) { + ret = AVERROR(ENOMEM); + goto end; + } + + fname_len = strlen(vobsub->sub_name); + ext = vobsub->sub_name - 3 + fname_len; + if (fname_len < 4 || *(ext - 1) != '.') { + av_log(s, AV_LOG_ERROR, "The input index filename is too short " + "to guess the associated .SUB file\n"); + ret = AVERROR_INVALIDDATA; + goto end; + } + memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3); + av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, vobsub->sub_name); } - memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3); - av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, sub_name); if (!(iformat = av_find_input_format("mpeg"))) { ret = AVERROR_DEMUXER_NOT_FOUND; @@ -721,9 +731,9 @@ static int vobsub_read_header(AVFormatContext *s) if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0) goto end; - ret = avformat_open_input(&vobsub->sub_ctx, sub_name, iformat, NULL); + ret = avformat_open_input(&vobsub->sub_ctx, vobsub->sub_name, iformat, NULL); if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", sub_name); + av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", vobsub->sub_name); goto end; } @@ -860,7 +870,6 @@ static int vobsub_read_header(AVFormatContext *s) av_free(header_str); end: - av_free(sub_name); return ret; } @@ -996,6 +1005,18 @@ static int vobsub_read_close(AVFormatContext *s) return 0; } +static const AVOption options[] = { + { "sub_name", "URI for .sub file", offsetof(MpegDemuxContext, sub_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, + { NULL } +}; + +static const AVClass vobsub_demuxer_class = { + .class_name = "vobsub", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVInputFormat ff_vobsub_demuxer = { .name = "vobsub", .long_name = NULL_IF_CONFIG_SMALL("VobSub subtitle format"), @@ -1007,5 +1028,6 @@ AVInputFormat ff_vobsub_demuxer = { .read_close = vobsub_read_close, .flags = AVFMT_SHOW_IDS, .extensions = "idx", + .priv_class = &vobsub_demuxer_class, }; #endif -- cgit v1.2.3