mirror of https://github.com/mpv-player/mpv
demux_lavf: make minimum probe score customizable, remove lavf_preferred
libavformat wants to read a full ~400KB of data to determine whether it's really AAC. This causes slow startup with AAC web radio streams [1] (possible due to a broken initial packet). There are similar issues with other file formats. Make the probe "score" (libavformat's mechanism for testing file formats) configurable with the -lavfdtops:probescore option. This allows lowering the amount of data read on probing. If the probe score is below the probescore option value, demux_lavf will try to get a higher score by feeding more data to libavformat, until the required score or the max. probe size is reached. Remove the lavf_preferred demuxer entry. This had a purpose in mplayer-svn, but now there doesn't seem to be any good reason for it to exist. Make sure that our native "good" demuxers are above demux_lavf in demuxer_list[] instead (so that they are preferred). [1] http://lr2mp0.latvijasradio.lv:8000
This commit is contained in:
parent
323eb54b60
commit
222a5cf7c0
|
@ -1028,6 +1028,12 @@
|
||||||
|
|
||||||
analyzeduration=<value>
|
analyzeduration=<value>
|
||||||
Maximum length in seconds to analyze the stream properties.
|
Maximum length in seconds to analyze the stream properties.
|
||||||
|
probescore=<1-100>
|
||||||
|
Minimum required libavformat probe score. Lower values will require
|
||||||
|
less data to be loaded (makes streams start faster), but makes file
|
||||||
|
format detection less reliable. Can be used to force auto-detected
|
||||||
|
libavformat demuxers, even if libavformat considers the detection not
|
||||||
|
reliable enough. (Default: 26.)
|
||||||
format=<value>
|
format=<value>
|
||||||
Force a specific libavformat demuxer.
|
Force a specific libavformat demuxer.
|
||||||
o=<key>=<value>[,<key>=<value>[,...]]
|
o=<key>=<value>[,<key>=<value>[,...]]
|
||||||
|
|
|
@ -150,6 +150,7 @@ typedef struct MPOpts {
|
||||||
|
|
||||||
struct lavfdopts {
|
struct lavfdopts {
|
||||||
unsigned int probesize;
|
unsigned int probesize;
|
||||||
|
int probescore;
|
||||||
unsigned int analyzeduration;
|
unsigned int analyzeduration;
|
||||||
char *format;
|
char *format;
|
||||||
char *cryptokey;
|
char *cryptokey;
|
||||||
|
|
|
@ -57,7 +57,6 @@ extern const demuxer_desc_t demuxer_desc_avi;
|
||||||
extern const demuxer_desc_t demuxer_desc_asf;
|
extern const demuxer_desc_t demuxer_desc_asf;
|
||||||
extern const demuxer_desc_t demuxer_desc_matroska;
|
extern const demuxer_desc_t demuxer_desc_matroska;
|
||||||
extern const demuxer_desc_t demuxer_desc_lavf;
|
extern const demuxer_desc_t demuxer_desc_lavf;
|
||||||
extern const demuxer_desc_t demuxer_desc_lavf_preferred;
|
|
||||||
extern const demuxer_desc_t demuxer_desc_mng;
|
extern const demuxer_desc_t demuxer_desc_mng;
|
||||||
extern const demuxer_desc_t demuxer_desc_mpeg_ps;
|
extern const demuxer_desc_t demuxer_desc_mpeg_ps;
|
||||||
extern const demuxer_desc_t demuxer_desc_mpeg_pes;
|
extern const demuxer_desc_t demuxer_desc_mpeg_pes;
|
||||||
|
@ -79,11 +78,10 @@ const demuxer_desc_t *const demuxer_list[] = {
|
||||||
#ifdef CONFIG_TV
|
#ifdef CONFIG_TV
|
||||||
&demuxer_desc_tv,
|
&demuxer_desc_tv,
|
||||||
#endif
|
#endif
|
||||||
&demuxer_desc_lavf_preferred,
|
|
||||||
&demuxer_desc_avi,
|
|
||||||
&demuxer_desc_asf,
|
|
||||||
&demuxer_desc_matroska,
|
&demuxer_desc_matroska,
|
||||||
&demuxer_desc_lavf,
|
&demuxer_desc_lavf,
|
||||||
|
&demuxer_desc_avi,
|
||||||
|
&demuxer_desc_asf,
|
||||||
#ifdef CONFIG_MNG
|
#ifdef CONFIG_MNG
|
||||||
&demuxer_desc_mng,
|
&demuxer_desc_mng,
|
||||||
#endif
|
#endif
|
||||||
|
@ -920,6 +918,7 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
|
||||||
{
|
{
|
||||||
struct demuxer *demuxer;
|
struct demuxer *demuxer;
|
||||||
int fformat;
|
int fformat;
|
||||||
|
mp_msg(MSGT_DEMUXER, MSGL_V, "Trying demuxer: %s\n", desc->name);
|
||||||
demuxer = new_demuxer(opts, stream, desc->type, audio_id,
|
demuxer = new_demuxer(opts, stream, desc->type, audio_id,
|
||||||
video_id, sub_id, filename);
|
video_id, sub_id, filename);
|
||||||
demuxer->params = params;
|
demuxer->params = params;
|
||||||
|
|
|
@ -68,7 +68,6 @@ enum demuxer_type {
|
||||||
DEMUXER_TYPE_AVS,
|
DEMUXER_TYPE_AVS,
|
||||||
DEMUXER_TYPE_AAC,
|
DEMUXER_TYPE_AAC,
|
||||||
DEMUXER_TYPE_MPC,
|
DEMUXER_TYPE_MPC,
|
||||||
DEMUXER_TYPE_LAVF_PREFERRED,
|
|
||||||
DEMUXER_TYPE_MNG,
|
DEMUXER_TYPE_MNG,
|
||||||
DEMUXER_TYPE_EDL,
|
DEMUXER_TYPE_EDL,
|
||||||
DEMUXER_TYPE_CUE,
|
DEMUXER_TYPE_CUE,
|
||||||
|
|
|
@ -49,13 +49,13 @@
|
||||||
#include "mp_taglists.h"
|
#include "mp_taglists.h"
|
||||||
|
|
||||||
#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
|
#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
|
||||||
#define SMALL_MAX_PROBE_SIZE (32 * 1024)
|
|
||||||
#define PROBE_BUF_SIZE (2 * 1024 * 1024)
|
#define PROBE_BUF_SIZE (2 * 1024 * 1024)
|
||||||
|
|
||||||
const m_option_t lavfdopts_conf[] = {
|
const m_option_t lavfdopts_conf[] = {
|
||||||
OPT_INTRANGE("probesize", lavfdopts.probesize, 0, 32, INT_MAX),
|
OPT_INTRANGE("probesize", lavfdopts.probesize, 0, 32, INT_MAX),
|
||||||
OPT_STRING("format", lavfdopts.format, 0),
|
OPT_STRING("format", lavfdopts.format, 0),
|
||||||
OPT_INTRANGE("analyzeduration", lavfdopts.analyzeduration, 0, 0, INT_MAX),
|
OPT_INTRANGE("analyzeduration", lavfdopts.analyzeduration, 0, 0, INT_MAX),
|
||||||
|
OPT_INTRANGE("probescore", lavfdopts.probescore, 0, 0, 100),
|
||||||
OPT_STRING("cryptokey", lavfdopts.cryptokey, 0),
|
OPT_STRING("cryptokey", lavfdopts.cryptokey, 0),
|
||||||
OPT_STRING("o", lavfdopts.avopt, 0),
|
OPT_STRING("o", lavfdopts.avopt, 0),
|
||||||
{NULL, NULL, 0, 0, 0, 0, NULL}
|
{NULL, NULL, 0, 0, 0, 0, NULL}
|
||||||
|
@ -175,7 +175,7 @@ static int lavf_check_file(demuxer_t *demuxer)
|
||||||
int read_size = INITIAL_PROBE_SIZE;
|
int read_size = INITIAL_PROBE_SIZE;
|
||||||
int score;
|
int score;
|
||||||
|
|
||||||
if (!demuxer->priv)
|
assert(!demuxer->priv);
|
||||||
demuxer->priv = talloc_zero(NULL, lavf_priv_t);
|
demuxer->priv = talloc_zero(NULL, lavf_priv_t);
|
||||||
priv = demuxer->priv;
|
priv = demuxer->priv;
|
||||||
priv->autoselect_sub = -1;
|
priv->autoselect_sub = -1;
|
||||||
|
@ -219,9 +219,16 @@ static int lavf_check_file(demuxer_t *demuxer)
|
||||||
}
|
}
|
||||||
mp_msg(MSGT_DEMUX, MSGL_INFO, "Forced lavf %s demuxer\n",
|
mp_msg(MSGT_DEMUX, MSGL_INFO, "Forced lavf %s demuxer\n",
|
||||||
priv->avif->long_name);
|
priv->avif->long_name);
|
||||||
return DEMUXER_TYPE_LAVF;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AVPROBE_SCORE_RETRY + 1 is the "recommended" limit. Below that, the user
|
||||||
|
// is supposed to retry with larger probe sizes until a higher value is
|
||||||
|
// reached.
|
||||||
|
int min_probe = AVPROBE_SCORE_RETRY + 1;
|
||||||
|
if (lavfdopts->probescore)
|
||||||
|
min_probe = lavfdopts->probescore;
|
||||||
|
|
||||||
avpd.buf = av_mallocz(FFMAX(BIO_BUFFER_SIZE, PROBE_BUF_SIZE) +
|
avpd.buf = av_mallocz(FFMAX(BIO_BUFFER_SIZE, PROBE_BUF_SIZE) +
|
||||||
FF_INPUT_BUFFER_PADDING_SIZE);
|
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
do {
|
do {
|
||||||
|
@ -237,19 +244,27 @@ static int lavf_check_file(demuxer_t *demuxer)
|
||||||
|
|
||||||
score = 0;
|
score = 0;
|
||||||
priv->avif = av_probe_input_format2(&avpd, probe_data_size > 0, &score);
|
priv->avif = av_probe_input_format2(&avpd, probe_data_size > 0, &score);
|
||||||
|
|
||||||
|
if (priv->avif) {
|
||||||
|
mp_msg(MSGT_HEADER, MSGL_V, "Found '%s' at score=%d size=%d.\n",
|
||||||
|
priv->avif->name, score, probe_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->avif && score >= min_probe)
|
||||||
|
break;
|
||||||
|
|
||||||
|
priv->avif = NULL;
|
||||||
read_size = FFMIN(2 * read_size, PROBE_BUF_SIZE - probe_data_size);
|
read_size = FFMIN(2 * read_size, PROBE_BUF_SIZE - probe_data_size);
|
||||||
} while ((demuxer->desc->type != DEMUXER_TYPE_LAVF_PREFERRED ||
|
} while (read_size > 0 && probe_data_size < PROBE_BUF_SIZE);
|
||||||
probe_data_size < SMALL_MAX_PROBE_SIZE) &&
|
|
||||||
score <= AVPROBE_SCORE_MAX / 4 &&
|
|
||||||
read_size > 0 && probe_data_size < PROBE_BUF_SIZE);
|
|
||||||
av_free(avpd.buf);
|
av_free(avpd.buf);
|
||||||
|
|
||||||
if (!priv->avif || score <= AVPROBE_SCORE_MAX / 4) {
|
if (!priv->avif) {
|
||||||
mp_msg(MSGT_HEADER, MSGL_V,
|
mp_msg(MSGT_HEADER, MSGL_V,
|
||||||
"LAVF_check: no clue about this gibberish!\n");
|
"No format found, try lowering probescore.\n");
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
}
|
||||||
mp_msg(MSGT_HEADER, MSGL_V, "LAVF_check: %s\n", priv->avif->long_name);
|
|
||||||
|
success:
|
||||||
|
|
||||||
demuxer->filetype = priv->avif->long_name;
|
demuxer->filetype = priv->avif->long_name;
|
||||||
if (!demuxer->filetype)
|
if (!demuxer->filetype)
|
||||||
|
@ -273,27 +288,6 @@ static bool matches_avinputformat_name(struct lavf_priv *priv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* formats for which an internal demuxer is preferred */
|
|
||||||
static const char * const preferred_internal[] = {
|
|
||||||
/* lavf Matroska demuxer doesn't support ordered chapters and fails
|
|
||||||
* for more files */
|
|
||||||
"matroska",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static int lavf_check_preferred_file(demuxer_t *demuxer)
|
|
||||||
{
|
|
||||||
if (lavf_check_file(demuxer)) {
|
|
||||||
const char * const *p;
|
|
||||||
lavf_priv_t *priv = demuxer->priv;
|
|
||||||
for (p = preferred_internal; *p; p++)
|
|
||||||
if (matches_avinputformat_name(priv, *p))
|
|
||||||
return 0;
|
|
||||||
return DEMUXER_TYPE_LAVF_PREFERRED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t char2int(char c)
|
static uint8_t char2int(char c)
|
||||||
{
|
{
|
||||||
if (c >= '0' && c <= '9') return c - '0';
|
if (c >= '0' && c <= '9') return c - '0';
|
||||||
|
@ -600,6 +594,10 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||||
lavf_priv_t *priv = demuxer->priv;
|
lavf_priv_t *priv = demuxer->priv;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// do not allow forcing the demuxer
|
||||||
|
if (!priv->avif)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
stream_seek(demuxer->stream, 0);
|
stream_seek(demuxer->stream, 0);
|
||||||
|
|
||||||
avfc = avformat_alloc_context();
|
avfc = avformat_alloc_context();
|
||||||
|
@ -659,13 +657,11 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->avfc = avfc;
|
priv->avfc = avfc;
|
||||||
|
|
||||||
if (avformat_find_stream_info(avfc, NULL) < 0) {
|
if (avformat_find_stream_info(avfc, NULL) < 0) {
|
||||||
mp_msg(MSGT_HEADER, MSGL_ERR,
|
mp_msg(MSGT_HEADER, MSGL_ERR,
|
||||||
"LAVF_header: av_find_stream_info() failed\n");
|
"LAVF_header: av_find_stream_info() failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add metadata. */
|
/* Add metadata. */
|
||||||
while ((t = av_dict_get(avfc->metadata, "", t,
|
while ((t = av_dict_get(avfc->metadata, "", t,
|
||||||
AV_DICT_IGNORE_SUFFIX)))
|
AV_DICT_IGNORE_SUFFIX)))
|
||||||
|
@ -1078,7 +1074,7 @@ const demuxer_desc_t demuxer_desc_lavf = {
|
||||||
"Michael Niedermayer",
|
"Michael Niedermayer",
|
||||||
"supports many formats, requires libavformat",
|
"supports many formats, requires libavformat",
|
||||||
DEMUXER_TYPE_LAVF,
|
DEMUXER_TYPE_LAVF,
|
||||||
0, // Check after other demuxer
|
1,
|
||||||
lavf_check_file,
|
lavf_check_file,
|
||||||
demux_lavf_fill_buffer,
|
demux_lavf_fill_buffer,
|
||||||
demux_open_lavf,
|
demux_open_lavf,
|
||||||
|
@ -1086,19 +1082,3 @@ const demuxer_desc_t demuxer_desc_lavf = {
|
||||||
demux_seek_lavf,
|
demux_seek_lavf,
|
||||||
demux_lavf_control
|
demux_lavf_control
|
||||||
};
|
};
|
||||||
|
|
||||||
const demuxer_desc_t demuxer_desc_lavf_preferred = {
|
|
||||||
"libavformat preferred demuxer",
|
|
||||||
"lavfpref",
|
|
||||||
"libavformat",
|
|
||||||
"Michael Niedermayer",
|
|
||||||
"supports many formats, requires libavformat",
|
|
||||||
DEMUXER_TYPE_LAVF_PREFERRED,
|
|
||||||
1,
|
|
||||||
lavf_check_preferred_file,
|
|
||||||
demux_lavf_fill_buffer,
|
|
||||||
demux_open_lavf,
|
|
||||||
demux_close_lavf,
|
|
||||||
demux_seek_lavf,
|
|
||||||
demux_lavf_control
|
|
||||||
};
|
|
||||||
|
|
|
@ -590,7 +590,6 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEMUXER_TYPE_LAVF:
|
case DEMUXER_TYPE_LAVF:
|
||||||
case DEMUXER_TYPE_LAVF_PREFERRED:
|
|
||||||
if((int)sh_video->fps==1000 || (int)sh_video->fps<=1){
|
if((int)sh_video->fps==1000 || (int)sh_video->fps<=1){
|
||||||
double next_pts = ds_get_next_pts(d_video);
|
double next_pts = ds_get_next_pts(d_video);
|
||||||
double d= (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts-pts1;
|
double d= (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts-pts1;
|
||||||
|
|
Loading…
Reference in New Issue