Comment utiliser le filtre ffmpeg overlay_cuda pour créer une vidéo SBS?

Aug 18 2020

FFMPEG a lancé il y a quelques mois la nouvelle version de FFMPEG avec le nouveau filtre "overlay_cuda", ce filtre fait la même chose que le "overlay" mais en utilisant une carte Nvidia pour l'appliquer.

J'ai trouvé sur le site Web FFMPEG une description du filtre, mais aucun exemple de son utilisation. Les seuls exemples que j'ai trouvés proviennent des engagements du développeur, mais sont de mettre une vidéo ou une photo sur une autre vidéo.

J'ai avant le filtre de superposition normal pour le faire en utilisant une image nullsrc avec le double de la largeur, mais maintenant je ne sais pas comment faire avec ce filtre.

Description du commit: https://patchwork.ffmpeg.org/project/ffmpeg/patch/[email protected]/ Page Web de la documentation ffmpeg: https://ffmpeg.org/ffmpeg-filters.html#overlay_005fcuda-1

J'espère que vous pouvez m'aider.

Mettre à jour:

J'ai fait cette commande FFmpeg que:

  1. Entrez chaque vidéo.
  2. La première vidéo crée un remplissage vers la droite, puis est téléchargée dans la mémoire de la carte.
  3. Avec la superposition Cuda, l'autre vidéo se place à droite de la vidéo 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

Mais je reçois ce message d'erreur:

[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

J'ai des problèmes avec les formats de pixels, j'espère que vous pourrez m'aider.

Mise à jour 2:

J'ai finalement résolu le problème du format de pixel et fait maintenant la superposition avec le rembourrage (ajoute de l'espace à la vidéo de superposition)

C'est la commande qui réussit:

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

Maintenant, je veux passer x=800à une variable comme x=iw+1mais il semble que ce filtre ne le supporte pas. Existe-t-il un moyen de définir une variable globale?

Réponses

Maxtrix Aug 24 2020 at 17:37

J? ai compris! Après avoir lu à nouveau ce que je peux faire avec les filtres Cuda, j'ai constaté que scale_nppnon seulement les vidéos redimensionnaient, mais que vous pouviez également modifier le format des pixels.

Donc après quelques tests, j'ai trouvé une très bonne solution:

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'est-ce qui rend cette commande FFMPEG:

  1. Entrez deux vidéos avec le décodage Cuda.
  2. La première vidéo [0:v]:
    • Échelle à 640 pixels de largeur en conservant l'aspect radio avec un format de pixel YUV420P
    • Téléchargement de la mémoire GPU vers la mémoire système
    • Appliquez un filtre de remplissage pour ajouter une largeur de 640 pixels à droite de la vidéo
    • Télécharger à nouveau dans la mémoire du GPU
    • Changer le format de pixel en nv12
    • Étiqueter comme [base]
  3. La deuxième vidéo [1:v]
    • Escale à 640 pixels de largeur en conservant l'aspect radio avec un format de pixel NV12
    • Étiqueter comme [overlay_video]
  4. Appliquer le overlay_cudafiltre
    • [base] vidéo comme vidéo de fond
    • [overlay_video] vidéo comme vidéo de premier plan
    • Insérez [overlay_video]640 pixels à droite comme [base]vidéo
  5. Terminer l'encodage
    • -an comme Audio null (Cela peut être supprimé, dans l'utilisation réelle, vous devez mélanger les signaux audio ou en choisir une parmi les deux vidéos, ou même ajouter une source audio externe.)
    • -c:v h264_nvenc Encodez la vidéo en utilisant le GPU avec le codec h264 (ici vous pouvez changer selon vos besoins).

Le seul inconvénient est que vous devez définir une résolution à l'avance, il n'y a aucun moyen de définir la résolution d'entrée (comme dans le filtre de superposition normal). Heureusement, vous pouvez en faire une variable pour un script et l'utiliser ffprobepour obtenir cette variable avant.