Live-Codierung mit VP9 mit FFmpeg
Codierungsparameter
VP9 bietet eine Reihe von Parametern zur Optimierung der Live-Codierung. Einige allgemeine Grundsätze werden unter Bitratenmodi beschrieben.
FFmpeg-Beispiel für die VP9-Codierung
In der folgenden Tabelle werden die Parameter eines Beispielaufrufs von ffmpeg
für die VP9-Codierung beschrieben.
Parameter | Beschreibung |
---|---|
-quality realtime |
realtime ist für Livestreams und Geschwindigkeiten über 5 erforderlich. |
-speed 6 |
Die Geschwindigkeit 5 bis 8 sollte für die Live- bzw. Echtzeitcodierung verwendet werden. Niedrigere Zahlen (5 oder 6 ) stehen für eine höhere Qualität, erfordern aber mehr CPU-Leistung. Höhere Zahlen (7 oder 8 ) führen zu einer geringeren Qualität, sind aber für Anwendungsfälle mit niedriger Latenz und für Geräte mit geringerer CPU-Leistung wie Mobilgeräte besser geeignet. |
-tile-columns 4 |
Beim Tiling wird das Video in rechteckige Bereiche aufgeteilt, was die Verwendung von Multithreading für die Codierung und Decodierung ermöglicht. Die Anzahl der Kacheln ist immer eine Zweierpotenz. 0 = 1 Kachel, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32. |
-frame-parallel 1 |
Funktionen für parallele Decodierbarkeit aktivieren. |
-threads 8 |
Maximale Anzahl der zu verwendenden Threads. |
-static-thresh 0 |
Grenzwert für die Bewegungserkennung. |
-max-intra-rate 300 |
Maximale Bitrate für I-Frames (in Prozent) |
-deadline realtime |
Alternative (alte) Version von -quality realtime |
-lag-in-frames 0 |
Maximale Anzahl der Frames, die verzögert werden sollen |
-qmin 4 -qmax 48 |
Mindest- und Höchstwerte für den Quantisierer. Die Werte hier sind nur ein Vorschlag. Wenn Sie sie anpassen, wird die Videoqualität erhöht oder verringert, was sich auf die Komprimierungseffizienz auswirkt. |
-row-mt 1 |
Aktivieren Sie das Row-Multithreading. Ermöglicht die Verwendung von bis zu zwei Threads als Kachelspalten. 0 = aus, 1 = an. |
-error-resilient 1 |
Aktivieren Sie Funktionen zur Fehlerbehebung. |
Codierungsparameter auswählen
Die folgenden Informationen beziehen sich auf das Encoding mit konstanter Bitrate (CBR) für das adaptive Bitrate-Streaming (ABR) von Livestreams, bei dem jede Zielrate explizit im Manifest des Packagers festgelegt wird. Dadurch wird das „Wechseln“ zwischen Raten für Kunden vereinfacht. Die Codierung mit variabler Bitrate (VBR) und der CQ-Modus sind ebenfalls Optionen, wenn die Bitrate flexibler sein kann oder die Codierung in Chunks erfolgt. Der Q-Modus ist für die Echtzeitcodierung, die für Live-Videos erforderlich ist, nicht geeignet. Weitere Informationen finden Sie unter Bitratenmodi.
Weitere Informationen zur Bearbeitung von VP9 finden Sie auch im zugehörigen Artikel zu VOD-Einstellungen. Hier wird jedoch der Fokus auf CBR gelegt.
Tipps und Tricks
Beim Livestreaming muss die Mindestcodierungsgeschwindigkeit in Echtzeit 1x betragen (FFmpeg gibt die Codierungsgeschwindigkeit im Laufe des Prozesses an). Wenn die Codierungsgeschwindigkeit unter 1x sinkt, kann der Codierungsprozess nicht mit der Eingabe von Live-Video mithalten. Nutzer sehen dann Pufferungen und Unterbrechungen in der Übertragung, die den Stream während der Liveübertragung unbrauchbar machen (obwohl das Archiv im Allgemeinen nutzbar ist).
Beispiele für die Verwendung von Codierungsparametern
Im Folgenden sehen Sie die CPU-Auslastung bei 25 fps für verschiedene Frame-Größen auf einem Quad-Core-i5-Desktop mit 3,6 GHz unter Linux:
Zielauflösung | FFmpeg-VP9-Parameter | CPU / Geschwindigkeit (Beispiel) |
---|---|---|
3.840 × 2.160 (2.160p) | -r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k | ~88% 0,39-fach |
2560 × 1440 (1440p) | -r 30 -g 90 -s 2560x1440 -quality realtime -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k | ~86% 0,68-Fach |
1920 × 1080 (1080p) | -r 30 -g 90 -s 1920x1080 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500k | ~82% 1.04x |
1280 × 720 (720p) | -r 30 -g 90 -s 1280x720 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3000k | ~78% 1,77-fach |
854 × 480 (480p) | -r 30 -g 90 -s 854x480 -quality realtime -speed 6 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k | ~64% 3,51‑fach |
640 × 360 (360p) | -r 30 -g 90 -s 640x360 -quality realtime -speed 7 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k | ~62% 5,27-fach |
426 × 240 (240p) | -r 30 -g 90 -s 426x240 -quality realtime -speed 8 -threads 2 -row-mt 1 -tile-columns 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k | ~66% 8.27x |
Ein Beispiel für FFmpeg könnte so aussehen:
ffmpeg -stream_loop 100 -i /home/id3as/Videos/120s_tears_of_steel_1080p.webm \
-r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 \
-tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k -c:v libvpx-vp9 \
-b:a 128k -c:a libopus -f webm pipe1
Tipps und Tricks
Hier wird die Ausgabe in eine FIFO-Pipe („pipe1“) geschrieben, die vor der Ausführung des FFmpeg-Befehls erstellt werden muss. Geben Sie dazu den Befehl
mkfifo pipe1
in Ihrem Arbeitsverzeichnis ein. Wenn Sie Shaka Packager verwenden, wird dieser Pipe als Eingabequelle für den angegebenen Stream gelauscht. Für andere Verpackungsmodelle ist möglicherweise eine andere Methode erforderlich.Damit
-row-mt
-Befehle erkannt werden, verwenden Sie die aktuelle stabile Version von FFmpeg (derzeit 3.3.3) von https://www.ffmpeg.org/download.html.
Beispiel für einen adaptiven Bitrate-Satz
Je nach Leistung des Computers, auf dem die FFmpeg-Codierung ausgeführt wird, ist es möglicherweise nicht möglich, alle folgenden Codierungen gleichzeitig bereitzustellen. Daher sollte aus der Liste eine Teilmenge ausgewählt werden, die den verfügbaren Ressourcen und Zielgruppen entspricht.
Vollständiges ABR-Set für FFmpeg
Im Idealfall kombinieren wir die im vorherigen Abschnitt beschriebenen Codierungsbeispiele, um einen einzelnen Befehl zu erstellen, mit dem alle gleichzeitig erzeugt werden:
ffmpeg -stream_loop 100 -i lakes1080p.mp4 \
-y -r 25 -g 75 -s 3840x2160 -quality realtime -speed 5 -threads 8 \
-tile-columns 2 -frame-parallel 1 \
-b:v 7800k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe1 \
-y -r 25 -g 75 -s 2560x1440 -quality realtime -speed 5 -threads 8 \
-tile-columns 2 -frame-parallel 1 \
-b:v 6000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe2 \
-y -r 25 -g 75 -s 1920x1080 -quality realtime -speed 5 -threads 4 \
-tile-columns 2 -frame-parallel 1 \
-b:v 4500k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe3 \
-y -r 25 -g 75 -s 1280x720 -quality realtime -speed 5 -threads 4 \
-tile-columns 2 -frame-parallel 1 \
-b:v 3000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe4 \
-y -r 25 -g 75 -s 854x480 -quality realtime -speed 6 -threads 4 \
-tile-columns 2 -frame-parallel 1 \
-b:v 2000k -c:v libvpx-vp9 -b:a 196k -c:a libopus -f webm pipe5 \
-y -r 25 -g 75 -s 640x360 -quality realtime -speed 7 -threads 2 \
-tile-columns 1 -frame-parallel 0 \
-b:v 730k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe6 \
-y -r 25 -g 75 -s 426x240 -quality realtime -speed 8 -threads 2 \
-tile-columns 1 -frame-parallel 0 \
-b:v 365k -c:v libvpx-vp9 -b:a 64k -c:a libopus -f webm pipe7
Für den oben genannten vollständigen Satz ist jedoch eine sehr leistungsstarke CPU oder möglicherweise die Unterstützung durch Hardware-GPU-Offload erforderlich, wie sie von einigen Chipsätzen zunehmend bereitgestellt wird. Intel Kabylake (und höher) verfügt über eine vollständige Hardware-Codierungspipeline. Die Kabylake-GPU kann 8-Bit-VP9-Codierung, aber keine 10-Bit-Codierung durchführen.
Praxisbeispiel für Computer mit Shaka Packager
Ein praktischeres Beispiel für gängige Desktopcomputer könnte Shaka Packager verwenden. Eine einfache Möglichkeit, Shaka einzurichten, ist die Installation in einem Docker-Container mit dem DockerHub-Image von Google. Eine Anleitung dazu finden Sie hier:
https://github.com/google/shaka-packager#using-docker-for-testing--development
Für dieses Beispiel haben wir einen Computer mit der folgenden Konfiguration verwendet:
System | Host: obs Kernel: 4.4.0-91-lowlatency x86_64 (64 Bit) |
Computer | Xfce 4.12.3 – Distribution: Betriebssystem: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/ |
CPU | Quad-Core Intel Core i5-6500 (-MCP-) Cache: 6144 KB Taktfrequenzen: max.: 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz |
Grafikkarte | Integrierte Intel Skylake-Grafik |
Arbeitsspeicher | 8 GB RAM |
In der Praxis könnte diese Maschine optimal den folgenden nutzbaren Bereich von ABR-Codierungen mit einer von FFmpeg durchgehend gemeldeten Codierungsgeschwindigkeit von 1x erzeugen:
ffmpeg -stream_loop 100 -i 120s_tears_of_steel_1080p.webm \
-y -r 30 -g 90 -s 1920x1080 -quality realtime -speed 7 -threads 8 \
-row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
-b:v 4500k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe1 \
-y -r 30 -g 90 -s 1280x720 -quality realtime -speed 8 -threads 6 \
-row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
-b:v 3000k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe2 \
-y -r 30 -g 90 -s 640x360 -quality realtime -speed 8 -threads 2 \
-row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 \
-b:v 730k -c:v libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe3
Beachten Sie, dass die -speed
-Einstellungen recht hoch sind. Diese Einstellungen wurden experimentell ermittelt und variieren von Maschine zu Maschine.
Shaka Packager-Overhead
Das Verpacken ist keine besonders CPU-intensive Aktivität. Shaka Packager kann so eingestellt werden, dass alle Ausgaben überwacht werden, auch wenn nur eine Teilmenge von FFmpeg bereitgestellt wird. Dies sind die Packager-Einstellungen, die auf der oben beschriebenen Maschine getestet wurden:
packager \
in=pipe1,stream=audio,init_segment=livehd-audio-1080.webm,segment_template=livehd-audio-1080-\$Number\$.webm \
in=pipe1,stream=video,init_segment=livehd-video-1080.webm,template=livehd-video-1080-\$Number\$.webm \
in=pipe2,stream=audio,init_segment=livehd-audio-720.webm,segment_template=livehd-audio-720-\$Number\$.webm \
in=pipe2,stream=video,init_segment=livehd-video-720.webm,template=livehd-video-720-\$Number\$.webm \
in=pipe3,stream=audio,init_segment=livehd-audio-360.webm,segment_template=livehd-audio-360-\$Number\$.webm \
in=pipe3,stream=video,init_segment=livehd-video-360.webm,template=livehd-video-360-\$Number\$.webm \
--mpd_output livehd.mpd --dump_stream_info --min_buffer_time=10 --time_shift_buffer_depth=300 \
--segment_duration=3 --io_block_size 65536