¿Cómo usar el filtro ffmpeg overlay_cuda para hacer un video SBS?
FFMPEG lanzó hace unos meses la nueva versión de FFMPEG con el nuevo filtro "overlay_cuda", este filtro hace lo mismo que el "overlay" pero usando una tarjeta Nvidia para aplicarlo.
Encontré la descripción del filtro en el sitio web de FFMPEG, pero no hay ejemplos de cómo usarlo. Los únicos ejemplos que encontré son los compromisos del desarrollador, pero son para poner un video o una foto sobre otro video.
Antes del filtro de superposición normal para hacer esto usando una imagen nullsrc con el doble de ancho, pero ahora no sé cómo hacerlo con este filtro.
Descripción del compromiso: https://patchwork.ffmpeg.org/project/ffmpeg/patch/[email protected]/ página web de documentación de ffmpeg: https://ffmpeg.org/ffmpeg-filters.html#overlay_005fcuda-1
Espero que puedas ayudarme.
Actualizar:
Hice esta orden FFmpeg que:
- Ingrese cada video.
- El primer video crea un relleno a la derecha y luego se carga en la memoria de la tarjeta.
- Con superposición de Cuda, el otro video se coloca a la derecha del video original.
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
Pero recibo este mensaje de error:
[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
Tengo problemas con los formatos de píxeles, espero que puedan ayudarme.
Actualización 2:
Finalmente resolví el problema del formato de píxeles y ahora hago la superposición con el relleno (agrega espacio al video de superposición)
Este es el comando que tiene éxito:
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
Ahora quiero cambiar x=800
a una variable como, x=iw+1
pero parece que este filtro no lo admite. ¿Hay alguna forma de establecer una variable global?
Respuestas
¡Lo tengo! Después de leer nuevamente lo que puedo hacer con los filtros Cuda, descubrí que scale_npp
no solo cambia el tamaño de los videos, sino que también puedes cambiar el formato de píxeles.
Entonces, después de algunas pruebas, encontré una solución muy agradable:
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
Qué hace este comando FFMPEG:
- Ingrese dos videos con decodificación Cuda.
- El primer video
[0:v]
:- Escale a 640 píxeles de ancho manteniendo la radio de aspecto con un formato de píxeles YUV420P
- Descarga de la memoria de la GPU a la memoria del sistema
- Aplicar un filtro de relleno para agregar 640 píxeles de ancho a la derecha del video
- Subir nuevamente a la memoria de la GPU
- Cambiar el formato de píxel a nv12
- Etiquetar como
[base]
- El segundo video
[1:v]
- Escale a 640 píxeles de ancho manteniendo la radio de aspecto con un formato de píxeles NV12
- Etiquetar como
[overlay_video]
- Aplicar
overlay_cuda
filtro[base]
video como video de fondo[overlay_video]
video como el video de primer plano- Inserte
[overlay_video]
640 píxeles a la derecha como el[base]
video
- Termina la codificación
-an
como Audio nulo (Esto se puede eliminar, en el uso real, debe mezclar las señales de audio o elegir uno de los dos videos, o incluso agregar una fuente de audio externa).-c:v h264_nvenc
Codifique el video usando la GPU con el códec h264 (aquí puede cambiar según sus necesidades).
El único inconveniente es que necesita establecer una resolución de antemano, no hay forma de establecer la resolución de entrada (como en el filtro de superposición normal). Afortunadamente, puede hacer esto como una variable para un script y usarlo ffprobe
para obtener esta variable antes.