summaryrefslogtreecommitdiffstats
path: root/demux/demux_lavf.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-05-28 21:51:54 +0200
committerwm4 <wm4@nowhere>2015-05-28 21:51:54 +0200
commit0949ee347d5623a96b6dfd087dec7369431f184d (patch)
tree61cd31836244ba47620b0e66c1e1da01e85cd9c2 /demux/demux_lavf.c
parentce0bf9692f48e587b01ba6a1c3ac7176ef18797e (diff)
downloadmpv-0949ee347d5623a96b6dfd087dec7369431f184d.tar.bz2
mpv-0949ee347d5623a96b6dfd087dec7369431f184d.tar.xz
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.
Diffstat (limited to 'demux/demux_lavf.c')
-rw-r--r--demux/demux_lavf.c40
1 files changed, 40 insertions, 0 deletions
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,