Как использовать фильтр ffmpeg overlay_cuda для создания видео SBS?

Aug 18 2020

FFMPEG несколько месяцев назад запустил новую версию FFMPEG с новым фильтром «overlay_cuda», этот фильтр делает то же самое, что и «оверлей», но с использованием карты Nvidia для его применения.

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

Я перед обычным фильтром наложения делал это, используя изображение nullsrc с удвоенной шириной, но теперь я не знаю, как использовать этот фильтр.

Описание фиксации: https://patchwork.ffmpeg.org/project/ffmpeg/patch/[email protected]/ Веб-страница документации ffmpeg: https://ffmpeg.org/ffmpeg-filters.html#overlay_005fcuda-1

Я надеюсь, что вы можете мне помочь.

Обновить:

Я сделал этот заказ FFmpeg, который:

  1. Введите каждое видео.
  2. Первое видео создает отступ справа, а затем загружается в память карты.
  3. При наложении Cuda другое видео помещается справа от исходного видео.
ffmpeg -y -loglevel info \
-i $video_1 \ -hwaccel cuda -hwaccel_output_format cuda -i $video_2 \
-filter_complex \
" \
[0:v]pad=w=2*iw:h=ih:x=0:y=0,hwupload_cuda[base];
[base][1:v]overlay_cuda=x=800:y=0" \
-an -c:v h264_nvenc overlay_test.mp4

Но я получаю это сообщение об ошибке:

[overlay_cuda @ 0x55fdec4b2ec0] Can't overlay nv12 on yuv420p 
[Parsed_overlay_cuda_2 @ 0x55fdec4b2d80] Failed to configure output pad on Parsed_overlay_cuda_2
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #1:0

У меня проблемы с форматами пикселей, надеюсь, вы мне поможете.

Обновление 2:

Я наконец решил проблему с форматом пикселей и теперь делаю наложение с отступом (добавляет место наложенному видео)

Это команда, которая успешна:

ffmpeg -y -loglevel info \
-i $video_1 \ -hwaccel cuda -hwaccel_output_format cuda -i $video_2 \
-filter_complex \
" \
[0:v]pad=w=2*iw:h=ih:x=0:y=0,hwupload_cuda,scale_npp=format=nv12[base];
[base][1:v]overlay_cuda=x=800:y=0" \
-an -c:v h264_nvenc overlay_test.mp4

Теперь я хочу перейти x=800на такую ​​переменную, x=iw+1но, похоже, этот фильтр не поддерживает это. Есть ли способ установить глобальную переменную?

Ответы

Maxtrix Aug 24 2020 at 17:37

Я понял! Прочитав еще раз, что я могу делать с фильтрами Cuda, я обнаружил, что они scale_nppне только изменяют размер видео, но также вы можете изменять формат пикселей.

Итак, после нескольких тестов я нашел очень хорошее решение:

ffmpeg -y -loglevel info \
-hwaccel cuda -hwaccel_output_format cuda -i $video_1 \ -hwaccel cuda -hwaccel_output_format cuda -i $video_2 \
-filter_complex \
" \
[0:v]scale_npp=640:-2:format=yuv420p,hwdownload,pad=w=2*iw:h=ih:x=0:y=0,hwupload_cuda,scale_npp=format=nv12[base];
[1:v]scale_npp=640:-2:format=nv12[overlay_video];
[base][overlay_video]overlay_cuda=x=640:y=0" \
-an -c:v h264_nvenc overlay_test.mp4

Что делает эту команду FFMPEG:

  1. Введите два видео с декодированием Cuda.
  2. Первое видео [0:v]:
    • Увеличьте ширину до 640 пикселей, сохраняя формат изображения YUV420P пикселей
    • Скачать из памяти GPU в системную память
    • Примените фильтр Padding, чтобы добавить ширину 640 пикселей справа от видео.
    • Снова загрузить в память графического процессора
    • Измените формат пикселей на nv12
    • Отметить как [base]
  3. Второе видео [1:v]
    • Увеличьте ширину до 640 пикселей, сохраняя формат изображения в формате пикселей NV12
    • Отметить как [overlay_video]
  4. Применить overlay_cudaфильтр
    • [base] видео как фоновое видео
    • [overlay_video] видео как видео переднего плана
    • Вставьте [overlay_video]640 пикселей вправо как [base]видео
  5. Завершить кодирование
    • -an как Audio null (это можно удалить, при реальном использовании вам нужно смешать аудиосигналы или выбрать одно из двух видео или даже добавить внешний источник звука.)
    • -c:v h264_nvenc Кодируйте видео с помощью графического процессора с кодеком h264 (здесь вы можете изменить по своему усмотрению).

Единственный недостаток заключается в том, что вам нужно установить разрешение заранее, нет возможности установить входное разрешение (как в обычном фильтре наложения). К счастью, вы можете сделать это как переменную для скрипта и использовать ffprobeдля получения этой переменной раньше.