FFMPEG: 2D zu 3D in Echtzeit

Teil 2 der Linux am Dienstag Mini-Serie zum Thema „2D in 3D umwandeln“ befasst sich mit FFMPEG und den verschiedenen Möglichkeiten, die sich daraus ergeben, und da gibt es einiges 😀

FFMPEG: 2D zu 3D in Echtzeit

Wer den ersten Beitrag noch nicht gelesen hat, sollte sich den vorher durchlesen, da diverse Rahmenbedingungen wie Framerate und Algorithmus auch für FFMPEG gelten, die ich aber nicht nochmal erklären werde 😉

Bino: der 3D Videoplayer

Die grundlegende Filtertechnik

Wer mit FFMPEG arbeitet weiß um die Myriaden von Dateiargumenten in der der Konsole, daher mache ich es Euch einfach: -vf stereo3d=al:arcc 

Das ist der Stereo3D-Filter den wir allen FFMPEG Tools mitgeben können, damit wir rot-cyanblaue 3D Bilder bekommen. Das Format stereo3d=in:out könnt Ihr auch ändern, je nachdem was Ihr so machen wollt. Es gibt im Netz diverse Webseiten, die da helfen können:

https://trac.ffmpeg.org/wiki/Stereoscopic
http://underpop.online.fr/f/ffmpeg/help/stereo3d.htm.gz

Der erste Link sollte eigentlich reichen um das Prinzip zu erklären. Da wir die Angaben in allen FFMPEG-Werkzeugen benutzen können, muß man den Teil also nur einmal austüfteln.

Wenn man sich einen Film in 3D ansehen möchte, kann man dafür FFPLAY benutzen:

ffplay -vf stereo3d=al:arcc film.mp4

Da hier die soweit alles auf Anhieb funktioniert, eignet es sich hervorragend für einen NEMO/Nautilus Actionmenüeintrag, also zum Abspielen auf Klick im Dateimanager 😉

Im Bild: Nemo

Um so einen Menüeintrag zu bekommen, braucht Ihr zwei Dateien:

/home/<username>.local/share/nemo/actions/play3d.nemo_action

[Nemo Action]
Name=Play 3D Video
Comment=Spiele Videos in 3D ab.

Exec=<play3d.sh %F>

Icon-Name=soundconverter

Selection=Any
Separator=;

Extensions=m4a;mp4;avi;webm;ogg;ogv;oga;wav;mkv

und /home/<username>.local/share/nemo/actions/play3d.sh

#!/bin/bash

IN=$*

IFS=";" read -ra FILES <<< "$IN"
for i in "${FILES[@]}"; do
    ffplay -vf stereo3d=al:arcc "$i" > /dev/null
done

Aber das ist natürlich nur der Anfang 😉 Kommen wir zur Abteilung „zu kalt für den Gefrierschrank“:

Zum Coolsein gehört v4l2loopback

Wer das auf seinem Rechner noch nicht drauf hat, sollte sich das v4l2loopback-Device nachinstallieren und dann kurz rebooten, damit der Kernel das korrekt verarbeiten kann. Für Fedora geht das so: dnf -y install v4l2loopback;reboot .

Wenn der PC wieder da ist, laden wir das Modul als normaler Benutzer: modprobe v4l2loopback

Ggf. dürft Ihr das auf Eurer Installation nicht, dann benutzt sudo dafür. Der Teil der jetzt kommt ist stark individuell von Eurer WebCam abhängig und wie Euer Kernel Lust hatte, mit dem V4L2 Videokram umzugehen.

Wenn meine Versionen der Befehle bei Euch nicht direkt funktionieren, dann gibt es diverse Gründe:

die Kamera kann die Auflösung nicht => eine andere Auflösung benutzen
die Kamera kann das Bildformat ( „pixfmt“ ) nicht => einfach mal „rawvideo“ angeben, das sollten alle können.
ffmpeg kann das Videogerät nicht lesen (/dev/video0: Kein passendes Gerät gefunden) => video1 benutzen

Am besten die Fehlermeldungen sorgsam lesen, ist meistens recht einfach.

… und es werde ein 3D-Bild !

ffmpeg -f video4linux2 -input_format mjpeg -video_size 1920×1080 -r 30 -i /dev/video1 -vf stereo3d=al:arcc -framerate 30 -video_size 1920×1080 -pixel_format yuvj422p -c:v:0 rawvideo -s 1920×1080 -r 30 -f v4l2 /dev/video0

ja, richtig geraten, die WebCam liefert jetzt ein 3D Bild aus, aber nur wenn Ihr Euch auch bewegt 😀 Das Bild kann von Firefox oder Chromium ( nehmt den dafür, FF zickt noch rum ) z.b. im Rahmen einer Videokonferenz oder bei Matrixcalls verwendet werden. Ihr könnt es Euch natürlich auch per WebCam-Tool wie Camorama ansehen und mit lustigen Effekten versehen, es per OBS Streamen, was auch immer Ihr wollt \o/

Ein paar Erklärungen

-f video4linux2 -input_format mjpeg -video_size 1920×1080 -r 30 -i /dev/video1

Einlesen von einer WebCam mit dem Videocodec „mjpeg“ aka MotionJPEG mit 30 FPS und in FULLHD Auflösung. Wenn man hier kein mjpeg nimmt, bekommt man i.d.R. nur Ruckelvideo mit 5 FPS, egal was man anfordert. Falls Eure Cam das nicht kann, was wie aber wohl können wird, nehmt „rawvideo“ als Codec, das geht immer. Hinweis: 5 FPS reichen für 3D nicht!

-vf stereo3d=al:arcc

Den Teil kennt Ihr ja schon von oben.

-framerate 30 -video_size 1920×1080 -pixel_format yuvj422p -c:v:0 rawvideo -s 1920×1080 -r 30 -f v4l2 /dev/video0

Mit 30 FPS (-r) in FullHD(-video_size) als Rawvideo skaliert (-s) auf FullHD als Video4Linux2 (-f) WebCam an /dev/video0 schreiben. Ja, zweimal die Auflösung drin, einfach machen, es gibt unterschiedliche FFMPEG Versionen, so klappts am Ehesten und einer ist eh die Streaminfo für den, der die Kamera benutzen will 😉

Wie, das reicht Euch noch nicht?

Hmm… na gut, es will ja nicht jeder sein Bild in die Konferenz streamen 😀

Die FFMPEG Argumente habe ich oben in 3 Teile aufgeteilt, Teil 2 ist immer gleich, aber die Teile 1 und 3 könnt Ihr austauschen, z.B. mit …

-c:v libx264 -preset fast -pix_fmt yuv420p -s 1920×1080 -strict experimental -acodec aac -ab 128000 -ar 48000 -ac 2 -vbsf h264_mp4toannexb -f mpegts „udp://127.0.0.1:10000?pkt_size=1316“

Ja ja, wieso OBS nutzen zum Streamen, FFMPEG kann das auch solo 😀

Um da einen TON zu bekommen, muß im ersten Teil „-f pulse -i default“ eingefügt werden, nach dem Videoteil, aber vor Teil 2. Das greift das PulseAudio Default Sink ab und kodiert es in die Tonspur ein.

Ganzen Desktop streamen…

ffmpeg -f x11grab -framerate 30 -video_size 1920×1080 -i :1.0 -f v4l2 /dev/video2 <- variabel

Als MP4 Film speichern …

-c:v libx264 -preset superfast -pix_fmt yuv420p -s 1920×1080 -strict experimental -acodec aac -ab 128000 -ar 48000 -ac 2 -f mp4 filmname.mp4

Da geht einiges, aber das coolste ist wohl die 3D Videokonferenz und jetzt Viel Spaß \o/

Linux am Dienstag: Programm für den 1.3.2022

Dieses mal in Linux am Dienstag, geht es um das, was man sonst nicht sehen kann und wie man damit seinen Matrix Mediastore aufräumt.

Linux am Dienstag: Programm für den 1.3.2022

Retrospektiv werfen wir noch einen Blick auf die Stereo-3D Technik von letzter Woche und schauen uns an, was man damit noch alles machen kann, außer Rick & Morty in 3D anzusehen 🙂

Unsere Themen ab 19 Uhr sind u.a. :

  • Bino – Aus 2D mach 3D
  • Sicherheit – Firmennetz von NVIDIA wurde Opfer des Ukrainekrieges
  • FFMPEG – Live 3D encoden
  • SNAP – Neue Sicherheitslücken in SNAP
  • MATRIX – Wie man mit ICat den Mediastore lichtet.

Wie jede Woche per Videokonferenz auf https://meet.cloud-foo.de/Linux .

Kleine Anmerkung: Die bisherigen Vorträge findet man jetzt unter https://linux-am-dienstag.de/archiv/ .

Linux – Schneller Videos schrumpfen

Wer wie ich Videos von Spielen captured und dadurch viel Rohmaterial in großen Bitraten liegen hat, braucht die Hilfe seiner Grafikkarte um dieses Rohmaterial möglichst schnell in handhabbare Größen umzuwandeln.

Moderne Video Hardware nutzen

Das Ausgangsmaterial ist mit 5 Mb/s erstellt worden, was den Kodiervorgang beim Bildschirmcapturen beschleunigt, zum Ansehen reichen aber 2 Mb/s VBR locker aus. Früher habe ich zum Recodieren meinen Achtkerner benutzt, was schon einmal 70% der Realzeit eines Videos benötigt hat.

Heute macht das die Nvidia Grafikkarte für mich und das mit meistens 10x Geschwindigkeit meines Achtkerners 🙂

Auslastung einer Nvidia GTX1050

Wie man auf dem Bild schön sehen kann, wird die Video Engine voll ausgenutzt. Das spiegelt sich dann in so einer FFMpegausgabe wieder:

Eine Ausgabe in der Bashshell von ffmpeg beim Nutzen von Nvidia GPUs

Faktor 18 – 23 wurden im Schnitt gesichtet, kommt halt auch drauf an, ob man Schwarzbilder oder Aktion kodiert. Wie ich schon bei meinem OpenShot Artikel geschrieben habe, hängt das Endergebnis auch stark von der Resthardware des PCs ab.

FFMpeg sorgt für den Hardwaresupport

Der Befehl „ffmpeg -hwaccels“ gibt einem die für FFMpeg verfügbaren HW-Encoder aus:

$ ffmpeg -hwaccels
ffmpeg version 4.1.4 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9 (GCC)

Hardware acceleration methods:
vdpau
cuda
vaapi
qsv
drm
opencl
qsv
cuvid

Auf Nvidia-Grafikkarten sieht der Befehl zum Kodieren dann so als Script aus:

#!/bin/bash

NAME=$(basename „$1“ .mp4)

ffmpeg -hwaccel cuvid -threads 8 -c:v h264_cuvid -i „$1“ -map 0:1 -map 0:0 -c:v:0 h264_nvenc -b:v:0 2000k -c:a:0 copy -f mp4 „/home/<username>/$NAME.mp4“

Damit wird eine VBR Rate von 2.000 Kb/s, der h264_cuvid Decoder für h264 Videos und der h264_nvenc Encoder für des Reencoden genutzt. Es beschleunigt den Vorgang nämlich sehr, wenn die Grafikkarte auch Dekodiert. Die Option „-hwaccel“ gibt den zu nutzenden Treiber an.

Anmerkung: Obiges Script kann nur einen Video- und einen Audiostream verarbeiten, Dual-Ton Tracks muß man selbst einbauen.

Verscripten geht immer…

Das Script nimmt als Argument ein mp4 Video, extrahiert den Dateinamen und erzeugt das Ausgabevideo im Homeverzeichnis ( passenden Benutzernamen einsetzen ). Ein „chmod 700 script“ gepaart mit einem „mv script ~/.local/bin/“ macht das ganze dann in der eigenen Shell leicht ausführbar.

Auch für nicht Nvidia-Grafikkarten gibt es verschiedene Codecs, die die Sache beschleunigen, wie man in obiger FFMpeg Ausgabe sehen kann. Allerdings sind Nvidia-Grafikkarten die schnellsten im Test vom Linux-Magazin gewesen, aus dem ich mir meinen optimierten Befehl hergeleitet habe.Das könnte sich bei der derzeitigen Dominanz von AMD natürlich bereits geändert haben.

Infos: https://www.linux-magazin.de/ausgaben/2017/11/ffmpeg-mit-gpus/