Audio 使用FFMPEG的快速WAV音频解码:加速avformat\u open\u input/avformat\u find\u stream\u info

Audio 使用FFMPEG的快速WAV音频解码:加速avformat\u open\u input/avformat\u find\u stream\u info,audio,ffmpeg,Audio,Ffmpeg,我正在为机器学习系统实现一个音频读取后端。这意味着解码应该是快速的。可能的格式有.wav,.gsm,.opus 我已经在FFMPEG中实现了音频解码: 目前,在5秒8khz.wav文件(我的工作负载的典型文件;实际上,我并行加载和处理大约1K个这样的文件)上使用大约需要0.02毫秒(平均读取同一文件100次)。这是合理的,因为.wav格式非常简单 在我的FFMPEG代码中,仅调用doingavformat\u open\u input,大约需要0.45毫秒(使用fmt\u ctx->stream

我正在为机器学习系统实现一个音频读取后端。这意味着解码应该是快速的。可能的格式有
.wav
.gsm
.opus

我已经在FFMPEG中实现了音频解码:

目前,在5秒8khz
.wav
文件(我的工作负载的典型文件;实际上,我并行加载和处理大约1K个这样的文件)上使用大约需要0.02毫秒(平均读取同一文件100次)。这是合理的,因为
.wav
格式非常简单

在我的FFMPEG代码中,仅调用doing
avformat\u open\u input
,大约需要0.45毫秒(使用
fmt\u ctx->streams[0]-probe\u packets=1
),比
scipy.io.wavfile.read慢20倍

到目前为止,
soundfile.read
scipy.io.wavfile.read
慢5倍,
ffmpeg
soundfile.read
慢4倍。所以总的来说,
ffmpeg
scipy.io.wavfile.read
慢20倍

有人知道如何避免这种延迟攻击吗?似乎
avformat\u open\u input
avformat\u find\u stream\u info()
做了太多的工作

我通过设置
probe_packets=1
优化了探测,并使用
AVIO
控制缓冲读取。我想我现在没事了

优化后的日志:

[wav @ 0x55f151175240] Format wav probed with size=2048 and score=99
decode_audio_BEFORE: 0.55 msec
[wav @ 0x55f151175240] Before avformat_find_stream_info() pos: 78 bytes read:65614 seeks:1 nb_streams:1
[wav @ 0x55f151175240] probing stream 0 pp:1
[wav @ 0x55f151175240] Probe with size=4096, packets=2500 detected mp3 with score=1
[wav @ 0x55f151175240] probed stream 0
[wav @ 0x55f151175240] parser not found for codec pcm_s16le, packets or times may be invalid.
[wav @ 0x55f151175240] After avformat_find_stream_info() pos: 80078 bytes read:145614 seeks:1 frames:20
decode_audio_BEFORE: 0.61 msec
[wav @ 0x563667d57b60] Before avformat_find_stream_info() pos: 78 bytes read:65614 seeks:1 nb_streams:1
[wav @ 0x563667d57b60] probing stream 0 pp:32
[wav @ 0x563667d57b60] Probe with size=4096, packets=2469 detected mp3 with score=1
[wav @ 0x563667d57b60] probing stream 0 pp:31
[wav @ 0x563667d57b60] Probe with size=8192, packets=2470 detected mp3 with score=1
[wav @ 0x563667d57b60] probing stream 0 pp:30
[wav @ 0x563667d57b60] probing stream 0 pp:29
[wav @ 0x563667d57b60] Probe with size=16384, packets=2472 detected mp3 with score=1
[wav @ 0x563667d57b60] probing stream 0 pp:28
[wav @ 0x563667d57b60] probing stream 0 pp:27
[wav @ 0x563667d57b60] probing stream 0 pp:26
[wav @ 0x563667d57b60] probing stream 0 pp:25
[wav @ 0x563667d57b60] probing stream 0 pp:24
[wav @ 0x563667d57b60] probing stream 0 pp:23
[wav @ 0x563667d57b60] probing stream 0 pp:22
[wav @ 0x563667d57b60] probing stream 0 pp:21
[wav @ 0x563667d57b60] probing stream 0 pp:20
[wav @ 0x563667d57b60] probing stream 0 pp:19
[wav @ 0x563667d57b60] probing stream 0 pp:18
[wav @ 0x563667d57b60] probing stream 0 pp:17
[wav @ 0x563667d57b60] probing stream 0 pp:16
[wav @ 0x563667d57b60] probing stream 0 pp:15
[wav @ 0x563667d57b60] probing stream 0 pp:14
[wav @ 0x563667d57b60] probing stream 0 pp:13
[wav @ 0x563667d57b60] probing stream 0 pp:12
[wav @ 0x563667d57b60] probed stream 0
[wav @ 0x563667d57b60] parser not found for codec pcm_s16le, packets or times may be invalid.
[wav @ 0x563667d57b60] After avformat_find_stream_info() pos: 80078 bytes read:145614 seeks:1 frames:20
decode_audio_AFTER: 7.90 msec
优化前记录:

[wav @ 0x55f151175240] Format wav probed with size=2048 and score=99
decode_audio_BEFORE: 0.55 msec
[wav @ 0x55f151175240] Before avformat_find_stream_info() pos: 78 bytes read:65614 seeks:1 nb_streams:1
[wav @ 0x55f151175240] probing stream 0 pp:1
[wav @ 0x55f151175240] Probe with size=4096, packets=2500 detected mp3 with score=1
[wav @ 0x55f151175240] probed stream 0
[wav @ 0x55f151175240] parser not found for codec pcm_s16le, packets or times may be invalid.
[wav @ 0x55f151175240] After avformat_find_stream_info() pos: 80078 bytes read:145614 seeks:1 frames:20
decode_audio_BEFORE: 0.61 msec
[wav @ 0x563667d57b60] Before avformat_find_stream_info() pos: 78 bytes read:65614 seeks:1 nb_streams:1
[wav @ 0x563667d57b60] probing stream 0 pp:32
[wav @ 0x563667d57b60] Probe with size=4096, packets=2469 detected mp3 with score=1
[wav @ 0x563667d57b60] probing stream 0 pp:31
[wav @ 0x563667d57b60] Probe with size=8192, packets=2470 detected mp3 with score=1
[wav @ 0x563667d57b60] probing stream 0 pp:30
[wav @ 0x563667d57b60] probing stream 0 pp:29
[wav @ 0x563667d57b60] Probe with size=16384, packets=2472 detected mp3 with score=1
[wav @ 0x563667d57b60] probing stream 0 pp:28
[wav @ 0x563667d57b60] probing stream 0 pp:27
[wav @ 0x563667d57b60] probing stream 0 pp:26
[wav @ 0x563667d57b60] probing stream 0 pp:25
[wav @ 0x563667d57b60] probing stream 0 pp:24
[wav @ 0x563667d57b60] probing stream 0 pp:23
[wav @ 0x563667d57b60] probing stream 0 pp:22
[wav @ 0x563667d57b60] probing stream 0 pp:21
[wav @ 0x563667d57b60] probing stream 0 pp:20
[wav @ 0x563667d57b60] probing stream 0 pp:19
[wav @ 0x563667d57b60] probing stream 0 pp:18
[wav @ 0x563667d57b60] probing stream 0 pp:17
[wav @ 0x563667d57b60] probing stream 0 pp:16
[wav @ 0x563667d57b60] probing stream 0 pp:15
[wav @ 0x563667d57b60] probing stream 0 pp:14
[wav @ 0x563667d57b60] probing stream 0 pp:13
[wav @ 0x563667d57b60] probing stream 0 pp:12
[wav @ 0x563667d57b60] probed stream 0
[wav @ 0x563667d57b60] parser not found for codec pcm_s16le, packets or times may be invalid.
[wav @ 0x563667d57b60] After avformat_find_stream_info() pos: 80078 bytes read:145614 seeks:1 frames:20
decode_audio_AFTER: 7.90 msec
这个问题是众所周知的,但到目前为止我找不到解决方法:


为什么不手动选择解码器(编解码器)并完全绕过探测?如本例所示:。这里
avcodec\u find\u解码器(AV\u CODEC\u ID\u MP2)用于手动选择编解码器。它还会为我解复用文件格式吗?至少我想支持wav/opus/gsm的快速读取。充其量我也希望支持m4a/webm。我不太理解ffmpeg术语:格式/解析器/编解码器。您的示例使用«解析器»而不处理«格式»(而我的示例使用«格式»而不使用«解析器»)。是否需要«格式»?或者«解析器»真的足够了吗?看起来应该没问题,对吧?如果我知道格式,我可以直接指定例如
AV\u CODEC\u ID\u PCM\u S16LE
,然后使用解析器,对吗?但仍然很有趣的是,为什么ffmpeg要花这么多时间猜测格式。在简单的情况下,检查几个头字节就足够了(特别是对于WAV),不是吗?据我所知,在您的情况下,您不需要进行探测。答案是肯定的。为什么不手动选择解码器(编解码器)并完全绕过探测呢?如本例所示:。这里
avcodec\u find\u解码器(AV\u CODEC\u ID\u MP2)用于手动选择编解码器。它还会为我解复用文件格式吗?至少我想支持wav/opus/gsm的快速读取。充其量我也希望支持m4a/webm。我不太理解ffmpeg术语:格式/解析器/编解码器。您的示例使用«解析器»而不处理«格式»(而我的示例使用«格式»而不使用«解析器»)。是否需要«格式»?或者«解析器»真的足够了吗?看起来应该没问题,对吧?如果我知道格式,我可以直接指定例如
AV\u CODEC\u ID\u PCM\u S16LE
,然后使用解析器,对吗?但仍然很有趣的是,为什么ffmpeg要花这么多时间猜测格式。在简单的情况下,检查几个头字节就足够了(特别是对于WAV),不是吗?据我所知,在您的情况下,您不需要进行探测。答案是肯定的。