Декодирование MJPEG происходит в 3 раза медленнее при открытии устройства ввода V4L2.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Декодирование MJPEG происходит в 3 раза медленнее при открытии устройства ввода V4L2.

Сообщение Anonymous »

Я пытаюсь декодировать видеопоток MJPEG, поступающий с веб-камеры, но сталкиваюсь с некоторыми блокировщиками производительности при использовании C API FFmpeg. Я воссоздал проблему на примере видеодекодера, где я просто открываю устройство ввода V4L2, считываю пакеты и отправляю их в декодер. Что странно, если я попытаюсь получить входные пакеты с устройства V4L2, а не из файла, вызов декодера avcodec_send_packet будет почти в 3 раза медленнее. После дальнейшего ковыряния я сузил вопрос до того, открываю ли я вообще устройство V4L2. Вот гистограмма времени ЦП, затраченного на вызов функции avcodec_send_packet с открытием устройства и без него, даже не используя его:
Без открытия устройства V4L2:
Без открытия устройства V4L2:
Изображение

С открытием V4L2 устройство:
Изображение

Интересно, что значительное количество вызовов функций приходится на временной интервал ~25 мс! Но большинство из них занимают ~78 мс... почему?
Я добавил следующий блок кода в основную функцию примера, и все, что нужно для запуска это замедление — вызов avformat_open_input! Мне не нужно читать кадры из ввода, достаточно просто открыть их.

Код: Выделить всё

//codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);  // Replace the example MPEG1 with MJPEG

// ...

avdevice_register_all();
auto* inputFormat = av_find_input_format("v4l2");
AVDictionary* options = nullptr;
av_dict_set(&options, "input_format", "mjpeg", 0);
av_dict_set(&options, "video_size", "1920x1080", 0);
AVFormatContext* fmtCtx = nullptr;

// Commenting this line out results in fast encoding!
avformat_open_input(&fmtCtx, "/dev/video0", inputFormat, &options);

// ... do while loop to parse packets from the file and decode them ...
Так что же здесь происходит? Почему открытие устройства ухудшает мою производительность декодирования?
Кроме того, если я попытаюсь запустить, казалось бы, эквивалентный конвейер через сам инструмент ffmpeg, я не столкнусь с этой проблемой. Запуск этой команды:

Код: Выделить всё

ffmpeg -f v4l2 -input_format mjpeg -video_size 1920x1080 -r 30 -c:v mjpeg -i /dev/video0 -c:v copy out.mjpeg
Генерирует выходной файл с заявленной скоростью чуть более 1,0x, то есть. 30 кадров в секунду. Отлично, почему C API не дает мне таких же результатов? Следует отметить одну вещь: я получаю периодические ошибки от декодера MJPEG (примерно каждую секунду), но не уверен, являются ли они проблемой или нет:

Код: Выделить всё

[mjpeg @ 0x5590d6b7b0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 27 >= 27
[mjpeg @ 0x5590d6b7b0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 30 >= 30
...
Я использую Raspberry Pi CM4 с FFmpeg 6.1.1


Подробнее здесь: https://stackoverflow.com/questions/791 ... put-device
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»