Использование параллельного декодера в libavcodec/ffmpeg

Проблема

Я пишу простую программу на языке C, которая использует libavcodec (https://github.com/Dr-Noob/framepos/blob/master/framepos.c)

Я работаю с видео h264. Пока декодирование работает, я вижу, что оно очень медленное, так как использует только 1 ядро ​​процессора (проверил с помощью top). С другой стороны, я знаю, что ffmpeg, который использует тот же libavocdec, установленный в моей системе, использует параллельный декодер h264. Я могу проверить это с помощью:

ffmpeg -c:v h264 -i test.mkv -f null -

С top я вижу, что он работает параллельно, и скорость заметно выше. Я хотел бы решение, которое всегда дает мне возможность декодировать видео, используя все ядра процессора, а не только в случае с кодеком h264.

Мои исследования до сих пор

Глядя на код ffmpeg, можно увидеть, что для получения AVCodec используется функция find_codec_or_die. Это закончится использованием avcodec_find_decoder_by_name. На самом деле, если в своей программе я использую эту функцию, запрашивая декодер h264, я все равно получаю последовательную версию. Более того, используя gdb в ffmpeg, я увидел, что AVCodec в ffmpeg называется ff_h264_decoder, а в моем коде gdb не знает, какой именно тип кодека. Суффикс ff заставляет меня думать, что это параллельный декодер (потому что похоже, что ff имеет какое-то отношение к parallel в контексте ffmpeg (https://ffmpeg.org/doxygen/2.7/pthread__frame_8c.html)). Однако, похоже, я не могу получить этот кодек.

Что я могу сделать для параллельного декодирования видео с помощью libavcodec в C?


person DrNoob    schedule 22.08.2020    source источник
comment
AVCodec не определяет многопоточность — это свойство AVCodecContext::thread_count (которое должно быть установлено перед avcodec_open2()) ffmpeg .org/doxygen/2.7/structAVCodecContext.htm   -  person gkv311    schedule 22.08.2020


Ответы (1)


Публикация комментария gkv311 в качестве ответа для дальнейшего использования.

AVCodec не поддерживает многопоточность. Он хранится внутри AVCodecContex. Итак, возможная схема запуска кодека параллельно:

AVCodec *codec = avcodec_find_decoder
AVCodecContext *ctx = avcodec_alloc_context3

ctx->thread_count = n_threads;
ctx->thread_type = FF_THREAD_FRAME;

avcodec_open2(ctx, fmt_ctx->video_codec, NULL)
person DrNoob    schedule 22.08.2020