summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/options.rst6
-rw-r--r--Makefile1
-rw-r--r--core/mplayer.c6
-rw-r--r--core/options.c2
-rw-r--r--core/options.h1
-rw-r--r--core/timeline/tl_matroska.c2
-rw-r--r--demux/demux.c220
-rw-r--r--demux/demux.h50
-rw-r--r--demux/demux_cue.c23
-rw-r--r--demux/demux_edl.c23
-rw-r--r--demux/demux_lavf.c18
-rw-r--r--demux/demux_libass.c61
-rw-r--r--demux/demux_mf.c77
-rw-r--r--demux/demux_mkv.c5
-rw-r--r--demux/demux_mng.c31
-rw-r--r--demux/demux_rawaudio.c7
-rw-r--r--demux/demux_rawvideo.c7
-rw-r--r--demux/demux_subreader.c9
-rw-r--r--demux/extension.c101
-rw-r--r--stream/stream_dvb.c3
-rw-r--r--stream/stream_mf.c2
-rw-r--r--stream/tv.c5
22 files changed, 223 insertions, 437 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index d891766f6b..a6e5fee7ed 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -690,12 +690,6 @@
Stop at given absolute time. Use ``--length`` if the time should be relative
to ``--start``. See ``--start`` for valid option values and examples.
-``--no-extbased``, ``--extbased``
- ``--no-extbased`` disables extension-based demuxer selection. By default,
- when the file type (demuxer) cannot be detected reliably (the file has no
- header or it is not reliable enough), the filename extension is used to
- select the demuxer. Always falls back on content-based demuxer selection.
-
``--field-dominance=<auto|top|bottom>``
Set first field for interlaced content. Useful for deinterlacers that
double the framerate: ``--vf=yadif=1`` and ``--vo=vdpau:deint``.
diff --git a/Makefile b/Makefile
index 3e0af2d55e..a1de600dcc 100644
--- a/Makefile
+++ b/Makefile
@@ -196,7 +196,6 @@ SOURCES = talloc.c \
demux/demux_rawaudio.c \
demux/demux_rawvideo.c \
demux/ebml.c \
- demux/extension.c \
demux/mf.c \
osdep/io.c \
osdep/numcores.c \
diff --git a/core/mplayer.c b/core/mplayer.c
index ecaa9dd10b..de6b4132fd 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -2297,9 +2297,9 @@ int reinit_video_chain(struct MPContext *mpctx)
goto no_video;
}
- mp_tmsg(MSGT_CPLAYER, MSGL_V, "[V] filefmt:%d fourcc:0x%X "
+ mp_tmsg(MSGT_CPLAYER, MSGL_V, "[V] fourcc:0x%X "
"size:%dx%d fps:%5.3f\n",
- mpctx->master_demuxer->file_format, mpctx->sh_video->format,
+ mpctx->sh_video->format,
mpctx->sh_video->disp_w, mpctx->sh_video->disp_h,
mpctx->sh_video->fps);
if (opts->force_fps)
@@ -2459,7 +2459,7 @@ static struct demux_packet *video_read_frame(struct MPContext *mpctx)
double d = next_pts == MP_NOPTS_VALUE ? sh_video->last_pts - pts1
: next_pts - sh_video->last_pts;
if (d >= 0) {
- if (demuxer->file_format == DEMUXER_TYPE_TV) {
+ if (demuxer->type == DEMUXER_TYPE_TV) {
if (d > 0)
sh_video->fps = 1.0f / d;
frame_time = d;
diff --git a/core/options.c b/core/options.c
index d676cb4948..2298d112b8 100644
--- a/core/options.c
+++ b/core/options.c
@@ -399,7 +399,6 @@ const m_option_t mp_opts[] = {
OPT_STRING("demuxer", demuxer_name, 0),
OPT_STRING("audio-demuxer", audio_demuxer_name, 0),
OPT_STRING("sub-demuxer", sub_demuxer_name, 0),
- OPT_FLAG("extbased", extension_parsing, 0),
{"mf", (void *) mfopts_conf, CONF_TYPE_SUBCONFIG, 0,0,0, NULL},
#ifdef CONFIG_RADIO
@@ -777,7 +776,6 @@ const struct MPOpts mp_default_opts = {
.sub_visibility = 1,
.sub_pos = 100,
.sub_speed = 1.0,
- .extension_parsing = 1,
.audio_output_channels = MP_CHMAP_INIT_STEREO,
.audio_output_format = -1, // AF_FORMAT_UNKNOWN
.playback_speed = 1.,
diff --git a/core/options.h b/core/options.h
index d46435bf9e..345835656b 100644
--- a/core/options.h
+++ b/core/options.h
@@ -152,7 +152,6 @@ typedef struct MPOpts {
char *demuxer_name;
char *audio_demuxer_name;
char *sub_demuxer_name;
- int extension_parsing;
int mkv_subtitle_preroll;
struct image_writer_opts *screenshot_image_opts;
diff --git a/core/timeline/tl_matroska.c b/core/timeline/tl_matroska.c
index 614ce0d6b7..f01160b60e 100644
--- a/core/timeline/tl_matroska.c
+++ b/core/timeline/tl_matroska.c
@@ -168,7 +168,7 @@ static bool check_file_seg(struct MPContext *mpctx, struct demuxer **sources,
free_stream(s);
return was_valid;
}
- if (d->file_format == DEMUXER_TYPE_MATROSKA) {
+ if (d->type == DEMUXER_TYPE_MATROSKA) {
for (int i = 1; i < num_sources; i++) {
if (sources[i])
continue;
diff --git a/demux/demux.c b/demux/demux.c
index 5a0e05d48f..61e0f2e9ef 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -224,46 +224,6 @@ struct demux_packet *demux_copy_packet(struct demux_packet *dp)
return new;
}
-/**
- * Get demuxer description structure for a given demuxer type
- *
- * @param file_format type of the demuxer
- * @return structure for the demuxer, NULL if not found
- */
-static const demuxer_desc_t *get_demuxer_desc_from_type(int file_format)
-{
- int i;
-
- for (i = 0; demuxer_list[i]; i++)
- if (file_format == demuxer_list[i]->type)
- return demuxer_list[i];
-
- return NULL;
-}
-
-
-static demuxer_t *new_demuxer(struct MPOpts *opts, stream_t *stream, int type)
-{
- struct demuxer *d = talloc_zero(NULL, struct demuxer);
- d->stream = stream;
- d->stream_pts = MP_NOPTS_VALUE;
- d->movi_start = stream->start_pos;
- d->movi_end = stream->end_pos;
- d->seekable = 1;
- d->filepos = -1;
- d->type = type;
- d->opts = opts;
- if (type)
- if (!(d->desc = get_demuxer_desc_from_type(type)))
- mp_msg(MSGT_DEMUXER, MSGL_ERR,
- "BUG! Invalid demuxer type in new_demuxer(), "
- "big troubles ahead.\n");
- if (stream->url)
- d->filename = strdup(stream->url);
- stream_seek(stream, stream->start_pos);
- return d;
-}
-
struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type)
{
if (demuxer->num_streams > MAX_SH_STREAMS) {
@@ -356,7 +316,6 @@ void free_demuxer(demuxer_t *demuxer)
// free streams:
for (int n = 0; n < demuxer->num_streams; n++)
free_sh_stream(demuxer->streams[n]);
- free(demuxer->filename);
talloc_free(demuxer);
}
@@ -546,8 +505,6 @@ void demuxer_help(void)
mp_msg(MSGT_DEMUXER, MSGL_INFO, " demuxer: info: (comment)\n");
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_DEMUXERS\n");
for (i = 0; demuxer_list[i]; i++) {
- if (demuxer_list[i]->type >= DEMUXER_TYPE_END) // internal type
- continue;
if (demuxer_list[i]->comment && strlen(demuxer_list[i]->comment))
mp_msg(MSGT_DEMUXER, MSGL_INFO, "%10s %s (%s)\n",
demuxer_list[i]->name, demuxer_list[i]->info,
@@ -558,66 +515,51 @@ void demuxer_help(void)
}
}
-
-/**
- * Get demuxer type for a given demuxer name
- *
- * @param demuxer_name string with demuxer name of demuxer number
- * @param force will be set if demuxer should be forced.
- * May be NULL.
- * @return DEMUXER_TYPE_xxx, -1 if error or not found
- */
-static int get_demuxer_type_from_name(char *demuxer_name, int *force)
-{
- if (!demuxer_name || !demuxer_name[0])
- return DEMUXER_TYPE_UNKNOWN;
- if (force)
- *force = demuxer_name[0] == '+';
- if (demuxer_name[0] == '+')
- demuxer_name = &demuxer_name[1];
- for (int i = 0; demuxer_list[i]; i++) {
- if (demuxer_list[i]->type >= DEMUXER_TYPE_END)
- // Can't select special demuxers from commandline
- continue;
- if (strcmp(demuxer_name, demuxer_list[i]->name) == 0)
- return demuxer_list[i]->type;
+static const char *d_level(enum demux_check level)
+{
+ switch (level) {
+ case DEMUX_CHECK_FORCE: return "force";
+ case DEMUX_CHECK_UNSAFE: return "unsafe";
+ case DEMUX_CHECK_REQUEST:return "request";
+ case DEMUX_CHECK_NORMAL: return "normal";
}
-
- return -1;
+ abort();
}
static struct demuxer *open_given_type(struct MPOpts *opts,
const struct demuxer_desc *desc,
- struct stream *stream, bool force,
- struct demuxer_params *params)
-{
- struct demuxer *demuxer;
- int fformat = desc->type;
- mp_msg(MSGT_DEMUXER, MSGL_V, "Trying demuxer: %s\n", desc->name);
- demuxer = new_demuxer(opts, stream, desc->type);
- demuxer->params = params;
- if (!force) {
- if (desc->check_file)
- fformat = desc->check_file(demuxer) >= 0 ? fformat : 0;
- }
- if (fformat == 0)
- goto fail;
- if (fformat == desc->type) {
+ struct stream *stream,
+ struct demuxer_params *params,
+ enum demux_check check)
+{
+ struct demuxer *demuxer = talloc_ptrtype(NULL, demuxer);
+ *demuxer = (struct demuxer) {
+ .desc = desc,
+ .type = desc->type,
+ .stream = stream,
+ .stream_pts = MP_NOPTS_VALUE,
+ .movi_start = stream->start_pos,
+ .movi_end = stream->end_pos,
+ .seekable = 1,
+ .filepos = -1,
+ .opts = opts,
+ .filename = talloc_strdup(demuxer, stream->url),
+ };
+ demuxer->params = params; // temporary during open()
+ stream_seek(stream, stream->start_pos);
+
+ mp_msg(MSGT_DEMUXER, MSGL_V, "Trying demuxer: %s (force-level: %s)\n",
+ desc->name, d_level(check));
+
+ int ret = demuxer->desc->open(demuxer, check);
+ if (ret >= 0) {
+ demuxer->params = NULL;
if (demuxer->filetype)
mp_tmsg(MSGT_DEMUXER, MSGL_INFO, "Detected file format: %s (%s)\n",
demuxer->filetype, desc->shortdesc);
else
mp_tmsg(MSGT_DEMUXER, MSGL_INFO, "Detected file format: %s\n",
desc->shortdesc);
- if (demuxer->desc->open) {
- int ret = demuxer->desc->open(demuxer);
- if (ret < 0) {
- mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "Opening as detected format "
- "\"%s\" failed.\n", desc->shortdesc);
- goto fail;
- }
- }
- demuxer->file_format = fformat;
if (stream_manages_timeline(demuxer->stream)) {
// Incorrect, but fixes some behavior with DVD/BD
demuxer->ts_resets_possible = false;
@@ -628,81 +570,55 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
demuxer_sort_chapters(demuxer);
demux_info_update(demuxer);
return demuxer;
- } else {
- // demux_mov can return playlist instead of mov
- if (fformat == DEMUXER_TYPE_PLAYLIST)
- return demuxer; // handled in mplayer.c
- /* Internal MPEG PS demuxer check can return other MPEG subtypes
- * which don't have their own checks; recurse to try opening as
- * the returned type instead. */
- free_demuxer(demuxer);
- desc = get_demuxer_desc_from_type(fformat);
- if (!desc) {
- mp_msg(MSGT_DEMUXER, MSGL_ERR,
- "BUG: recursion to nonexistent file format\n");
- return NULL;
- }
- return open_given_type(opts, desc, stream, false, params);
}
- fail:
+
free_demuxer(demuxer);
return NULL;
}
+static const int d_normal[] = {DEMUX_CHECK_NORMAL, DEMUX_CHECK_UNSAFE, -1};
+static const int d_request[] = {DEMUX_CHECK_REQUEST, -1};
+static const int d_force[] = {DEMUX_CHECK_FORCE, -1};
+
struct demuxer *demux_open(struct stream *stream, char *force_format,
struct demuxer_params *params, struct MPOpts *opts)
{
- struct demuxer *demuxer = NULL;
- const struct demuxer_desc *desc;
+ const int *check_levels = d_normal;
+ const struct demuxer_desc *check_desc = NULL;
+
if (!force_format)
force_format = opts->demuxer_name;
+ if (!force_format)
+ force_format = stream->demuxer;
- int force = 0;
- int demuxer_type;
- if ((demuxer_type = get_demuxer_type_from_name(force_format, &force)) < 0) {
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "Demuxer %s does not exist.\n",
- force_format);
- return NULL;
- }
- int file_format = 0;
- if (demuxer_type)
- file_format = demuxer_type;
-
- // If somebody requested a demuxer check it
- if (file_format) {
- desc = get_demuxer_desc_from_type(file_format);
- if (!desc)
- // should only happen with obsolete -demuxer 99 numeric format
+ if (force_format && force_format[0]) {
+ check_levels = d_request;
+ if (force_format[0] == '+') {
+ force_format += 1;
+ check_levels = d_force;
+ }
+ for (int n = 0; demuxer_list[n]; n++) {
+ if (strcmp(demuxer_list[n]->name, force_format) == 0)
+ check_desc = demuxer_list[n];
+ }
+ if (!check_desc) {
+ mp_msg(MSGT_DEMUXER, MSGL_ERR, "Demuxer %s does not exist.\n",
+ force_format);
return NULL;
- return open_given_type(opts, desc, stream, force, params);
- }
-
- // Test demuxers with safe file checks
- for (int i = 0; (desc = demuxer_list[i]); i++) {
- if (desc->safe_check) {
- demuxer = open_given_type(opts, desc, stream, false, params);
- if (demuxer)
- return demuxer;
}
}
- // Ok. We're over the stable detectable fileformats, the next ones are
- // a bit fuzzy. So by default (extension_parsing==1) try extension-based
- // detection first:
- if (stream->url && opts->extension_parsing == 1) {
- desc = get_demuxer_desc_from_type(demuxer_type_by_filename(stream->url));
- if (desc)
- demuxer = open_given_type(opts, desc, stream, false, params);
- if (demuxer)
- return demuxer;
- }
-
- // Finally try detection for demuxers with unsafe checks
- for (int i = 0; (desc = demuxer_list[i]); i++) {
- if (!desc->safe_check && desc->check_file) {
- demuxer = open_given_type(opts, desc, stream, false, params);
- if (demuxer)
- return demuxer;
+ // Test demuxers from first to last, one pass for each check_levels[] entry
+ for (int pass = 0; check_levels[pass] != -1; pass++) {
+ enum demux_check level = check_levels[pass];
+ for (int n = 0; demuxer_list[n]; n++) {
+ const struct demuxer_desc *desc = demuxer_list[n];
+ if (!check_desc || desc == check_desc) {
+ struct demuxer *demuxer = open_given_type(opts, desc, stream,
+ params, level);
+ if (demuxer)
+ return demuxer;
+ }
}
}
diff --git a/demux/demux.h b/demux/demux.h
index f64a02dce1..34ff9fd596 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -36,24 +36,11 @@ struct MPOpts;
#define MAX_PACK_BYTES 0x8000000 // 128 MiB
enum demuxer_type {
- DEMUXER_TYPE_UNKNOWN = 0,
+ DEMUXER_TYPE_GENERIC = 0,
DEMUXER_TYPE_TV,
- DEMUXER_TYPE_MF,
- DEMUXER_TYPE_RAWAUDIO,
- DEMUXER_TYPE_RAWVIDEO,
DEMUXER_TYPE_MATROSKA,
- DEMUXER_TYPE_LAVF,
- DEMUXER_TYPE_MNG,
DEMUXER_TYPE_EDL,
DEMUXER_TYPE_CUE,
- DEMUXER_TYPE_SUBREADER,
- DEMUXER_TYPE_LIBASS,
-
- /* Values after this are for internal use and can not be selected
- * as demuxer type by the user (-demuxer option). */
- DEMUXER_TYPE_END,
-
- DEMUXER_TYPE_PLAYLIST,
};
enum timestamp_type {
@@ -84,6 +71,22 @@ enum timestamp_type {
#define SEEK_BACKWARD (1 << 3)
#define SEEK_SUBPREROLL (1 << 4)
+// Strictness of the demuxer open format check.
+// demux.c will try by default: NORMAL, UNSAFE (in this order)
+// Using "-demuxer format" will try REQUEST
+// Using "-demuxer +format" will try FORCE
+// REQUEST can be used as special value for raw demuxers which have no file
+// header check; then they should fail if check!=FORCE && check!=REQUEST.
+//
+// In general, the list is sorted from weakest check to normal check.
+// You can use relation operators to compare the check level.
+enum demux_check {
+ DEMUX_CHECK_FORCE, // force format if possible
+ DEMUX_CHECK_UNSAFE, // risky/fuzzy detection
+ DEMUX_CHECK_REQUEST,// requested by user or stream implementation
+ DEMUX_CHECK_NORMAL, // normal, safe detection
+};
+
// demux_lavf can pass lavf buffers using FF_INPUT_BUFFER_PADDING_SIZE instead
#define MP_INPUT_BUFFER_PADDING_SIZE 16
@@ -101,14 +104,10 @@ typedef struct demuxer_desc {
const char *author; // Demuxer author(s)
const char *comment; // Comment, printed with -demuxer help
- enum demuxer_type type;
- // If 1 detection is safe and fast, do it before file extension check
- int safe_check;
+ enum demuxer_type type; // optional
// Return 0 on success, otherwise -1
- int (*check_file)(struct demuxer *demuxer);
- // Open the demuxer, return 0 on success, otherwise -1
- int (*open)(struct demuxer *demuxer);
+ int (*open)(struct demuxer *demuxer, enum demux_check check);
// The following functions are all optional
int (*fill_buffer)(struct demuxer *demuxer); // 0 on EOF, otherwise 1
void (*close)(struct demuxer *demuxer);
@@ -160,15 +159,8 @@ typedef struct demuxer {
int64_t movi_end;
struct stream *stream;
double stream_pts; // current stream pts, if applicable (e.g. dvd)
- char *filename; // Needed by avs_check_file
+ char *filename; // same as stream->url
enum demuxer_type type;
- /* Normally the file_format field is just a copy of the type field above.
- * There are 2 exceptions I noticed. Internal demux_avi may force
- * ->type to DEMUXER_TYPE_AVI_[NI|NINI] while leaving ->file_format at
- * DEMUXER_TYPE_AVI. Internal demux_mov may set ->type to
- * DEMUXER_TYPE_PLAYLIST and also return that from the check function
- * or not (looks potentially buggy). */
- enum demuxer_type file_format;
int seekable; // flag
/* Set if using absolute seeks for small movements is OK (no pts resets
* that would make pts ambigious, preferably supports back/forward flags */
@@ -252,8 +244,6 @@ void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
bool selected);
void demuxer_enable_autoselect(struct demuxer *demuxer);
-int demuxer_type_by_filename(char *filename);
-
void demuxer_help(void);
int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name,
diff --git a/demux/demux_cue.c b/demux/demux_cue.c
index 43ef910868..db2f40ea57 100644
--- a/demux/demux_cue.c
+++ b/demux/demux_cue.c
@@ -29,21 +29,21 @@ bool mp_probe_cue(struct bstr s);
#define PROBE_SIZE 512
-static int try_open_file(struct demuxer *demuxer)
+static int try_open_file(struct demuxer *demuxer, enum demux_check check)
{
struct stream *s = demuxer->stream;
- char buf[PROBE_SIZE];
- int len = stream_read(s, buf, sizeof(buf));
- if (len <= 0)
- return -1;
- if (!mp_probe_cue((struct bstr) { buf, len }))
- return -1;
- stream_seek(s, 0);
+ if (check >= DEMUX_CHECK_UNSAFE) {
+ char buf[PROBE_SIZE];
+ int len = stream_read(s, buf, sizeof(buf));
+ if (len <= 0)
+ return -1;
+ if (!mp_probe_cue((struct bstr) { buf, len }))
+ return -1;
+ stream_seek(s, 0);
+ }
demuxer->file_contents = stream_read_complete(s, demuxer, 1000000);
if (demuxer->file_contents.start == NULL)
return -1;
- if (!mp_probe_cue((struct bstr) { buf, len }))
- return -1;
return 0;
}
@@ -54,6 +54,5 @@ const struct demuxer_desc demuxer_desc_cue = {
.author = "Uoti Urpala",
.comment = "",
.type = DEMUXER_TYPE_CUE,
- .safe_check = true,
- .check_file = try_open_file, // no separate .open
+ .open = try_open_file,
};
diff --git a/demux/demux_edl.c b/demux/demux_edl.c
index 44fa824193..0f4bf06dbf 100644
--- a/demux/demux_edl.c
+++ b/demux/demux_edl.c
@@ -23,17 +23,19 @@
#include "demux.h"
#include "stream/stream.h"
-static int try_open_file(struct demuxer *demuxer)
+static int try_open_file(struct demuxer *demuxer, enum demux_check check)
{
struct stream *s = demuxer->stream;
- const char header[] = "mplayer EDL file";
- const int len = sizeof(header) - 1;
- char buf[len];
- if (stream_read(s, buf, len) < len)
- return -1;
- if (strncmp(buf, header, len))
- return -1;
- stream_seek(s, 0);
+ if (check >= DEMUX_CHECK_UNSAFE) {
+ const char header[] = "mplayer EDL file";
+ const int len = sizeof(header) - 1;
+ char buf[len];
+ if (stream_read(s, buf, len) < len)
+ return -1;
+ if (strncmp(buf, header, len))
+ return -1;
+ stream_seek(s, 0);
+ }
demuxer->file_contents = stream_read_complete(s, demuxer, 1000000);
if (demuxer->file_contents.start == NULL)
return -1;
@@ -47,6 +49,5 @@ const struct demuxer_desc demuxer_desc_edl = {
.author = "Uoti Urpala",
.comment = "",
.type = DEMUXER_TYPE_EDL,
- .safe_check = true,
- .check_file = try_open_file, // no separate .open
+ .open = try_open_file,
};
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 0e7690f606..88587f8ce0 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -185,7 +185,7 @@ static char *remove_prefix(char *s, const char **prefixes)
static const char *prefixes[] =
{"ffmpeg://", "lavf://", "avdevice://", "av://", NULL};
-static int lavf_check_file(demuxer_t *demuxer)
+static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
{
struct MPOpts *opts = demuxer->opts;
struct lavfdopts *lavfdopts = &opts->lavfdopts;
@@ -258,7 +258,8 @@ static int lavf_check_file(demuxer_t *demuxer)
min_probe = lavfdopts->probescore;
AVProbeData avpd = {
- .filename = priv->filename,
+ // Disable file-extension matching with normal checks
+ .filename = check <= DEMUX_CHECK_REQUEST ? priv->filename : NULL,
.buf_size = 0,
.buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE),
};
@@ -493,18 +494,20 @@ static void add_metadata(demuxer_t *demuxer, AVDictionary *metadata)
demux_info_add(demuxer, t->key, t->value);
}
-static int demux_open_lavf(demuxer_t *demuxer)
+static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
{
struct MPOpts *opts = demuxer->opts;
struct lavfdopts *lavfdopts = &opts->lavfdopts;
AVFormatContext *avfc;
AVDictionaryEntry *t = NULL;
- lavf_priv_t *priv = demuxer->priv;
float analyze_duration = 0;
int i;
- // do not allow forcing the demuxer
- if (!priv->avif)
+ if (lavf_check_file(demuxer, check) < 0)
+ return -1;
+
+ lavf_priv_t *priv = demuxer->priv;
+ if (!priv)
return -1;
stream_seek(demuxer->stream, 0);
@@ -904,9 +907,6 @@ const demuxer_desc_t demuxer_desc_lavf = {
.shortdesc = "libavformat",
.author = "Michael Niedermayer",
.comment = "supports many formats, requires libavformat",
- .type = DEMUXER_TYPE_LAVF,
- .safe_check = 1,
- .check_file = lavf_check_file,
.fill_buffer = demux_lavf_fill_buffer,
.open = demux_open_lavf,
.close = demux_close_lavf,
diff --git a/demux/demux_libass.c b/demux/demux_libass.c
index 4dadb42b89..24e1b9e114 100644
--- a/demux/demux_libass.c
+++ b/demux/demux_libass.c
@@ -33,7 +33,7 @@ struct priv {
ASS_Track *track;
};
-static int d_check_file(struct demuxer *demuxer)
+static int d_check_file(struct demuxer *demuxer, enum demux_check check)
{
const char *user_cp = demuxer->opts->sub_cp;
struct stream *s = demuxer->stream;
@@ -43,42 +43,45 @@ static int d_check_file(struct demuxer *demuxer)
if (!lib)
return -1;
- // Probe by loading a part of the beginning of the file with libass.
- // Incomplete scripts are usually ok, and we hope libass is not verbose
- // when dealing with (from its perspective) completely broken binary
- // garbage.
-
- bstr buf = stream_peek(s, PROBE_SIZE);
- // Older versions of libass will overwrite the input buffer, and despite
- // passing length, expect a 0 termination.
- void *tmp = talloc_size(NULL, buf.len + 1);
- memcpy(tmp, buf.start, buf.len);
- buf.start = tmp;
- buf.start[buf.len] = '\0';
- bstr cbuf =
- mp_charset_guess_and_conv_to_utf8(buf, user_cp, MP_ICONV_ALLOW_CUTOFF);
- if (cbuf.start == NULL)
- cbuf = buf;
- ASS_Track *track = ass_read_memory(lib, cbuf.start, cbuf.len, NULL);
- if (cbuf.start != buf.start)
- talloc_free(cbuf.start);
- talloc_free(buf.start);
- if (!track)
- return -1;
- ass_free_track(track);
+ if (check >= DEMUX_CHECK_UNSAFE) {
+ // Probe by loading a part of the beginning of the file with libass.
+ // Incomplete scripts are usually ok, and we hope libass is not verbose
+ // when dealing with (from its perspective) completely broken binary
+ // garbage.
+
+ bstr buf = stream_peek(s, PROBE_SIZE);
+ // Older versions of libass will overwrite the input buffer, and despite
+ // passing length, expect a 0 termination.
+ void *tmp = talloc_size(NULL, buf.len + 1);
+ memcpy(tmp, buf.start, buf.len);
+ buf.start = tmp;
+ buf.start[buf.len] = '\0';
+ bstr cbuf = mp_charset_guess_and_conv_to_utf8(buf, user_cp,
+ MP_ICONV_ALLOW_CUTOFF);
+ if (cbuf.start == NULL)
+ cbuf = buf;
+ ASS_Track *track = ass_read_memory(lib, cbuf.start, cbuf.len, NULL);
+ if (cbuf.start != buf.start)
+ talloc_free(cbuf.start);
+ talloc_free(buf.start);
+ if (!track)
+ return -1;
+ ass_free_track(track);
+ }
// Actually load the full thing.
- buf = stream_read_complete(s, NULL, 100000000);
+ bstr buf = stream_read_complete(s, NULL, 100000000);
if (!buf.start) {
mp_tmsg(MSGT_ASS, MSGL_ERR, "Refusing to load subtitle file "
"larger than 100 MB: %s\n", demuxer->filename);
return -1;
}
- cbuf = mp_charset_guess_and_conv_to_utf8(buf, user_cp, MP_ICONV_VERBOSE);
+ bstr cbuf = mp_charset_guess_and_conv_to_utf8(buf, user_cp,
+ MP_ICONV_VERBOSE);
if (cbuf.start == NULL)
cbuf = buf;
- track = ass_read_memory(lib, cbuf.start, cbuf.len, NULL);
+ ASS_Track *track = ass_read_memory(lib, cbuf.start, cbuf.len, NULL);
if (cbuf.start != buf.start)
talloc_free(cbuf.start);
talloc_free(buf.start);
@@ -114,8 +117,6 @@ const struct demuxer_desc demuxer_desc_libass = {
.shortdesc = "ASS/SSA subtitles (libass)",
.author = "",
.comment = "",
- .safe_check = 1,
- .type = DEMUXER_TYPE_LIBASS,
- .check_file = d_check_file,
+ .open = d_check_file,
.close = d_close,
};
diff --git a/demux/demux_mf.c b/demux/demux_mf.c
index 5e3469a0f1..33747f12d7 100644
--- a/demux/demux_mf.c
+++ b/demux/demux_mf.c
@@ -149,9 +149,9 @@ static const struct {
{0}
};
-static const char *probe_format(mf_t *mf)
+static const char *probe_format(mf_t *mf, enum demux_check check)
{
- if (mf->nr_of_files < 1)
+ if (check > DEMUX_CHECK_REQUEST)
return NULL;
char *type = mf_type;
if (!type || !type[0]) {
@@ -159,47 +159,42 @@ static const char *probe_format(mf_t *mf)
if (p)
type = p + 1;
}
- if (!type || !type[0])
- return NULL;
- int i;
- for (i = 0; type2format[i].type; i++) {
- if (strcasecmp(type, type2format[i].type) == 0)
- break;
+ for (int i = 0; type2format[i].type; i++) {
+ if (type && strcasecmp(type, type2format[i].type) == 0)
+ return type2format[i].codec;
}
- return type2format[i].codec;
-}
-
-static mf_t *open_mf(demuxer_t *demuxer)
-{
- if (!demuxer->stream->url)
- return NULL;
-
- if (strncmp(demuxer->stream->url, "mf://", 5) == 0) {
- return open_mf_pattern(demuxer->stream->url + 5);
- } else {
- mf_t *mf = open_mf_single(demuxer->stream->url);
- mf->streams = calloc(1, sizeof(struct stream *));
- mf->streams[0] = demuxer->stream;
- return mf;
+ if (check == DEMUX_CHECK_REQUEST) {
+ if (!mf_type) {
+ mp_msg(MSGT_DEMUX, MSGL_ERR,
+ "[demux_mf] file type was not set! (try --mf-type=ext)\n");
+ } else {
+ mp_msg(MSGT_DEMUX, MSGL_ERR,
+ "[demux_mf] --mf-type set to an unknown codec!\n");
+ }
}
+ return NULL;
}
-static int demux_check_file(demuxer_t *demuxer)
-{
- if (demuxer->stream->type == STREAMTYPE_MF)
- return 0;
- mf_t *mf = open_mf(demuxer);
- bool ok = mf && probe_format(mf);
- free_mf(mf);
- return ok ? 0 : -1;
-}
-
-static int demux_open_mf(demuxer_t* demuxer)
+static int demux_open_mf(demuxer_t* demuxer, enum demux_check check)
{
sh_video_t *sh_video = NULL;
+ mf_t *mf;
+
+ if (strncmp(demuxer->stream->url, "mf://", 5) == 0 &&
+ demuxer->stream->type == STREAMTYPE_MF)
<