A maioria das pessoas conhece os fundamentos da teoria da cor. Ao combinar o brilho de várias cores primárias, você pode recriar qualquer cor visível para uma pessoa. Muitas pessoas sabem que as cores individuais são simplesmente os comprimentos de onda do espectro eletromagnético. Mas o que muitos não percebem é como a situação se torna difícil quando nos esforçamos para registrar e reproduzir cores com precisão.
Existem muitos sistemas envolvidos na conversão de um valor tripleto RGB em um comprimento de onda de luz específico. Essa transformação deve ser padronizada para que todos os softwares, todos os decodificadores de vídeo, placas de vídeo e monitores (mesmo feitos por fabricantes diferentes em décadas diferentes) possam produzir os mesmos resultados com os mesmos dados de entrada. Para enfrentar este desafio, foram desenvolvidos padrões de cores. No entanto, monitores e outras tecnologias evoluíram com o tempo. A televisão se tornou digital, a compressão começou e trocamos os CRTs por LCD e OLED. O novo equipamento era capaz de exibir mais cores com brilho mais alto, mas os sinais recebidos ainda eram adaptados às capacidades dos monitores mais antigos.
A solução para este problema foi criar um novo "espaço de cores". Novo conteúdo HD pode ser produzido em um novo espaço de cores e novos monitores HD podem exibi-lo. E se o espaço de cor antigo for convertido em um novo antes de ser exibido, o conteúdo antigo não perderá compatibilidade.
Esta é uma solução funcional, mas complica o processo de criação de vídeo. Em cada etapa do processo de captura, gravação, edição, codificação, decodificação, composição e exibição, você precisa considerar o espaço de cores que está usando. E se pelo menos uma etapa do processo usar equipamento antigo, ou houver um bug de software devido ao qual o espaço de cores não é levado em consideração, o resultado pode ser uma imagem incorreta. O vídeo ainda pode ser assistido, mas as cores podem parecer muito escuras ou claras.
Hoje, os dois espaços de cores mais populares são BT.601 (também chamado de smpte170m; usarei esses dois nomes neste artigo), que se tornou o padrão para conteúdo SD, e BT.709, que se tornou o padrão para Conteúdo HD. Existe também o BT.2020, que está se tornando mais popular graças ao seu conteúdo HDR e UHD. É importante notar que a divisão HD / SD é um pouco falha aqui. Não há limitações técnicas, é apenas uma abordagem tradicional. O conteúdo HD pode ser codificado em BT.601 e o conteúdo SD em BT.709. Se você pegar um arquivo de vídeo 1080p e reduzi-lo para 480p, o espaço de cores não mudará automaticamente. Alterar o espaço de cores é uma etapa adicional realizada como parte do processo.
O que acontece se um processo não for executado corretamente? Vamos fazer um experimento.
O programa ffmpeg é um verdadeiro milagre do nosso tempo. É uma ferramenta de vídeo digital muito popular e toda a indústria deve muito a seus desenvolvedores. Em meu experimento, usarei essa ferramenta para criar e modificar arquivos de vídeo.
Primeiro, vou criar um arquivo de teste simples usando ffmpeg:
ffmpeg -f rawvideo -s 320x240 -pix_fmt yuv420p -t 1 -i /dev/zero -an -vcodec libx264 -profile:v baseline -crf 18 -preset:v placebo -color_range pc -y 601.mp4
Uma breve explicação deste comando:
ffmpeg
—
-f rawvideo
— ffmpeg, , .
-s 320x240
— . , . .
-pix_fmt yuv420p
— . Yuv420p — . , yuv(0,0,0) . RGB, , .
-t 1
— 1
-i /dev/zero
— . /dev/zero — , mac. , .
-an
— , .
-vcodec libx264
— libx264.
-profile:v baseline
— h.264. h.264, .
-preset:v placebo
— libx264, . , . , .
-color_range pc
— 0 255. 16-235. - , . ,pc
,tv
.
-crf 18
- a opção de fator de taxa constante diz à libx264 para criar um arquivo de vídeo de alta qualidade e usar quantos bits forem necessários para garantir a qualidade18
. Quanto menor for o número, maior será a qualidade. 18 é uma qualidade muito alta.
-y
- dá permissão ao ffmpeg para sobrescrever o arquivo se ele existir.
601.mp4
- o nome do arquivo resultante.
Este comando cria um arquivo 601.mp4 com 1 segundo de duração, que pode ser aberto e reproduzido. Depois de executar este comando, podemos verificar se ffmpeg não distorceu os valores de pixel executando o seguinte comando e examinando a saída:
ffmpeg -i 601.mp4 -f rawvideo - | xxd
00000000: 0000 0000 0000 0000 0000 0000 0000 0000
00000010: 0000 0000 0000 0000 0000 0000 0000 0000
00000020: 0000 0000 0000 0000 0000 0000 0000 0000
00000030: 0000 0000 0000 0000 0000 0000 0000 0000
00000040: 0000 0000 0000 0000 0000 0000 0000 0000
00000050: 0000 0000 0000 0000 0000 0000 0000 0000
...
...
Esses dados em hexadecimal indicam que todos os valores de pixel após a decodificação são zero.
Ao renderizar um vídeo no Safari, obtemos uma captura de tela como esta:
Surge a pergunta: o que é esse espaço de cores? Chamei o arquivo de 601.mp4, mas em nenhum lugar do comando especifiquei um espaço de cor, então como o Safari sabia qual tom de verde renderizar? Como o navegador sabe que yuv (0,0,0) deve ser igual a rgb (0,135,0)? Obviamente, existe um algoritmo para calcular esses valores. Na verdade, esta é uma multiplicação de matriz simples. (Observação: alguns formatos de pixel, incluindo yuv420p, requerem uma etapa de pré e pós-processamento para conversão, mas nesta demonstração omitiremos essas sutilezas.) Cada espaço de cores tem sua própria matriz. Como não especificamos a matriz do espaço de cores ao codificar o vídeo, o Safari apenas faz uma suposição. Podemos iterar sobre todas as matrizes, multiplicar todos os valores RGB pelas matrizes inversas e ver a que eles correspondem,mas vamos tentar uma abordagem mais visual e ver se podemos descobrir o que o Safari está fazendo.
Para fazer isso, irei inserir metadados no arquivo para que o Safari saiba qual espaço de cor está sendo usado e não tenha que adivinhar.
ffmpeg -f rawvideo -s 320x240 -pix_fmt yuv420p -t 1 -i /dev/zero -an -vcodec libx264 -profile:v baseline -crf 18 -preset:v placebo -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range pc -y 601vui.mp4
O comando ffmpeg permanece praticamente o mesmo, mas adicionei o seguinte:
-color_trc smpte170m
-colorspace smpte170m
-color_primaries smpte170m
Esses são os metadados para o espaço de cores em que o arquivo será codificado. Não vou explicar as diferenças entre essas opções, porque isso exigirá outro artigo. Por enquanto, apenas definimos todos eles com o espaço de cores de que precisamos. smpte170m é o mesmo que BT.601.
A especificação de um espaço de cor não afeta como o arquivo é codificado, os valores de pixel ainda são codificados como yuv (0,0,0). Para verificar isso, podemos executar o comando no novo arquivo
ffmpeg -i zero.mp4 -f rawvideo - | xxd
. Os sinalizadores de espaço de cores não são ignorados, mas simplesmente escritos em alguns bits dentro da seção "informações de usabilidade do vídeo" (VUI) no cabeçalho do fluxo de vídeo. O decodificador irá agora procurar o VUI e usá-lo para carregar a matriz desejada.
E aqui está o resultado:
Com e sem VUI, os vídeos são renderizados com a mesma cor. Vamos tentar o arquivo BT.709:
ffmpeg -i 601vui.mp4 -an -vcodec libx264 -profile:v baseline -crf 18 -preset:v placebo -vf "colorspace=range=pc:all=bt709" -y 709.mp4
Novas opções:
-i 601vui.mp4
— 601vui.mp4
-vf "colorspace=all=BT.709"
— ffmpeg, . yuv rgb, . «all» — color_primaries, colorspace color_trc.
Aqui pegamos o vídeo 601vui.mp4 e usamos o filtro de espaço de cores para converter para BT.709. O filtro de espaço de cores pode ler o espaço de cores dos dados de entrada do arquivo vui 601vui.mp4, portanto, só precisamos especificar o espaço de cores que queremos receber na saída. Executando o
comando para este arquivo
ffmpeg -i 709.mp4 -f rawvideo - | xxd
, obtemos após a transformação do espaço de cores os valores de pixel yuv (93,67,68). No entanto, ao renderizar o arquivo, deveParece o mesmo. É importante notar que os resultados finais podem não ser idênticos porque continuamos a usar 24 bits para codificar cada pixel, e BT.709 tem uma gama ligeiramente maior de cores. Consequentemente, algumas cores em BT.709 não são mapeadas exatamente para BT.601 e vice-versa.
Ao observar o resultado, você pode ver claramente que algo está errado. O novo arquivo é renderizado com valores rgb de 0.157.0 - muito mais brilhantes do que o arquivo de entrada.
Vamos dar uma olhada nas propriedades do arquivo usando o aplicativo ffprobe:
ffprobe 601vui.mp4:
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuvj420p(pc, smpte170m), 320x240, 9 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
E
ffprobe 709.mp4:
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuvj420p(pc), 320x240, 5 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
A maioria das informações aqui não é importante para nós, mas notaremos que 601vui.mp4 está no formato de pixel “yuvj420p (pc, smpte170m)”. É assim que entendemos que o arquivo tem o VUI correto. Mas 709.mp4 contém apenas "yuvj420p (pc)". Parece que os metadados do espaço de cores não foram incluídos no arquivo de saída. Embora o filtro de espaço de cores fosse capaz de ler o espaço de cores original e nós especificássemos o novo espaço explicitamente, o ffmpeg não gravou o vui correto no arquivo final.
Isso é ruim ... Ffmpeg é a ferramenta de conversão de vídeo mais popular. E está perdendo informações sobre cores. Este é provavelmente o motivo pelo qual muitos vídeos não contêm metadados de espaço de cores e, portanto, muitos vídeos são renderizados com cores incompatíveis. Em defesa do ffmpeg, esse é um problema complicado. Para inicializar o codificador, você precisa saber o espaço de cores com antecedência. Além disso, o espaço de cores pode ser alterado com um filtro de vídeo. Este é um problema complicado de resolver no código, mas ainda é triste que esse comportamento seja padrão.
Você pode contornar isso adicionando manualmente os metadados do espaço de cores:
ffmpeg -i 601vui.mp4 -an -vcodec libx264 -profile:v baseline -crf 18 -preset:v placebo -vf "colorspace=range=pc:all=bt709" -colorspace bt709 -color_primaries bt709 -color_trc bt709 -color_range pc -y 709vui.mp4
Como resultado, o valor da cor em 709vui.mp4 será rgb (0.132.0). O brilho do canal verde é um pouco menor do que em 601vui.mp4, mas como a conversão do espaço de cores ocorre com perda e o resultado me agrada, chamaremos de sucesso.
Disto podemos concluir que, quando nenhum espaço de cor é especificado no arquivo, o Safari assume que é BT.601. E no lado do Safari, essa é uma suposição muito boa. Mas, como dito acima, BT.601 é o padrão de vídeo SD e BT.709 é o padrão de vídeo HD. Vamos verificar os vídeos HD com e sem VUI e ver como o Safari os renderiza. Usei os mesmos comandos do ffmpeg, apenas alterei a resolução para 1920x1080.
Tanto em SD quanto em HD, a cor é reproduzida da mesma forma. O Safari não leva em consideração a resolução ao fazer suposições sobre o espaço de cores. A Apple está na mídia e no espaço editorial há muito tempo, então eu esperava que o produto dessa empresa apresentasse resultados decentes. Mas mesmo que tudo seja tão inteligente no Safari, é interessante como fica a situação em outros navegadores.
Cromada:
O Chrome torna o vídeo 601 um pouco mais escuro que o Safari, mas 709 tem a mesma aparência. Suspeito que a diferença se deva às otimizações de velocidade em cálculos de ponto flutuante, mas isso é irrelevante para o nosso teste.
Sei por experiência própria que quando a aceleração de hardware é desativada nas configurações, o Chrome é renderizado de forma diferente:
Examinando esse resultado, podemos ver que os valores em 601 são renderizados de maneira muito semelhante aos anteriores, mas os 709 arquivos são renderizados como se não tivessem um VUI. A partir disso, podemos concluir que o Chrome, com a aceleração de hardware desabilitada, simplesmente ignora o VUI e renderiza todos os arquivos como se estivessem no formato 601. Isso significa que todos os 709 arquivos não serão reproduzidos corretamente.
Finalmente, vamos explorar o Firefox:
Há muito o que fazer aqui. Como 709.mp4 e 709vui.mp4 têm a mesma aparência, você pode concluir que, se o VUI não estiver disponível, o Firefox assumirá o formato BT.709. Renderizar 601vui.mp4 corretamente significa que, para o conteúdo BT.601, a seção VUI é levada em consideração. No entanto, quando um arquivo BT.601 sem VUI é processado como 709, ele se torna muito escuro. Obviamente, é impossível renderizar uma imagem corretamente sem todas as informações necessárias, mas o método escolhido pelo Firefox distorce a cor mais do que aquele escolhido pelos navegadores Safari e Chrome.
Como podemos ver, a situação de renderização de cores do vídeo ainda é o Velho Oeste. Infelizmente, cobrimos apenas parte do problema. Ainda não estudamos o Windows. Vamos fazer isso.
Microsoft borda:
Parece que o Edge (pelo menos no meu computador) simplesmente ignora o VUI e renderiza tudo como 601.
Chrome (com aceleração de hardware habilitada):
A situação não é muito diferente do Mac. Se a VUI estiver presente, ela é tratada corretamente, mas se não estiver presente, presume-se que seja BT.601 para conteúdo SD e BT.709 para conteúdo HD. Este é o único navegador em que eu vi isso, mas há uma certa lógica nisso. Como a renderização é feita de forma diferente do Mac, suspeito que o problema esteja no SO ou, mais provavelmente, em algo no nível dos drivers da placa de vídeo, e essa escolha não foi feita pela equipe de desenvolvimento do Chrome.
O Firefox se comporta exatamente como em um Mac.
Para Linux, iOS, Android, Roku, Fire TV, smart TVs, consoles de jogos, etc., vou deixar isso como um exercício para o leitor.
O que aprendemos? Mais importante: sempreinclua metadados de espaço de cor em seus vídeos. Se você estiver usando o ffmpeg e não definir os sinalizadores de cor, então você não está trabalhando corretamente. Em segundo lugar, embora o ffmpeg seja um programa excelente, sua popularidade, facilidade de uso e padrões mal escolhidos têm sido um péssimo serviço. Você nunca deve presumir que o software é inteligente o suficiente para descobri-lo sozinho. Os gerentes de projeto da Ffmpeg, Google, Mozilla, Microsoft (e provavelmente Nvidia e AMD) precisam se reunir e trabalhar juntos para encontrar uma maneira. Eu entendo que não há uma boa solução aqui, mas ruim e previsível é melhor do que ruim e aleatório. Pessoalmente, recomendo sempre assumir o formato BT.601 se a seção VUI estiver faltando. Isso cria o mínimo de distorção. Pode ser selecionado para alinhar este padrão FOMS, ou mesmo a AOM , já que essas organizações estão muito bem representadas.
Por último, mas não menos importante, se você tem um vídeo sem informações de cor e precisa convertê-lo ou renderizá-lo, boa sorte!
Propaganda
VDSina oferece servidores baratos com pagamento diário. O canal de Internet para cada servidor é de 500 Megabits, a proteção contra ataques DDoS está incluída na tarifa, a capacidade de instalar Windows, Linux ou o sistema operacional em geral a partir de sua imagem, e também um painel de controle de servidor proprietário muito conveniente . É hora de tentar;)
Participe do nosso chat no Telegram .