From 0949ee347d5623a96b6dfd087dec7369431f184d Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 28 May 2015 21:51:54 +0200 Subject: demux_lavf: do a better job at guessing the vobsub .sub filename Vobsubs come as .idx/.sub pair of files. The .idx file is the one that should be opened, but the name of the .sub file is unknown. We can now make our own guess what the name of that file is. In particular, improve support with URLs (as these can have the file extension in the middle of the filename string if there are HTTP parameters). Note that this works only with newer ffmpeg versions, because the recently added sub_name demuxer option is used for this. --- demux/demux_lavf.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'demux') diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 694b098878..42355804c5 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -45,6 +45,7 @@ #include "demux.h" #include "stheader.h" #include "options/m_option.h" +#include "options/path.h" #define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE @@ -414,6 +415,43 @@ static void parse_cryptokey(AVFormatContext *avfc, const char *str) *key++ = (char2int(str[0]) << 4) | char2int(str[1]); } +static char *replace_idx_ext(void *ta_ctx, bstr f) +{ + if (f.len < 4 || f.start[f.len - 4] != '.') + return NULL; + char *ext = bstr_endswith0(f, "IDX") ? "SUB" : "sub"; // match case + return talloc_asprintf(ta_ctx, "%.*s.%s", f.len - 4, f.start, ext); +} + +static void guess_and_set_vobsub_name(struct demuxer *demuxer, AVDictionary **d) +{ + lavf_priv_t *priv = demuxer->priv; + if (!matches_avinputformat_name(priv, "vobsub")) + return; + + void *tmp = talloc_new(NULL); + bstr bfilename = bstr0(priv->filename); + char *subname = NULL; + if (mp_is_url(bfilename)) { + // It might be a http URL, which has additional parameters after the + // end of the actual file path. + bstr start, end; + if (bstr_split_tok(bfilename, "?", &start, &end)) { + subname = replace_idx_ext(tmp, start); + if (subname) + subname = talloc_asprintf(tmp, "%s?%.*s", subname, BSTR_P(end)); + } + } + if (!subname) + subname = replace_idx_ext(tmp, bfilename); + if (!subname) + subname = talloc_asprintf(tmp, "%.*s.sub", BSTR_P(bfilename)); + + MP_VERBOSE(demuxer, "Assuming associated .sub file: %s\n", subname); + av_dict_set(d, "sub_name", subname, 0); + talloc_free(tmp); +} + static void select_tracks(struct demuxer *demuxer, int start) { lavf_priv_t *priv = demuxer->priv; @@ -742,6 +780,8 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) av_dict_set(&dopts, "rtsp_transport", transport, 0); } + guess_and_set_vobsub_name(demuxer, &dopts); + avfc->interrupt_callback = (AVIOInterruptCB){ .callback = interrupt_cb, .opaque = demuxer, -- cgit v1.2.3