diff options
-rw-r--r-- | DOCS/man/en/options.rst | 6 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | core/mplayer.c | 6 | ||||
-rw-r--r-- | core/options.c | 2 | ||||
-rw-r--r-- | core/options.h | 1 | ||||
-rw-r--r-- | core/timeline/tl_matroska.c | 2 | ||||
-rw-r--r-- | demux/demux.c | 220 | ||||
-rw-r--r-- | demux/demux.h | 50 | ||||
-rw-r--r-- | demux/demux_cue.c | 23 | ||||
-rw-r--r-- | demux/demux_edl.c | 23 | ||||
-rw-r--r-- | demux/demux_lavf.c | 18 | ||||
-rw-r--r-- | demux/demux_libass.c | 61 | ||||
-rw-r--r-- | demux/demux_mf.c | 77 | ||||
-rw-r--r-- | demux/demux_mkv.c | 5 | ||||
-rw-r--r-- | demux/demux_mng.c | 31 | ||||
-rw-r--r-- | demux/demux_rawaudio.c | 7 | ||||
-rw-r--r-- | demux/demux_rawvideo.c | 7 | ||||
-rw-r--r-- | demux/demux_subreader.c | 9 | ||||
-rw-r--r-- | demux/extension.c | 101 | ||||
-rw-r--r-- | stream/stream_dvb.c | 3 | ||||
-rw-r--r-- | stream/stream_mf.c | 2 | ||||
-rw-r--r-- | stream/tv.c | 5 |
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``. @@ -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) < |