summaryrefslogtreecommitdiffstats
path: root/demux/demux_lavf.c
diff options
context:
space:
mode:
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,