Codificação VP9 HDR

O vídeo em High Dynamic Range (HDR) é uma tecnologia em desenvolvimento. Hoje, há vários padrões que harmonizam gradualmente.

Para uma visão geral da evolução do vídeo HDR, consulte o artigo da Wikipédia Vídeo de alto alcance dinâmico.

O FFmpeg pode ser usado com o VP9 para (1) compactar fontes HDR em saídas de faixa dinâmica padrão (SDR) ou (2) reempacotar uma fonte HDR em formatos HDR compatíveis com a Web.

Origens de entrada

Atualmente, ao codificar HDR com VP9, qualquer codec de alta profundidade de bits (10 bits) compatível com FFmpeg pode ser usado como entrada (por exemplo, VP9 Perfil 2 e 3, H.264 (10 bits), DNxHR, HEVC, ProRes etc.). Consulte também o artigo de suporte do YouTube Enviar vídeos em High Dynamic Range (HDR).

Alcance da saída codificada:

Atualmente e em geral, os dispositivos de destino compatíveis incluem qualquer dispositivo que possa decodificar o perfil 2 do VP9 e gerar saída para uma tela HDR.

  • Chromecast Ultra + TV compatível com HDR
  • Chrome 64 Canary no Windows 10 Fall Creators Update, com a flag HDR ativada. Essa é uma boa ferramenta de depuração.
  • Qualquer TV HDR com VP9 Profile 2
    • Todos os modelos HDR da Samsung de 2017 (lista do flatpanelshd.com) e modelos de 2016 que começam com "KS"
    • Todos os modelos HDR da LG de 2017 (e alguns modelos LG G6 de 2016)
    • Em dispositivos móveis que oferecem suporte à decodificação HDR de 10 bits do perfil 2 VP9 acelerado por hardware (Meizu Pro 7)
    • Blu-ray UHD de 2017

Configurações de linha de comando do FFmpeg para ativar o perfil 2 do VP9 e EOTFs HDR

O FFmpeg precisa ter sido criado com suporte a 10 bits (ou até mesmo 12 bits).

Nos exemplos abaixo, usamos um ffmpeg criado de forma estática com suporte a 10 bits. Você pode usar nosso script de build para criar o seu ou seguir as orientações no site do FFmpeg.

Confira a seguir uma linha de comando do FFmpeg utilizável para codificação HDR nos padrões SMPTE 2084 (PQ EOTF) com VP9:

ffmpeg -i strobe_scientist_18Mbps.webm -b:v 18000000 -pass 1 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
  -maxrate 26800000 -minrate 8040000 -profile:v 2 -vcodec libvpx-vp9 /dev/null && \
   ffmpeg -i strobe_scientist_18Mbps.webm -b:v 18000000 -pass 2 \
   -pix_fmt yuv420p10le \
   -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
   -maxrate 26800000 -minrate 8040000 -profile:v 2 -vcodec libvpx-vp9 \
   strobe_scientist_18Mbps.webm

Confira os principais parâmetros apresentados aqui:

ffmpeg O build estático com suporte a 10 bits
-pass 1 O HDR exige codificação de duas passagens. Neste exemplo, a primeira transmissão é enviada para /dev/null e processada na memória durante a segunda transmissão.
-pix_fmt yuv420p10le Define o formato de pixel YUV 4:2:0 de 10 bits.
-color_primaries 9 Define BT2020. Consulte as páginas 5 e 6 deste documento para mais detalhes.
-color_trc 16 16 define as características de transferência como SMPTE 2084. PQ 18 define as características de transferência SMPTE 2086 HLG
-colorspace 9 colorspace é "matrix_coefficients". Isso precisa ser definido de acordo com a forma como o conteúdo foi masterizado. (por exemplo, bt709, bt2020_ncl). Neste exemplo, deve ser 9 para bt2020_ncl. Para mais informações, consulte a página 12 deste documento.
-color_range 1 Intervalo de cores (0 = não especificado, 1 = mpeg/studio/tv, 2 = jpeg/full/pc)
-profile:v 2 Para HDR, é necessário um perfil ou 2 ou 3.
-vcodec libvpx-vp9 Use o codificador VP9.

Exemplo de codificações

Os exemplos a seguir usam o arquivo de origem strobe_scientist.mkv.

Como uma observação geral sobre taxas de bits com codificação HDR, é recomendável usar uma taxa de bits 25 a 30% maior do que a codificação SDR de 8 bits equivalente. Os exemplos geralmente têm como alvo 18 Mbps. É possível alcançar bons resultados de HDR com taxas de bits de 12 Mbps e ajuste ideal.

As codificações foram realizadas em um sistema Ubuntu Linux com as seguintes especificações:

  • Processador: 4x Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
  • Memória (RAM): 8060 MB (1492 MB usados)
  • Gráficos: Intel HD Graphics 530 (Skylake GT2)
  • SO: Ubuntu 16.04 LTS

Converter para YUV 4:2:0 10 bits PQ

Exemplo A: 6 Mbps 4k 2 passagens
ffmpeg -y -report -i strobe_scientist.mkv -b:v 6000000 -speed 4 -pass 1 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
  -maxrate 8000000 -minrate 4000000 \
  -profile:v 2 -vcodec libvpx-vp9 -f webm /dev/null && \
  ffmpeg -y -report -i strobe_scientist.mkv -b:v 6000000 -pass 2 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
  -maxrate 8000000 -minrate 4000000 \
  -profile:v 2 -vcodec libvpx-vp9 \
  2pass_HDR_strobe_scientist_6Mbps-static.webm
Exemplo B1: 18 Mbps 4k 2 passagens
ffmpeg -y -report -i strobe_scientist.mkv -b:v **18000000** -speed 4 -pass 1 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
  -maxrate **20800000** -minrate **15040000** \
  -profile:v 2 -vcodec libvpx-vp9 -f webm /dev/null && \
  ffmpeg -y -report -i strobe_scientist.mkv -b:v 18000000 -pass 2 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
  -maxrate **20800000** -minrate **15040000** \
  -profile:v 2 -vcodec libvpx-vp9 \
  2pass_HDR_strobe_scientist_18Mbps-static.webm
Exemplo B2: 18 Mbps 1080p 2 passagens
ffmpeg -y -report -i strobe_scientist.mkv -b:v 18000000 -speed 4 -pass 1 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
  -maxrate 20800000 -minrate 15040000 \
  -profile:v 2 **-vf ****scale=-1:1080**** **-vcodec libvpx-vp9 \
  -f webm /dev/null && \
  ffmpeg -y -report -i strobe_scientist.mkv -b:v 18000000 -pass 2 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 \
  -maxrate 20800000 -minrate 15040000 \
  -profile:v 2 **-vf ****scale=-1:1080**** **-vcodec libvpx-vp9 \
  1080_2pass_HDR_strobe_scientist_18Mbps-static.webm

Converter HDR em SDR com uma tabela de pesquisa (LUT)

Para converter HDR em SDR, o transcodificador precisa entender como mapear níveis de brilho e cores para o espaço de cores BT.709 menor e o intervalo de brilho não HDR. Para ter os melhores resultados, use uma LUT que descreva como realizar esse mapeamento, geralmente específico do conteúdo. Os exemplos C e D mostram como usar uma LUT. Usamos bt2020_to_bt709_example.cube

Exemplo C: 18 Mbps 4K HDR para SDR com LUT
ffmpeg -i strobe_scientist.mkv -y -b:v 18000000 -speed 4 -pass 1 \
  -pix_fmt yuv420p \
  -color_primaries 1 -color_trc 1 -colorspace 1 -color_range 1 \
  -maxrate 26800000 -minrate 8040000 -profile:v 0 \
  -vf scale=-1:-1:in_color_matrix=bt2020,format=rgb48,lut3d=bt2020_to_bt709_example.cube,scale=-1:-1:out_color_matrix=bt709 \
  -vcodec libvpx-vp9 -f webm /dev/null && \
  ffmpeg -i strobe_scientist.mkv -y -b:v 18000000 -pass 2 \
  -pix_fmt yuv420p \
  -color_primaries 1 -color_trc 1 -colorspace 1 -color_range 1 \
  -maxrate 26800000 -minrate 8040000 -profile:v 0 \
  -vf scale=-1:-1:in_color_matrix=bt2020,format=rgb48,lut3d=bt2020_to_bt709_example.cube,scale=-1:-1:out_color_matrix=bt709 \
  -vcodec libvpx-vp9 -f webm SDR_strobe_scientist_18Mbps-static.webm

Converter HLG para VP9 HLG10 10 bits PQ

Requer uma fonte HLG. Usamos o arquivo de entrada strobe_scientist_hlg.mkv

Exemplo D: 18 Mbps 4k 2-Pass HLG
ffmpeg -y -i strobe_scientist_hlg.mkv -b:v 18000000 -pass 1 -speed 4 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 18 -colorspace 9 -color_range 1 \
  -maxrate 26800000 -minrate 8040000 \
  -profile:v 2 -vcodec libvpx-vp9 -f webm /dev/null && \
  ffmpeg -y -i strobe_scientist_hlg.mkv -b:v 18000000 -pass 2 \
  -pix_fmt yuv420p10le \
  -color_primaries 9 -color_trc 18 -colorspace 9 -color_range 1 \
  -maxrate 26800000 -minrate 8040000 \
  -profile:v 2 -vcodec libvpx-vp9 \
  HLG_HDR_strobe_scientist_18Mbps-static.webm

Resumo

Os arquivos de saída têm tamanhos variados. A entrada era de 4,3 GB.

Exemplo Saída desejada Tamanho no disco Tempo de codificação
A 6 Mbps 4k HDR sem escalonamento 51,2 MB 142m
B1 HDR 4K sem escalonamento de 18 Mbps 161MB 213m
B2 HDR dimensionado de 1080p a 18 Mbps 160MB 113m
C 18 Mbps HDR para SDR sem escalonamento 165MB 124m
D Conversão HLG de 18 Mbps 165MB 168m

A codificação de duas passagens é recomendada para HDR, já que a de uma passagem pode variar em determinadas configurações.

Ferramentas necessárias para sinalizar HDR na saída WebM e MP4 (ferramentas de linha de comando Matroska)

No momento da redação deste artigo, o FFmpeg não oferece um mecanismo para especificar metadados estáticos SMPTE 2086 em WebM/MKV, mas os propaga de um fluxo de entrada quando ele os contém.

A ferramenta mkvmerge, parte do mkvtoolnix, pode ser usada para inserir ou modificar esses metadados, caso seu aplicativo exija isso.

Confira abaixo um exemplo de como inserir metadados HDR em um dos arquivos criados acima. Ele é especialmente adequado para preparar conteúdo HDR para envio ao YouTube.

mkvmerge \
  -o HDR_strobe_scientist_18Mbps.mkv\
  --colour-matrix 0:9 \
  --colour-range 0:1 \
  --colour-transfer-characteristics 0:16 \
  --colour-primaries 0:9 \
  --max-content-light 0:1000 \
  --max-frame-light 0:300 \
  --max-luminance 0:1000 \
  --min-luminance 0:0.01 \
  --chromaticity-coordinates 0:0.68,0.32,0.265,0.690,0.15,0.06 \
  --white-colour-coordinates 0:0.3127,0.3290 \
  HDR_strobe_scientist_18Mbps.webm

Este exemplo produz o arquivo HDR_strobe_scientist_18Mbps.mkv em 0,6 segundos.