Come utilizzare il filtro ffmpeg overlay_cuda per realizzare un video SBS?
FFMPEG qualche mese fa ha lanciato la nuova versione di FFMPEG con il nuovo filtro "overlay_cuda", questo filtro è lo stesso dell '"overlay" ma utilizza una scheda Nvidia per applicarlo.
Ho trovato sul sito web FFMPEG la descrizione del filtro, ma nessun esempio su come usarlo. Gli unici esempi che ho trovato provengono dai commit dello sviluppatore, ma sono mettere un video o una foto su un altro video.
Prima del normale filtro di sovrapposizione per farlo usando un'immagine nullsrc con il doppio della larghezza, ma ora non so come farlo con questo filtro.
Descrizione commit: https://patchwork.ffmpeg.org/project/ffmpeg/patch/[email protected]/ pagina web della documentazione ffmpeg: https://ffmpeg.org/ffmpeg-filters.html#overlay_005fcuda-1
Spero che puoi aiutarmi.
Aggiornare:
Ho fatto questo ordine FFmpeg che:
- Inserisci ogni video.
- Il primo video crea un riempimento a destra e quindi viene caricato nella memoria della scheda.
- Con l'overlay Cuda, l'altro video si trova a destra del video originale.
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
Ma ricevo questo messaggio di errore:
[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
Ho problemi con i formati pixel, spero che tu possa aiutarmi.
Aggiornamento 2:
Ho finalmente risolto il problema del formato pixel e ora crea l'overlay con il padding (aggiunge spazio al video overlay)
Questo è il comando che riesce:
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
Ora voglio passare x=800
a una variabile come x=iw+1
ma sembra che questo filtro non lo supporti. C'è un modo per impostare una variabile globale?
Risposte
Capito! Dopo aver letto di nuovo cosa posso fare con i filtri Cuda, ho scoperto che scale_npp
non solo ridimensiona i video, ma puoi anche cambiare il formato dei pixel.
Quindi dopo alcuni test ho trovato una soluzione molto carina:
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
Cosa rende questo comando FFMPEG:
- Inserisci due video con la decodifica Cuda.
- Il primo video
[0:v]
:- Scala a 640 pixel di larghezza mantenendo l'aspetto radio con un formato pixel YUV420P
- Scarica dalla memoria GPU alla memoria di sistema
- Applicare un filtro Padding per aggiungere una larghezza di 640 pixel a destra del video
- Carica di nuovo nella memoria della GPU
- Cambia il formato dei pixel in nv12
- Etichetta come
[base]
- Il secondo video
[1:v]
- Scala fino a 640 pixel di larghezza mantenendo l'aspetto radio con un formato pixel NV12
- Etichetta come
[overlay_video]
- Applica
overlay_cuda
filtro[base]
video come video di sfondo[overlay_video]
video come video in primo piano- Inserisci
[overlay_video]
640 pixel a destra come il[base]
video
- Termina la codifica
-an
come Audio null (questo può essere cancellato, nell'uso reale è necessario mescolare i segnali audio o sceglierne uno dai due video, o anche aggiungere una sorgente audio esterna.)-c:v h264_nvenc
Codifica il video utilizzando la GPU con il codec h264 (qui puoi modificare in base alle tue esigenze).
L'unico inconveniente è che è necessario impostare una risoluzione in anticipo, non c'è modo di impostare la risoluzione di ingresso (come nel normale filtro di sovrapposizione). Fortunatamente, puoi renderlo come una variabile per uno script e usarlo ffprobe
per ottenere questa variabile prima.