mirror of
https://github.com/mpv-player/mpv
synced 2025-03-15 03:14:30 +01:00
demuxer.c: clean up demux_open_stream()
Refactor the code to avoid duplication. Behavior should be mostly the same as before.
This commit is contained in:
parent
7b076f79a9
commit
b98821de7c
@ -922,163 +922,125 @@ int get_demuxer_type_from_name(char *demuxer_name, int *force)
|
|||||||
|
|
||||||
int extension_parsing = 1; // 0=off 1=mixed (used only for unstable formats)
|
int extension_parsing = 1; // 0=off 1=mixed (used only for unstable formats)
|
||||||
|
|
||||||
/*
|
static struct demuxer *open_given_type(struct MPOpts *opts,
|
||||||
NOTE : Several demuxers may be opened at the same time so
|
const struct demuxer_desc *desc,
|
||||||
demuxers should NEVER rely on an external var to enable them
|
struct stream *stream, bool force,
|
||||||
self. If a demuxer can't do any auto-detection it should only use
|
int audio_id, int video_id, int sub_id,
|
||||||
file_format. The user can explicitly set file_format with the -demuxer
|
char *filename)
|
||||||
option so there is really no need for another extra var.
|
|
||||||
For convenience an option can be added to set file_format directly
|
|
||||||
to the right type (ex: rawaudio,rawvideo).
|
|
||||||
Also the stream can override the file_format so a demuxer which rely
|
|
||||||
on a special stream type can set file_format at the stream level
|
|
||||||
(ex: tv,mf).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static demuxer_t *demux_open_stream(struct MPOpts *opts, stream_t *stream,
|
|
||||||
int file_format, int force, int audio_id,
|
|
||||||
int video_id, int dvdsub_id,
|
|
||||||
char *filename)
|
|
||||||
{
|
{
|
||||||
demuxer_t *demuxer = NULL;
|
struct demuxer *demuxer;
|
||||||
|
int fformat;
|
||||||
|
demuxer = new_demuxer(opts, stream, desc->type, audio_id,
|
||||||
|
video_id, sub_id, filename);
|
||||||
|
if (desc->check_file)
|
||||||
|
fformat = desc->check_file(demuxer);
|
||||||
|
else
|
||||||
|
fformat = desc->type;
|
||||||
|
if (force)
|
||||||
|
fformat = desc->type;
|
||||||
|
if (fformat == 0)
|
||||||
|
goto fail;
|
||||||
|
if (fformat == desc->type) {
|
||||||
|
mp_tmsg(MSGT_DEMUXER, MSGL_INFO, "%s file format detected.\n",
|
||||||
|
desc->shortdesc);
|
||||||
|
if (demuxer->desc->open) {
|
||||||
|
struct demuxer *demux2 = demuxer->desc->open(demuxer);
|
||||||
|
if (!demux2) {
|
||||||
|
mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "Opening as detected format "
|
||||||
|
"\"%s\" failed.\n", desc->shortdesc);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/* At least demux_mov can return a demux_demuxers instance
|
||||||
|
* from open() instead of the original fed in. */
|
||||||
|
demuxer = demux2;
|
||||||
|
}
|
||||||
|
demuxer->file_format = fformat;
|
||||||
|
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, audio_id,
|
||||||
|
video_id, sub_id, filename);
|
||||||
|
}
|
||||||
|
fail:
|
||||||
|
free_demuxer(demuxer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sh_video_t *sh_video = NULL;
|
static struct demuxer *demux_open_stream(struct MPOpts *opts,
|
||||||
|
struct stream *stream,
|
||||||
const demuxer_desc_t *demuxer_desc;
|
int file_format, bool force,
|
||||||
int fformat = 0;
|
int audio_id, int video_id, int sub_id,
|
||||||
int i;
|
char *filename)
|
||||||
|
{
|
||||||
|
struct demuxer *demuxer = NULL;
|
||||||
|
const struct demuxer_desc *desc;
|
||||||
|
|
||||||
// If somebody requested a demuxer check it
|
// If somebody requested a demuxer check it
|
||||||
if (file_format) {
|
if (file_format) {
|
||||||
if ((demuxer_desc = get_demuxer_desc_from_type(file_format))) {
|
desc = get_demuxer_desc_from_type(file_format);
|
||||||
demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id,
|
if (!desc)
|
||||||
video_id, dvdsub_id, filename);
|
// should only happen with obsolete -demuxer 99 numeric format
|
||||||
if (demuxer_desc->check_file)
|
|
||||||
fformat = demuxer_desc->check_file(demuxer);
|
|
||||||
if (force || !demuxer_desc->check_file)
|
|
||||||
fformat = demuxer_desc->type;
|
|
||||||
if (fformat != 0) {
|
|
||||||
if (fformat == demuxer_desc->type) {
|
|
||||||
demuxer_t *demux2 = demuxer;
|
|
||||||
// Move messages to demuxer detection code?
|
|
||||||
mp_tmsg(MSGT_DEMUXER, MSGL_INFO,
|
|
||||||
"%s file format detected.\n",
|
|
||||||
demuxer_desc->shortdesc);
|
|
||||||
file_format = fformat;
|
|
||||||
if (!demuxer->desc->open
|
|
||||||
|| (demux2 = demuxer->desc->open(demuxer))) {
|
|
||||||
demuxer = demux2;
|
|
||||||
goto dmx_open;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Format changed after check, recurse
|
|
||||||
free_demuxer(demuxer);
|
|
||||||
return demux_open_stream(opts, stream, fformat, force,
|
|
||||||
audio_id, video_id, dvdsub_id,
|
|
||||||
filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check failed for forced demuxer, quit
|
|
||||||
free_demuxer(demuxer);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
demuxer = open_given_type(opts, desc, stream, force, audio_id,
|
||||||
|
video_id, sub_id, filename);
|
||||||
|
if (demuxer)
|
||||||
|
goto dmx_open;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test demuxers with safe file checks
|
// Test demuxers with safe file checks
|
||||||
for (i = 0; (demuxer_desc = demuxer_list[i]); i++) {
|
for (int i = 0; (desc = demuxer_list[i]); i++) {
|
||||||
if (demuxer_desc->safe_check) {
|
if (desc->safe_check) {
|
||||||
demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id,
|
demuxer = open_given_type(opts, desc, stream, false, audio_id,
|
||||||
video_id, dvdsub_id, filename);
|
video_id, sub_id, filename);
|
||||||
if ((fformat = demuxer_desc->check_file(demuxer)) != 0) {
|
if (demuxer)
|
||||||
if (fformat == demuxer_desc->type) {
|
goto dmx_open;
|
||||||
demuxer_t *demux2 = demuxer;
|
|
||||||
mp_tmsg(MSGT_DEMUXER, MSGL_INFO,
|
|
||||||
"%s file format detected.\n",
|
|
||||||
demuxer_desc->shortdesc);
|
|
||||||
file_format = fformat;
|
|
||||||
if (!demuxer->desc->open
|
|
||||||
|| (demux2 = demuxer->desc->open(demuxer))) {
|
|
||||||
demuxer = demux2;
|
|
||||||
goto dmx_open;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (fformat == DEMUXER_TYPE_PLAYLIST)
|
|
||||||
return demuxer; // handled in mplayer.c
|
|
||||||
// Format changed after check, recurse
|
|
||||||
free_demuxer(demuxer);
|
|
||||||
demuxer = demux_open_stream(opts, stream, fformat, force,
|
|
||||||
audio_id, video_id,
|
|
||||||
dvdsub_id, filename);
|
|
||||||
if (demuxer)
|
|
||||||
return demuxer; // done!
|
|
||||||
file_format = DEMUXER_TYPE_UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free_demuxer(demuxer);
|
|
||||||
demuxer = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no forced demuxer perform file extension based detection
|
|
||||||
// Ok. We're over the stable detectable fileformats, the next ones are
|
// Ok. We're over the stable detectable fileformats, the next ones are
|
||||||
// a bit fuzzy. So by default (extension_parsing==1) try extension-based
|
// a bit fuzzy. So by default (extension_parsing==1) try extension-based
|
||||||
// detection first:
|
// detection first:
|
||||||
if (file_format == DEMUXER_TYPE_UNKNOWN && filename
|
if (filename && extension_parsing == 1) {
|
||||||
&& extension_parsing == 1) {
|
desc = get_demuxer_desc_from_type(demuxer_type_by_filename(filename));
|
||||||
file_format = demuxer_type_by_filename(filename);
|
if (desc)
|
||||||
if (file_format != DEMUXER_TYPE_UNKNOWN) {
|
demuxer = open_given_type(opts, desc, stream, false, audio_id,
|
||||||
// we like recursion :)
|
video_id, sub_id, filename);
|
||||||
demuxer = demux_open_stream(opts, stream, file_format, force,
|
if (demuxer)
|
||||||
audio_id, video_id, dvdsub_id,
|
goto dmx_open;
|
||||||
filename);
|
|
||||||
if (demuxer)
|
|
||||||
return demuxer; // done!
|
|
||||||
file_format = DEMUXER_TYPE_UNKNOWN; // continue fuzzy guessing...
|
|
||||||
mp_msg(MSGT_DEMUXER, MSGL_V,
|
|
||||||
"demuxer: continue fuzzy content-based format guessing...\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Try detection for all other demuxers
|
|
||||||
for (i = 0; (demuxer_desc = demuxer_list[i]); i++) {
|
// Finally try detection for demuxers with unsafe checks
|
||||||
if (!demuxer_desc->safe_check && demuxer_desc->check_file) {
|
for (int i = 0; (desc = demuxer_list[i]); i++) {
|
||||||
demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id,
|
if (!desc->safe_check && desc->check_file) {
|
||||||
video_id, dvdsub_id, filename);
|
demuxer = open_given_type(opts, desc, stream, false, audio_id,
|
||||||
if ((fformat = demuxer_desc->check_file(demuxer)) != 0) {
|
video_id, sub_id, filename);
|
||||||
if (fformat == demuxer_desc->type) {
|
if (demuxer)
|
||||||
demuxer_t *demux2 = demuxer;
|
goto dmx_open;
|
||||||
mp_tmsg(MSGT_DEMUXER, MSGL_INFO,
|
|
||||||
"%s file format detected.\n",
|
|
||||||
demuxer_desc->shortdesc);
|
|
||||||
file_format = fformat;
|
|
||||||
if (!demuxer->desc->open
|
|
||||||
|| (demux2 = demuxer->desc->open(demuxer))) {
|
|
||||||
demuxer = demux2;
|
|
||||||
goto dmx_open;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (fformat == DEMUXER_TYPE_PLAYLIST)
|
|
||||||
return demuxer; // handled in mplayer.c
|
|
||||||
// Format changed after check, recurse
|
|
||||||
free_demuxer(demuxer);
|
|
||||||
demuxer = demux_open_stream(opts, stream, fformat, force,
|
|
||||||
audio_id, video_id,
|
|
||||||
dvdsub_id, filename);
|
|
||||||
if (demuxer)
|
|
||||||
return demuxer; // done!
|
|
||||||
file_format = DEMUXER_TYPE_UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free_demuxer(demuxer);
|
|
||||||
demuxer = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
//====== File format recognized, set up these for compatibility: =========
|
|
||||||
dmx_open:
|
dmx_open:
|
||||||
|
|
||||||
demuxer->file_format = file_format;
|
if (demuxer->type == DEMUXER_TYPE_PLAYLIST)
|
||||||
|
return demuxer;
|
||||||
|
|
||||||
if ((sh_video = demuxer->video->sh) && sh_video->bih) {
|
struct sh_video *sh_video = demuxer->video->sh;
|
||||||
|
if (sh_video && sh_video->bih) {
|
||||||
int biComp = le2me_32(sh_video->bih->biCompression);
|
int biComp = le2me_32(sh_video->bih->biCompression);
|
||||||
mp_msg(MSGT_DEMUX, MSGL_INFO,
|
mp_msg(MSGT_DEMUX, MSGL_INFO,
|
||||||
"VIDEO: [%.4s] %dx%d %dbpp %5.3f fps %5.1f kbps (%4.1f kbyte/s)\n",
|
"VIDEO: [%.4s] %dx%d %dbpp %5.3f fps %5.1f kbps (%4.1f kbyte/s)\n",
|
||||||
@ -1089,7 +1051,7 @@ static demuxer_t *demux_open_stream(struct MPOpts *opts, stream_t *stream,
|
|||||||
}
|
}
|
||||||
#ifdef CONFIG_ASS
|
#ifdef CONFIG_ASS
|
||||||
if (opts->ass_enabled && ass_library) {
|
if (opts->ass_enabled && ass_library) {
|
||||||
for (i = 0; i < MAX_S_STREAMS; ++i) {
|
for (int i = 0; i < MAX_S_STREAMS; ++i) {
|
||||||
sh_sub_t *sh = demuxer->s_streams[i];
|
sh_sub_t *sh = demuxer->s_streams[i];
|
||||||
if (sh && sh->type == 'a') {
|
if (sh && sh->type == 'a') {
|
||||||
sh->ass_track = ass_new_track(ass_library);
|
sh->ass_track = ass_new_track(ass_library);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user