Codifica in tempo reale con VP9 tramite FFmpeg

Parametri di codifica

VP9 fornisce una serie di parametri per ottimizzare la codifica in tempo reale. Alcuni principi generali sono descritti in Modalità velocità di bit.

Esempio di codifica FFmpeg VP9

La tabella seguente descrive i parametri di una chiamata di esempio ffmpeg per la codifica VP9.

Parametro Descrizione
-quality realtime realtime è essenziale per il live streaming e le velocità superiori a 5.
-speed 6 La velocità compresa tra 5 e 8 deve essere utilizzata per la codifica in tempo reale e in tempo reale. I numeri più bassi (5 o 6) sono di qualità superiore, ma richiedono una maggiore CPU. Numeri più elevati (7 o 8) avranno una qualità inferiore, ma sono più gestibili per casi d'uso con minore latenza e per dispositivi di potenza CPU inferiore, come i dispositivi mobili.
-tile-columns 4 Il tiling suddivide il video in aree rettangolari, il che consente il multi-thread per codifica e decodifica. Il numero di riquadri è sempre una potenza di due. 0 = 1 riquadro, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32.
-frame-parallel 1 Abilita le funzionalità di decodifica parallela.
-threads 8 Numero massimo di thread da utilizzare.
-static-thresh 0 Soglia di rilevamento dei movimenti.
-max-intra-rate 300 Velocità in bit massima i-frame (pct)
-deadline realtime Versione alternativa (legacy) di -quality realtime
-lag-in-frames 0 Numero massimo di frame da ritardare
-qmin 4 -qmax 48 Valori minimi e massimi per il quantificatore. I valori in questa sezione sono semplicemente un suggerimento. La modifica di questa impostazione aiuterà ad aumentare o ridurre la qualità video a scapito dell'efficienza della compressione.
-row-mt 1 Abilita il multi-threading. Consente di utilizzare fino al doppio di thread come colonne riquadro. 0 = disattivata, 1 = attiva.
-error-resilient 1 Abilita le funzionalità di resilienza errori.

Scelta dei parametri di codifica

Le informazioni che seguono utilizzano la codifica a velocità in bit (CBR) costante per il flusso di bit adattivo in tempo reale, dove ogni frequenza target è impostata in modo esplicito nel manifest del packer. In questo modo, sarà possibile passare da una tariffa all'altra per i clienti. Le opzioni Codifica velocità in bit (VBR) e Modalità CQ sono disponibili anche se la velocità in bit può essere più flessibile o se la codifica viene modificata. La modalità Q ha difficoltà con la codifica in tempo reale richiesta per il video in diretta. Per ulteriori informazioni, consulta la sezione Modalità velocità in bit.

Per ulteriori dettagli su come manipolare VP9, vale la pena fare riferimento anche all'articolo associato nelle impostazioni VOD, ma tenendo conto di un approccio incentrato sulla CBR.

Suggerimenti utili

Ricorda che, durante il live streaming, tutto è vincolato a una velocità di codifica minima di 1 volte (FFmpeg, che indica la velocità di codifica man mano che avanza). Se la velocità di codifica scende al di sotto di 1 volte, il processo di codifica non mantiene l'input del video in diretta e gli utenti riscontrano un buffering, mentre le interruzioni della trasmissione rendono il flusso inutilizzabile durante la trasmissione dal vivo (sebbene l'archivio sia generalmente utilizzabile).

Esempi di parametri di codifica in azione

Di seguito è riportato l'utilizzo della CPU a 25 fps per varie dimensioni di frame su un desktop quad-core i5 a 3,6 GHz, con Linux:

Obiettivo di risoluzione Parametri FFmpeg VP9 CPU / velocità (esempio)
3840x2160 (2160p) -r 30 -g 90 -s 3840 x 2160 -qualità in tempo reale -velocità 5 -thread 16 -riga-mt 1 -colonne-piastrelle 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0,39x
2560x1440 (1440p) -r 30 -g 90 -s 2560 x 1440 -qualità in tempo reale -velocità 5 -thread 16 -riga-mt 1 -colonne-piastrelle 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k ~86% 0,68x
1920x1080 (1080p) -r 30 -g 90 -s 1920 x 1080 -qualità in tempo reale -velocità 5 -thread 8 -riga-mt 1 -colonne-piastrelle 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500k ~82% 1,04x
1280x720 (720p) -r 30 -g 90 -s 1280 x 720 -qualità in tempo reale -velocità 5 -thread 8 -riga-mt 1 -colonne-piastrelle 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3000k ~78% 1,77x
854x480 (480p) -r 30 -g 90 -s 854x480 -qualità in tempo reale -velocità 6 -thread 4 -riga-mt 1 -colonne-piastrelle 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k ~64% 3,51x
640x360 (360p) -r 30 -g 90 -s 640x360 -qualità in tempo reale -velocità 7 -thread 4 -riga-mt 1 -colonne-piastrelle 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k ~62% 5,27x
426x240 (240p) -r 30 -g 90 -s 426x240 -qualità in tempo reale -velocità 8 -thread 2 -riga-mt 1 -colonne-piastrelle 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k ~66% 8,27x

Un esempio di file FFmpeg potrebbe avere il seguente aspetto:

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

Suggerimenti utili

  • Tieni presente che qui stiamo eseguendo un output di una pipeline FIFO ("pipe1"), che dovrebbe essere creata prima dell'esecuzione, prima di eseguire il comando FFmpeg. Per farlo, assegna il comando mkfifo pipe1 alla directory di lavoro. Durante l'utilizzo di Shaka Packager, il podcast verrà ascoltato come sorgente di input per lo stream specificato. Altri modelli di confezione potrebbero richiedere un metodo diverso.

  • Per assicurarti che i comandi -row-mt vengano riconosciuti, utilizza l'ultima release stabile di FFmpeg (3.3.3 attualmente) da https://www.ffmpeg.org/download.html

Esempio di velocità in bit adattiva

A seconda della potenza della macchina che esegue la codifica FFmpeg, potrebbe o meno essere in grado di fornire tutte le codifiche seguenti contemporaneamente, quindi un sottoinsieme adatto alle tue risorse e ai tuoi segmenti di pubblico di destinazione disponibili deve essere selezionato dall'elenco.

Set ABR completo FFmpeg

In uno scenario ideale, combiniamo gli esempi di codifica descritti nella sezione precedente per creare un singolo comando che li produce tutti contemporaneamente:

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

Il set completo riportato sopra, tuttavia, richiede una CPU molto potente o magari il supporto per l'offload della GPU dell'hardware, come alcuni chipset sempre più forniti. Intel Kabylake (e oltre) ha una pipeline di codifica hardware completa. Tieni presente che la GPU Kabylake può eseguire la codifica VP9 a 8 bit, ma non a 10 bit.

Un esempio pratico di desktop che usa Shaka Packager

Un esempio più pratico per le macchine desktop comuni potrebbe essere Shaka Packager. Un modo semplice per configurare Shaka è installarlo all'interno di un container Docker, utilizzando l'immagine DockerHub di Google. Puoi trovare le istruzioni qui:

https://github.com/google/shaka-packager#using-docker-for-testing--development

Per questo esempio abbiamo utilizzato una macchina con la seguente configurazione:

Sistema Host: obs Kernel: 4.4.0-91-lowlatency x86_64 (64 bit)
Desktop Xfce 4.12.3 Distro: Sistema operativo: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
CPU Intel Core i5-6500 quad-core
(-MCP)
cache: 6144 kB
velocità di orologio: max: 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz
Scheda grafica Scheda grafica integrata Intel Skylake
Memoria 8 GB di RAM

In pratica, questa macchina potrebbe produrre in modo ottimale il seguente intervallo utilizzabile di codifiche ABR, con FFmpeg che registra costantemente la velocità di codifica 1x:

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

Tieni presente che le impostazioni di -speed sono piuttosto alte. Queste impostazioni sono state stabilite in modo sperimentale e varieranno in base alla macchina.

Lavagna pacchettistica Shaka

La pacchettizzazione non è un'attività particolarmente intensa della CPU. Shaka Packager può essere impostato per ascoltare tutti gli output, anche se solo un sottoinsieme viene fornito da FFmpeg. Queste sono le impostazioni del packager testate sul computer descritto sopra:

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