Как использовать фильтр ffmpeg overlay_cuda для создания видео SBS?
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, который:
- Введите каждое видео.
- Первое видео создает отступ справа, а затем загружается в память карты.
- При наложении 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
но, похоже, этот фильтр не поддерживает это. Есть ли способ установить глобальную переменную?
Ответы
Я понял! Прочитав еще раз, что я могу делать с фильтрами 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:
- Введите два видео с декодированием Cuda.
- Первое видео
[0:v]
:- Увеличьте ширину до 640 пикселей, сохраняя формат изображения YUV420P пикселей
- Скачать из памяти GPU в системную память
- Примените фильтр Padding, чтобы добавить ширину 640 пикселей справа от видео.
- Снова загрузить в память графического процессора
- Измените формат пикселей на nv12
- Отметить как
[base]
- Второе видео
[1:v]
- Увеличьте ширину до 640 пикселей, сохраняя формат изображения в формате пикселей NV12
- Отметить как
[overlay_video]
- Применить
overlay_cuda
фильтр[base]
видео как фоновое видео[overlay_video]
видео как видео переднего плана- Вставьте
[overlay_video]
640 пикселей вправо как[base]
видео
- Завершить кодирование
-an
как Audio null (это можно удалить, при реальном использовании вам нужно смешать аудиосигналы или выбрать одно из двух видео или даже добавить внешний источник звука.)-c:v h264_nvenc
Кодируйте видео с помощью графического процессора с кодеком h264 (здесь вы можете изменить по своему усмотрению).
Единственный недостаток заключается в том, что вам нужно установить разрешение заранее, нет возможности установить входное разрешение (как в обычном фильтре наложения). К счастью, вы можете сделать это как переменную для скрипта и использовать ffprobe
для получения этой переменной раньше.