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