ffmpeg # probesize & analyzeduration

avformat_find_stream_info的調(diào)用堆棧.png

ffmpeg在avformat_find_stream_info中會(huì)讀取一部分源文件的音視頻數(shù)據(jù),來分析文件信息,那么這個(gè)操作讀取多少數(shù)據(jù)呢?
答案是: 通過probesize和analyzeduration兩個(gè)參數(shù)來控制

Some applications, including the ffmpeg command-line tool, can only work with streams that were detected during the initial scan; streams that are detected later are ignored.

The size of the initial scan is controlled by two options: probesize (default ~5 Mo) and analyzeduration (default 5,000,000 μs = 5 s). For the subtitle stream to be detected, both values must be large enough.

直接用命令行查看這兩個(gè)參數(shù):

[root@localhost ffmpeg_v4.0]# ./ffmpeg -h full | grep 'analyzeduration\|probesize'
ffmpeg version N-91445-g6cc6b61 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-11)
  configuration: --enable-gpl --enable-debug=3 --enable-libmfx --disable-optimizations --disable-stripping
  libavutil      56. 18.102 / 56. 18.102
  libavcodec     58. 21.104 / 58. 21.104
  libavformat    58. 17.101 / 58. 17.101
  libavdevice    58.  4.101 / 58.  4.101
  libavfilter     7. 25.100 /  7. 25.100
  libswscale      5.  2.100 /  5.  2.100
  libswresample   3.  2.100 /  3.  2.100
  libpostproc    55.  2.100 / 55.  2.100
  -probesize         <int64>      .D....... set probing size (from 32 to I64_MAX) (default 5e+06)
  -formatprobesize   <int>        .D....... number of bytes to probe file format (from 0 to 2.14748e+09) (default 1.04858e+06)
  -analyzeduration   <int64>      .D....... specify how many microseconds are analyzed to probe the input (from 0 to I64_MAX) (default 0)
  -fpsprobesize      <int>        .D....... number of frames used to probe fps (from -1 to 2.14748e+09) (default -1)

-probesize和 -analyzeduration定義在libavformat/options_table.h

static const AVOption avformat_options[] = {
...
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT64, {.i64 = 5000000 }, 32, INT64_MAX, D},
...
{"analyzeduration", "specify how many microseconds are analyzed to probe the input", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, D},
...
}

可以看到probesize默認(rèn)為5000000, 而analyzeduration默認(rèn)為0.

傳入的參數(shù)保存在libavformat/avformat.h中AVFormatContext的probesize和max_analyze_duration變量中。

typedef struct AVFormatContext {
...
    /**
     * Maximum size of the data read from input for determining
     * the input container format.
     * Demuxing only, set by the caller before avformat_open_input().
     */
    int64_t probesize;

    /**
     * Maximum duration (in AV_TIME_BASE units) of the data read
     * from input in avformat_find_stream_info().
     * Demuxing only, set by the caller before avformat_find_stream_info().
     * Can be set to 0 to let avformat choose using a heuristic.
     */
    int64_t max_analyze_duration;
...
}

從上可以看出probesize是從源文件中讀取的最大字節(jié)數(shù),單位為字節(jié)。
max_analyze_duration是從文件中讀取的最大時(shí)長,單位為 AV_TIME_BASE units

/**
 * Internal time base represented as integer
 */

#define AV_TIME_BASE            1000000
‘probesize integer (input)’

Set probing size in bytes, i.e. the size of the data to analyze to get stream information.
A higher value will enable detecting more information in case it is dispersed into the stream, but will increase latency.
Must be an integer not lesser than 32.
It is 5000000 by default.

probesize的單位是字節(jié)。
最小是32字節(jié)。
默認(rèn)是 5000000字節(jié)。

‘a(chǎn)nalyzeduration integer (input)’

Specify how many microseconds are analyzed to probe the input.
A higher value will enable detecting more accurate information, but will increase latency.
It defaults to 5,000,000 microseconds = 5 seconds.

avformat_find_stream_info函數(shù)中:

    max_stream_analyze_duration = max_analyze_duration;
    max_subtitle_analyze_duration = max_analyze_duration;
    if (!max_analyze_duration) {
        max_stream_analyze_duration =
        max_analyze_duration        = 5*AV_TIME_BASE;
        max_subtitle_analyze_duration = 30*AV_TIME_BASE;
        if (!strcmp(ic->iformat->name, "flv"))
            max_stream_analyze_duration = 90*AV_TIME_BASE;
        if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts"))
            max_stream_analyze_duration = 7*AV_TIME_BASE;
    }

可以看到analyzeduration參數(shù)不設(shè)置時(shí),即analyzeduration默認(rèn)等于0時(shí),可以看到默認(rèn)的分析時(shí)長為5秒:

 max_analyze_duration        = 5*AV_TIME_BASE;

而如果是flv文件的時(shí)候, 默認(rèn)為90秒

if (!strcmp(ic->iformat->name, "flv"))
            max_stream_analyze_duration = 90*AV_TIME_BASE;

mpeg和mpegts文件的時(shí)候,默認(rèn)7秒:

 if (!strcmp(ic->iformat->name, "mpeg") || !strcmp(ic->iformat->name, "mpegts"))
            max_stream_analyze_duration = 7*AV_TIME_BASE;

probesize & analyzeduration 同時(shí)存在 聽誰的?

To coerce ffmpeg to search further for the subtitle stream, use options:

 -probesize <bytes> -analyzeduration <Maximum duration in AV_TIME_BASE units>

which will cause ffmpeg to search until the first of those limits is reached.
Note that both of these options must appear on the command line before the specification of the input via -i. For example:

ffmpeg -probesize 50M -analyzeduration 100M -i vts.vob

will search through vts.vob for all streams until it has read 50 MB of data or 100 seconds of video, whichever comes first.

結(jié)論是: 誰先達(dá)到就聽誰的
以上的例子是讀取50M的數(shù)據(jù)或100秒的數(shù)據(jù),那個(gè)標(biāo)準(zhǔn)先達(dá)到,那就聽誰的,停止probe

References:

ffmpeg/doc/ffmpeg-formats.texi
ffmpeg/doc/faq.texi
https://ffmpeg.org/ffmpeg-formats.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容