Live-Codierung mit VP9 mit FFmpeg

Codierungsparameter

VP9 enthält eine Reihe von Parametern, um die Live-Codierung zu optimieren. Einige allgemeine Grundsätze werden in den Bitratenmodi erläutert.

FFmpeg-VP9-Codierungsbeispiel

In der folgenden Tabelle werden die Parameter eines ffmpeg-Beispielaufrufs für die VP9-Codierung beschrieben.

Parameter Beschreibung
-quality realtime realtime ist die Voraussetzung für das Livestreaming und für Geschwindigkeiten über 5.
-speed 6 Für Livestreams / Echtzeit-Codierungen sollte die Geschwindigkeit 5 bis 8 verwendet werden. Niedrigere Zahlen (5 oder 6) sind höher, benötigen aber mehr CPU-Leistung. Höhere Zahlen (7 oder 8) haben eine geringere Qualität, sind aber besser für Anwendungsfälle mit geringerer Latenz und für weniger leistungsfähige CPU-Geräte wie Mobilgeräte geeignet.
-tile-columns 4 Durch die Tiling-Funktion wird das Video in rechteckige Bereiche aufgeteilt, die für das Codieren und Decodieren Multithreading ermöglichen. Die Anzahl der Kacheln ist immer hoch zwei. 0 = 1 Kachel, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32.
-frame-parallel 1 Parallele entschlüsselbare Funktionen aktivieren
-threads 8 Maximale Anzahl der Threads.
-static-thresh 0 Grenzwert für Bewegungserkennung.
-max-intra-rate 300 Maximale i-Frame-Bitrate (pct)
-deadline realtime Alternative (alte) Version von -quality realtime
-lag-in-frames 0 Maximale Anzahl von Frames, die verzögert werden sollen
-qmin 4 -qmax 48 Mindest- und Höchstwerte für den Quantierer Die hier angegebenen Werte sind nur Vorschläge und können bei der Verbesserung der Videoqualität zulasten der Komprimierung beitragen.
-row-mt 1 Zeilen-Multithreading aktivieren. Ermöglicht die Verwendung von bis zu doppelt so vielen Threads als Kachelspalten. 0 = deaktiviert, 1 = aktiviert.
-error-resilient 1 Features für Fehlerbeständigkeit aktivieren.

Codierungsparameter auswählen

Die folgenden Informationen verwenden die Codierung mit konstanter Bitrate (CBR) für das Live-Streaming mit adaptiver Bitrate (ABR), wobei jede Zielrate explizit im Packager-Paket festgelegt wird. Dies führt zu einer saubereren Navigation zwischen Clients. Die Codierung mit variabler Bitrate (VBR) und der CQ-Modus sind ebenfalls Optionen, wenn die Bitrate flexibler sein kann oder die Codierung unterteilt wird. Der Q-Modus hat Probleme mit der Echtzeitcodierung, die für Live-Videos erforderlich ist. Weitere Informationen findest du unter Bitratenmodi.

Weitere Informationen zur Manipulation von VP9 finden Sie im zugehörigen Artikel zu VOD-Einstellungen. Berücksichtigen Sie dabei jedoch den Schwerpunkt auf der CBR.

Tipps und Tricks

Beim Livestreaming ist alles auf eine minimale Codierungsgeschwindigkeit von 1x beschränkt (FFmpeg gibt die Codierungsgeschwindigkeit beim Fortschritt an). Wenn die Codierungsgeschwindigkeit unter das 1-Fache fällt, kann die Codierung nicht mit der Eingabe des Live-Videos Schritt halten. Außerdem kommt es zu Zwischenspeicherungen und bei der Übertragung wird der Stream unbrauchbar, auch wenn das Archiv im Allgemeinen nutzbar ist.

Beispiele für Codierungsparameter in der Praxis

Nachfolgend sehen Sie die CPU-Auslastung bei 25 fps für verschiedene Frame-Größen auf einem Quad-Core-i5-Computer mit 3,6 GHz:

Zielauflösung FFmpeg VP9-Parameter CPU / Geschwindigkeit (Beispiel)
3840 × 2160 (2160p) -R 30 -g 90 -s 3840x2160 -Qualität Echtzeit -Geschwindigkeit 5 -Threads 16 -row-mt 1 -Kacheln 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0,39-fach
2560 × 1440 (1440p) -r 30 -g 90 -s 2560x1440 -Qualität Echtzeit -Geschwindigkeit 5 -Threads 16 -row-mt 1 -Kachels 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k ~86% 0,68-fach
1920 × 1080 (1080p) -R 30 -g 90 -s 1920x1080 -Qualität Echtzeit -Geschwindigkeit 5 -Threads 8 -row-mt 1 -Kacheln 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500k ~82% 1,04-fach
1280 × 720 (720p) -r 30 -g 90 -s 1280x720 - Echtzeit Echtzeit - Geschwindigkeit 5 -Threads 8 -row-mt 1 -Kacheln 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3000k ~78% 1,77-fach
854 × 480 (480p) -R 30 -g 90 -s 854 x 480 - Echtzeit Echtzeit - Geschwindigkeit 6 -Threads 4 -row-mt 1 -Kacheln 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k ~64% 3,51-fach
640 × 360 (360p) -R 30 -g 90 -s 640x360 - Echtzeit Echtzeit -Geschwindigkeit 7 -Threads 4 -row-mt 1 -Kacheln 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k ~62% 5,27-fach
426 × 240 (240p) -r 30 -g 90 -s 426x240 - Echtzeitqualität - Geschwindigkeit 8 -Threads 2 -row-mt 1 -Kacheln 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k ~66% 8,27-fach

Ein Beispiel für ein FFmpeg-Beispiel:

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 vp9 \
  -b:a 128k -c:a libopus -f webm pipe1

Tipps und Tricks

  • Hier wird eine Ausgabe an eine FIFO-Pipeline ("pipe1") ausgegeben, die vor der Ausführung des FFmpeg-Befehls erstellt werden sollte. Geben Sie dazu den Befehl mkfifo pipe1 in Ihrem Arbeitsverzeichnis an. Wenn Sie Shaka Packager verwenden, überwacht es diese Pipe als Eingabequelle für den angegebenen Stream. Für andere Verpackungsmodelle ist möglicherweise eine andere Methode erforderlich.

  • Damit -row-mt-Befehle erkannt werden, müssen Sie die neueste stabile Version von FFmpeg (derzeit 3.3.3) von https://www.ffmpeg.org/download.html verwenden.

Beispiel für eine adaptive Bitrate

Je nach Leistung der Maschine, die die FFmpeg-Codierung ausführt, können die folgenden Codierungen gleichzeitig bereitgestellt werden. Es kann also sein, dass ein Teil Ihrer Ressourcen und Zielgruppen aus der Liste ausgewählt wird.

FFMPEG-vollständiger ABR-Satz

In einem Idealfall kombinieren wir die im vorherigen Abschnitt beschriebenen Codierungsbeispiele, um einen einzigen Befehl zu erstellen, der sie alle gleichzeitig generiert:

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 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 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 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 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 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 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 vp9 -b:a 64k -c:a libopus -f webm pipe7

Die oben genannte Gruppe benötigen jedoch eine sehr leistungsstarke CPU oder ist möglicherweise mit Hardware-GPU-Auslagerungen kompatibel, wie dies bei einigen Chipsätzen zunehmend der Fall ist. Intel Kabylake (und höher) hat eine vollständige Hardware-Codierungs-Pipeline. Hinweis: Die Kabylake-GPU kann eine 8-Bit-VP9-Codierung, aber keine 10-Bit-Codierung ausführen.

Beispiel für einen Desktop-Computer mit Shaka Packager

Ein praktischeres Beispiel für gängige Computercomputer ist der Shaka Packager. Sie können Shaka ganz einfach in einem Docker-Container einrichten. Dazu verwenden Sie das DockerHub-Image von Google. Hier findest du eine Anleitung:

https://github.com/google/shaka-packager#using-reseller-for-testing-- Development

In diesem Beispiel haben wir eine Maschine mit der folgenden Konfiguration verwendet:

System Host: obs Kernel: 4.4.0-91-lowlatenz x86_64 (64-Bit)
Desktop Xfce 4.12.3 (Distro): Betriebssystem: https://googleplaystudio.org/2016/10/googleplay-studio-16-10-released/
CPU Quad-Core Intel Core i5-6500 (-MCP-)
Cache: 6144 KB
Uhrgeschwindigkeit: max. 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz
Grafikkarte Integrierte Grafik von Intel Skylake
Arbeitsspeicher 8 GB RAM

In der Praxis könnte diese Maschine optimal den folgenden nutzbaren Bereich von ABR-Codierungen erzeugen, wobei FFmpeg konsistent die 1x-Codierungsgeschwindigkeit meldet:

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 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 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 vp9 -b:a 128k -c:a libopus -f webm pipe3

Beachte, dass die Einstellungen für -speed recht hoch sind. Diese Einstellungen wurden experimentell festgelegt und variieren je nach Computer.

Shaka-Packager-Overhead

Die Verpackung ist keine besonders CPU-intensive Aktivität. Sie können dafür sorgen, dass der Shaka Packager alle Ausgaben erfasst, selbst wenn nur eine Teilmenge von FFmpeg bereitgestellt wird. Dies sind die Packager-Einstellungen, die auf dem oben beschriebenen Computer 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