Codificação ao vivo com VP9 usando FFmpeg
Parâmetros de codificação
O VP9 oferece uma série de parâmetros para otimizar a codificação em tempo real. Alguns princípios gerais deles são discutidos em Modos taxados.
Exemplo de codificação FFmpeg VP9
A tabela abaixo descreve os parâmetros de uma chamada de exemplo ffmpeg
para a codificação VP9.
Parâmetro | Descrição |
---|---|
-quality realtime |
realtime é essencial para transmissões ao vivo e para velocidades acima de 5 . |
-speed 6 |
A velocidade 5 até 8 precisa ser usada para codificação em tempo real / ao vivo. Números menores (5 ou 6 ) têm qualidade mais alta, mas exigem mais energia da CPU. Números mais altos (7 ou 8 ) terão qualidade inferior, mas serão mais gerenciáveis para casos de uso com menor latência e também para dispositivos com baixo consumo de energia, como os dispositivos móveis. |
-tile-columns 4 |
O compartilhamento divide o vídeo em regiões retangulares, o que permite várias linhas de execução para codificação e decodificação. O número de blocos é sempre uma potência de dois. 0 = 1 bloco, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32 |
-frame-parallel 1 |
Ative os recursos de codificância paralela. |
-threads 8 |
Número máximo de linhas de execução a serem usadas. |
-static-thresh 0 |
Limite de detecção de movimento. |
-max-intra-rate 300 |
Taxa máxima de bits do i-Frame (pct) |
-deadline realtime |
Versão alternativa (legada) de -quality realtime |
-lag-in-frames 0 |
Número máximo de frames para atrasar |
-qmin 4 -qmax 48 |
Valores mínimo e máximo do quantizador. Os valores exibidos são apenas uma sugestão, e isso ajudará a aumentar/diminuir a qualidade do vídeo à custa da compactação. |
-row-mt 1 |
Ativar o multi-threading. Permite o uso de até duas vezes a linha de execução como colunas de bloco. 0 = desativado, 1 = ativado. |
-error-resilient 1 |
Ativar recursos de resiliência de erros. |
Como escolher parâmetros de codificação
As informações abaixo usam codificação de taxa de bits constante (CBR) para streaming de taxa de bits adaptável (ABR, na sigla em inglês), em que cada taxa de destino é definida explicitamente no manifesto do Packager. Isso resultará em uma "mudança" mais clara entre as taxas para os clientes. A codificação de taxa de bits variável (VBR) e o modo CQ também serão opções se a taxa de bits for mais flexível ou se a codificação estiver sendo fragmentada. O modo Q terá um problema com a codificação em tempo real necessária para vídeo ao vivo. Consulte Modos taxados para ver mais informações.
Para mais detalhes sobre como manipular o VP9, também vale a pena consultar o artigo associado sobre as configurações de VOD, mas considerando o foco na CBR.
Dicas e sugestões
Lembre-se de que, na transmissão ao vivo, tudo é restrito a uma velocidade de codificação mínima de 1x em tempo real. O FFmpeg informa a velocidade de codificação à medida que avança. Se a velocidade de codificação diminuir para menos de 1x, o processo de codificação não acompanhará a entrada de vídeo ao vivo, e os usuários enfrentarão buffer, e as interrupções na transmissão tornarão o stream inutilizável durante a transmissão ao vivo, embora o arquivo seja geralmente utilizável.
Exemplos de parâmetros de codificação em ação
Veja a seguir a utilização da CPU a 25 fps para vários tamanhos de frame em uma área de trabalho quad-core i5 de 3,6 Ghz com Linux:
Resolução-alvo | Parâmetros FFmpeg VP9 | CPU / Velocidade (exemplo) |
---|---|---|
3.840 x 2.160 (2160p) | -r 30 -g 90 -s 3840 x 2160 -qualidade em tempo real -velocidade 5 -linhas de execução 16 -row-mt 1 -colunas-coluna 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k | ~88% 0.39x |
2.560 x 1.440 (1440p) | -r 30 -g 90 -s 2560 x 1440 -qualidade em tempo real -velocidade 5 -linhas de execução 16 -row-mt 1 -colunas-3 - -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6.000k | Cerca de 86% 0,68x |
1.920 x 1.080 (1080p) | -r 30 -g 90 -s 1920 x 1080 -qualidade em tempo real -velocidade 5 -linhas de execução 8 -row-mt 1 -colunas-coluna 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500 mil | Cerca de 82% 1,04x |
1.280 x 720 (720p) | -r 30 -g 90 -s 1.280 x 720 -qualidade em tempo real -velocidade 5 -linhas de execução 8 -linha-mt 1 -colunas-coluna 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3.000k | Cerca de 78% 1,77x |
854x480 (480p) | -r 30 -g 90 -s 854 x 480 -qualidade em tempo real -velocidade 6 -linhas de execução 4 -linha-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k | Cerca de 64% 3,51x |
640x360 (360p) | -r 30 -g 90 -s 640 x 360 -qualidade em tempo real -velocidade 7 -linhas de execução 4 -linha-mt 1 -tile-columns 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k | Cerca de 62% 5,27x |
426x240 (240p) | -r 30 -g 90 -s 426 x 240 -qualidade em tempo real -velocidade 8 -linhas de execução 2 -linha-mt 1 -tile-columns 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k | Cerca de 66% 8,27x |
Veja um exemplo de FFmpeg:
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
Dicas e sugestões
Aqui, a saída está sendo feita para um pipeline FIFO ("pipe1"), que precisa ser criado antes da execução, antes de executar o comando FFmpeg. Para fazer isso, forneça o comando
mkfifo pipe1
no seu diretório de trabalho. Ao usar o Shaka Packager, ele detecta esse pipeline como origem de entrada do stream especificado. Outros modelos de empacotamento podem exigir um método diferente.Para garantir que os comandos
-row-mt
sejam reconhecidos, use a versão estável mais recente do FFmpeg (3.3.3 atualmente) de https://www.ffmpeg.org/download.html.
Exemplo de taxa de bits adaptável definida
Dependendo da capacidade da máquina que executa a codificação do FFmpeg, ela pode ou não ser capaz de entregar todas as codificações a seguir ao mesmo tempo. Portanto, um subconjunto adequado para seus próprios recursos disponíveis e os públicos-alvo precisam ser selecionados na lista.
Pacote completo de ABR do FFmpeg
Em um cenário ideal, combinamos os exemplos de codificação descritos na seção anterior para criar um único comando que produza todos eles ao mesmo tempo:
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
No entanto, o conjunto completo acima exigirá uma CPU muito poderosa ou possivelmente suporte de descarga de GPU de hardware, como alguns chipsets fornecem cada vez mais. O Intel Kabylake (e além) tem um pipeline completo de codificação de hardware. A GPU Kabylake pode codificar VP9 de 8 bits, mas não de 10 bits.
Um exemplo prático de computador usando o Shaka Packager
Um exemplo prático para máquinas comuns de computador pode ser o Shaka Packager. Uma maneira simples de configurar o Shaka é instalá-lo em um contêiner do Docker, usando a imagem do DockerHub do Google. As instruções podem ser encontradas aqui:
https://github.com/google/shaka-packager#using-docker-for-testing--development
Neste exemplo, usamos uma máquina com a seguinte configuração:
Sistema | Host: obs Kernel: 4.4.0-91-lowlat x86_64 (64 bits) |
Computador | Xfce 4.12.3 Distro: SO: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/ |
CPU | Intel Core i5-6500 (-MCP-) de quatro núcleos cache: 6.144 KB velocidades de relógio: máx. 3.600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz |
Placa gráfica | Gráficos integrados do Intel PageSpeed |
Memória | 8 GB de RAM |
Na prática, essa máquina consegue produzir de maneira ideal o seguinte intervalo utilizável de codificações ABR, com o FFmpeg informando consistentemente uma velocidade de codificação 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
As configurações de -speed
são muito altas. Essas configurações foram estabelecidas
experimental e varia de acordo com a máquina.
Sobrecarga do Shaka Packager
O empacotamento não é uma atividade particularmente intensa. O Shaka Packager pode ser configurado para detectar todas as saídas, mesmo que apenas um subconjunto seja enviado pelo FFmpeg. Estas são as configurações do Packager testadas na máquina descrita acima:
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