Я реализую бэкэнд для чтения аудио для системы машинного обучения. Это означает, что декодирование должно быть быстрым. Возможные форматы: .wav
, .gsm
, .opus
.
Я реализовал декодирование звука в FFMPEG: https://github.com/vadimkantorov/readaudio/blob/master/decode_audio_ffmpeg.c
В настоящее время используется scipy.io.wavfile.read
для 5-секундного файла 8 кГц .wav
(типичный файл для моей рабочей нагрузки; на практике я загружаю и обрабатываю около 1 Кб таких файлов параллельно) занимает около 0,02 миллисекунды (в среднем при чтении того же файла 100 раз). Это разумно, потому что формат .wav
довольно прост.
В моем коде FFMPEG только вызов, выполняющий avformat_open_input
и avformat_find_stream_info()
, занимает около 0,45 миллисекунды (с fmt_ctx->streams[0]-probe_packets=1
) и в 20 раз медленнее, чем scipy.io.wavfile.read
.
Пока soundfile.read
в 5 раз медленнее scipy.io.wavfile.read
, ffmpeg
в 4 раза медленнее soundfile.read
. Таким образом, в целом ffmpeg
в 20 раз медленнее, чем scipy.io.wavfile.read
.
Кто-нибудь знает, как избежать этой задержки? По-прежнему кажется, что avformat_open_input
и avformat_find_stream_info()
делают слишком много работы.
Я оптимизировал зондирование, установив probe_packets=1
, и использовал AVIO
для управления буферизованным чтением. Я думаю, что IO теперь хорошо оптимизирован ...
Журнал после оптимизации:
[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
Эта проблема хорошо известна, но Мне пока не удалось найти обходной путь: