Что FFmpeg делает с avcodec_send_packet ()? - PullRequest
2 голосов
/ 15 марта 2019

Я пытаюсь оптимизировать часть программного обеспечения для воспроизведения видео, которая внутренне использует библиотеки FFmpeg для декодирования. Мы обнаружили, что на некоторых больших видео (4K, 60fps) декодирование кадра иногда занимает больше времени, чем этот кадр должен отображаться; к сожалению, из-за проблемной области просто буферизация / пропуск кадров не возможен.

Однако, похоже, что исполняемый файл FFmpeg способен нормально декодировать видео, примерно в 2 раза быстрее, поэтому я пытался понять, что мы делаем неправильно.

Я написал очень урезанную программу декодирования для тестирования; источник здесь (это около 200 строк). Из его профилирования видно, что одним из основных узких мест при декодировании является функция avcodec_send_packet(), которая может занять до 50 мс на вызов. Однако измерение одного и того же вызова в FFmpeg показывает странное поведение:

Yes, you can embed images

(это время, затрачиваемое на каждый вызов avcodec_send_packet () в миллисекундах при декодировании видео с кодированием VP9 4K 25fps.)

По сути, кажется, что когда FFmpeg использует эту функцию, для выполнения каждого из N вызовов требуется лишь какое-то время, где N - количество потоков, используемых для декодирования. Однако и мой тестовый декодер, и сам продукт используют 4 потока для декодирования, и этого не происходит; при использовании потоковой передачи на основе кадров тестовый декодер ведет себя как FFmpeg, используя только 1 поток. Похоже, это указывает на то, что мы вообще не используем многопоточность, но мы все еще видим улучшение производительности за счет использования большего количества потоков.

Результаты FFmpeg в среднем примерно вдвое быстрее, чем у наших декодеров, поэтому очевидно, что мы делаем что-то не так. Я читал источник в FFmpeg, чтобы попытаться найти какие-либо подсказки, но до сих пор это ускользало от меня.

У меня такой вопрос: что FFmpeg делает здесь, а мы нет? Как же мы можем повысить производительность нашего декодера?

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 18 марта 2019

avcodec_send_packet() и avcodec_receive_frame() являются функциями-обертками. Самое важное, что они делают, это вызывает функцию декодирования выбранного кодека и возвращает декодированный кадр (или ошибку).

Попробуйте настроить параметры кодека, например, низкая задержка может не дать вам того, что вы хотите. И иногда старый API (я думаю, что он все еще существует) avcodec_decode_video2() превосходит более новый, вы можете попробовать это тоже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...