Как стать автором
Обновить

GPU-ускорение FFmpeg. Видите прибавку в скорости? И я нет. А она должна быть…

Время на прочтение10 мин
Количество просмотров11K
Всего голосов 27: ↑24 и ↓3+25
Комментарии28

Комментарии 28

хотя что-то мне подсказывает, что в этой операции FFmpeg работал в однопоточном режиме

kdenlive мне говорит, что многопоточный рендер может вызвать артефакты изображения. Не хочется рисковать.

Исходя из моего общения с друзьями операторами и монтажёрами, многие не хотят рисковать и с GPU-рендерингом, доверяя только обработке проекта на процессоре.

libx265 (не знаю как другие) любит работать на CPU во много потоков, правда ни один она при этом почему-то не занимает на 100% на длительное время. Следовательно, надо запускать несколько инстансов ffmpeg для получения реальной картины, да ещё и подбирать это кол-во для демонстрации реального выигрыша на конкретном CPU.

Спасибо за совет, в следующий раз когда буду более подробно и под другим углом проводить тесты + скорее всего с другим железом, учту это.

Ну вот, для mpeg4, внезапно, как оказалось может.
Не удивлюсь уже, если за пределами mpeg4 vs h264 и при других задачах, помимо просто рескейла/смены битрейта ещё какие-то сюрпризы вскроются.

Эммм, прошу прощения, а вы уверены что попадали в поддерживаемые картами профили энкодеров? Тут бы в документацию поглубже нырнуть, как мне кажется.

После проведения этого эксперимента, я уже ни в чём не уверен, но исходя из моего перечитывания SDK Nvidia и спецификаций использованных нами карточек, в профили мы попадали.

Прям с битрейтами, левелами, профилями, частотой кадров?

NVENC/NVDEC + рескейл легко дают 500-1000 fps на вашей задаче. Просто инструмент не тот. Возьмите Gstreamer из поставки DeepStream и убедитесь сами. Тесты, конечно, тестируют софт, но вводят в заблуждение относительно железа.

Еще я бы хотел отметить, что скейл на cpu и два трансфера RGB туда сюда через pci-e уменьшают производительность радикально. В нормальном варианте скейл тоже должен быть в gpu (deepstream).

вроде не должно быть переноса RGB туда сюда
так как указан для декодера -hwaccel_output_format_cuda
используеться scale_cuda а потом опять h264_nvenc

Ну может тогда не 2, а все 4 трансфера….

может тогда не RGB a NV12. это в 1.5 раза меньше данных :-)

Ну может и nv12, это надо ffmpeg смотреть.

Спасибо что напомнили про Gstreamer, в данном случае хотелось конкретно на примере ffmpeg поэкспериментировать, так как с ним привыкли работать.
FFmpeg ещё на удивление ведёт себя в лучшую сторону когда работаешь с его модулями по отдельности через код на плюсах, а не в консоли. Пока что правда непонятно, почему так.

Вам пы попробовать указывать nvenc/nvdec явно в качестве кодека, и nvscale в качестве скейлера - при такой комбинации, и отключении кодирования звука, потребление cpu должно быть совсем небольшим.

Да, автор явно перепутал аппаратные кодеки нвидиа с полусофтовой кудой

В первых 2/3 напутал, я про это и сам отписался. Хотя по идее mpeg4 тоже аппаратно поддерживается, но вот фильтр на рескейл определённо грузил только процессор.

ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4

Тут уж и кодек указан аппаратный, и фильтр на рескейл аппаратный, мониторинг показывал что GPU был загружен, а CPU почти простаивал. Или же этого тоже недостаточно и ещё что-то нужно было указывать в параметрах команды для большего аппаратного ускорения?

Вот так уже существенно лучше, правда в статье этого не было )
Надо ещё проверить, что кадры не передаются каждый раз из видеокарты в основную память и обратно. Например, это можно посмотреть в дебаг логах ffmpeg, там надо смотреть на pixel format в разных стадиях пайплайна обработки.

После того как я заметил что mpeg4 напутал с h264/h265 я же вроде бы так и сделал, да и мониторинг у меня отражал что CPU почти не грузился(в статью правда это уже не вошло).

ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4

Показ разницы в процентах в таких тестах просто неприемлем для нормального восприятия.

Например -300% - это как? а фраза "выполнение в 4 раза дольше" выглядит более понятно.

И оперировать следовало не ускорением, а понятием время исполнения.

Спасибо за замечание, в следующем посте по этой теме или аналогичными, буду писать словами развёрнуто, а не только процентами.

В topaz video ai то же странности с этим ffmpeg, иногда 15 ФПС, иногда 60. Недозагрузка ГПУ и цпу. Надо поэкспериментировать, может быть реально перед обработкой в топазе быстрее будет перегнать в х265, а потом уже запускать обработку.

С ffmpeg у меня странности ещё продолжились дальше, когда я решил его использовать не из под консоли, а по документации подключая его модули в программе на плюсах. Разницы в производительности я от этого не ожидал, но она снова откуда-то взялась.

Ну а ещё в исходниках ffmpeg убивает околонулевое количество комментариев.

Ты ffmpeg не правильно запускаешь, у тебя везде используется фильтр и кодек для CPU.

Для GPU другие аргументы и зависят от того, что за GPU.

Рекомендую почитать https://trac.ffmpeg.org/wiki/HWAccelIntro

cdnnowВ общем, М̶и̶х̶а̶и̶л̶, Матвей, несмотря не первый неудачный опыт, будет логично провести вторую попытку с верными вводными, мы верим - у вас получится!

Спасибо, буду стараться.)
Хотя в завершающей 1/3 от статьи, вроде наконец-то тестировал уже всё как надо.
Но в комментариях появилось много интересных предложений для нового тестирования, так что продолжению скорее всего точно быть. Плюс интересно ещё поэкспериментировать с FFmpeg не в консоли, а с подключением его отдельных библиотек в коде, под конкретные задачи.

И по стилю, скорее всего дальше будет также. Не хочется вырезать неудачные дубли и трудности, так как примеров того когда всё идёт как надо достаточно. А когда всё пошло не по плану, обычно отбраковывается и свет никогда не видит, хотя интересного и полезного, там порой не меньше.

Читал во время написания поста, перечитал опять и честно говоря так и не понял, где именно везде у меня кодек для CPU.

ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4

Кодек - hevc_nvenc использует GPU.

NVENC can be used for H.264 and HEVC encoding. FFmpeg supports NVENC through the h264_nvenc and hevc_nvenc encoders. In order to enable it in FFmpeg you need:

Фильтр - scale_cuda - использует GPU.

An example using scale_cuda and encoding in hardware, scale_cuda is available if compiled with ffnvcodec and --enable-cuda-llvm (default is on, requires nvidia llvm to be present at runtime):

Да и мониторинг через nvtop и htop, указывает на загрузку GPU, а не CPU.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий