Codifica live con VP9 utilizzando FFmpeg
Parametri di codifica
VP9 fornisce una serie di parametri per ottimizzare la codifica live. Alcuni principi generali sono descritti in Modalità bitrate.
Esempio di codifica VP9 FFmpeg
La tabella seguente descrive i parametri di una chiamata ffmpeg
di esempio per la codifica VP9.
Parametro | Descrizione |
---|---|
-quality realtime |
realtime è essenziale per il live streaming e per velocità superiori a 5 . |
-speed 6 |
La velocità 5 - 8 deve essere utilizzata per la codifica live / in tempo reale. I numeri più bassi (5 o 6 ) indicano una qualità superiore, ma richiedono più potenza della CPU. I numeri più alti (7 o 8 ) avranno una qualità inferiore, ma saranno più gestibili per i casi d'uso con latenza inferiore e anche per i dispositivi con potenza della CPU inferiore, come i dispositivi mobili. |
-tile-columns 4 |
La suddivisione in riquadri divide il video in regioni rettangolari, il che consente il multithreading per la codifica e la decodifica. Il numero di tessere è sempre una potenza di due. 0 = 1 riquadro, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32. |
-frame-parallel 1 |
Attiva 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 (%) |
-deadline realtime |
Versione alternativa (legacy) di -quality realtime |
-lag-in-frames 0 |
Numero massimo di frame da ritardare |
-qmin 4 -qmax 48 |
Valori minimo e massimo per il quantizzatore. I valori qui riportati sono solo un suggerimento e la loro modifica contribuirà ad aumentare/diminuire la qualità del video a scapito dell'efficienza della compressione. |
-row-mt 1 |
Abilita il multithreading a livello di riga. Consente l'utilizzo di un massimo di due thread come colonne dei riquadri. 0 = off, 1 = on. |
-error-resilient 1 |
Attiva le funzionalità di resilienza agli errori. |
Scelta dei parametri di codifica
Le informazioni riportate di seguito utilizzano la codifica a velocità in bit costante (CBR) per lo streaming a velocità in bit adattiva (ABR) live, in cui ogni velocità target è impostata in modo esplicito nel manifest del packager. In questo modo, i clienti potranno passare più facilmente da una tariffa all'altra. La codifica a velocità in bit variabile (VBR) e la modalità CQ sono altre opzioni se la velocità in bit può essere più flessibile o se la codifica viene suddivisa in blocchi. La modalità Q avrà difficoltà con la codifica in tempo reale richiesta per i video live. Per ulteriori informazioni, consulta la sezione Modalità di bitrate.
Per ulteriori dettagli su come manipolare VP9, ti consigliamo di consultare anche l'articolo di accompagnamento sulle impostazioni VOD, tenendo conto di un focus su CBR.
Suggerimenti utili
Tieni presente che, durante il live streaming, tutto è vincolato a una velocità di codifica in tempo reale minima di 1x (FFmpeg segnala la velocità di codifica man mano che procede). Se la velocità di codifica scende al di sotto di 1x, il processo di codifica non riuscirà a tenere il passo con l'input del video live e gli utenti riscontreranno buffering e interruzioni nella trasmissione, il che renderà inutilizzabile lo stream durante la trasmissione live (anche se l'archivio sarà generalmente utilizzabile).
Esempi di parametri di codifica in azione
Di seguito è riportato l'utilizzo della CPU a 25 fps per varie dimensioni dei frame su un computer desktop quad-core i5 da 3,6 GHz con Linux:
Risoluzione target | Parametri FFmpeg VP9 | CPU / Velocità (esempio) |
---|---|---|
3840x2160 (2160p) | -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,39x |
2560x1440 (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.68x |
1920x1080 (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 |
1280x720 (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,77x |
854x480 (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,51x |
640x360 (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,27x |
426x240 (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 |
Un esempio di 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 libvpx-vp9 \
-b:a 128k -c:a libopus -f webm pipe1
Suggerimenti utili
Tieni presente che qui l'output viene inviato a una pipe FIFO ("pipe1"), che deve essere creata prima dell'esecuzione, prima di eseguire il comando FFmpeg. Per farlo, dai il comando
mkfifo pipe1
nella tua directory di lavoro. Quando utilizzi Shaka Packager, ascolterà questa pipe come sorgente di input per lo stream specificato. Altri modelli di imballaggio potrebbero richiedere un metodo diverso.Per assicurarti che i comandi
-row-mt
vengano riconosciuti, utilizza l'ultima release stabile di FFmpeg (attualmente la 3.3.3) disponibile all'indirizzo https://www.ffmpeg.org/download.html
Esempio di set di velocità in bit adattiva
A seconda della potenza della macchina che esegue la codifica FFmpeg, potrebbe non essere possibile fornire tutte le codifiche seguenti contemporaneamente, pertanto è necessario selezionare dall'elenco un sottoinsieme adatto alle risorse disponibili e ai segmenti di pubblico di destinazione.
Set ABR completo di FFmpeg
In uno scenario ideale, combiniamo gli esempi di codifica descritti nella sezione precedente per creare un unico comando che li produca 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 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
Il set completo sopra indicato, tuttavia, richiederà una CPU molto potente o, eventualmente, il supporto dell'offload della GPU hardware, come fornito sempre più spesso da alcuni chipset. Intel Kabylake (e versioni successive) dispone di 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 per computer utilizzando Shaka Packager
Un esempio più pratico per le macchine desktop comuni potrebbe utilizzare Shaka Packager. Un modo semplice per configurare Shaka è installarlo all'interno di un container Docker utilizzando l'immagine DockerHub di Google. Le istruzioni sono disponibili 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) |
Computer | Xfce 4.12.3 Distro: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/ |
CPU | Intel Core i5-6500 (-MCP-) quad-core cache: 6144 KB velocità di clock: max: 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz |
Scheda grafica | 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 segnala costantemente una velocità di codifica pari a 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 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
Tieni presente che le impostazioni di -speed
sono piuttosto elevate. Queste impostazioni sono state stabilite
in modo sperimentale e varieranno da una macchina all'altra.
Overhead di Shaka Packager
Il packaging non è un'attività particolarmente intensiva per la 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 sulla macchina descritta 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