Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Первая часть: Noções básicas de trabalho com vídeo e imagens

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

O quê? Um codec de vídeo é um software/hardware que compacta e/ou descompacta vídeo digital.

Para quê? Apesar de certas limitações em termos de largura de banda e
e em termos de espaço de armazenamento de dados, o mercado exige vídeo de qualidade cada vez maior. Você se lembra como no último post calculamos o mínimo necessário para 30 frames por segundo, 24 bits por pixel, com resolução de 480x240? Recebemos 82,944 Mbit/s sem compressão. Atualmente, a compactação é a única maneira de transmitir HD/FullHD/4K para telas de televisão e para a Internet. Como isso é alcançado? Agora vamos examinar brevemente os métodos principais.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

A tradução foi feita com o apoio da EDISON Software.

Estamos engajados em integração de sistemas de videovigilânciaE estamos desenvolvendo um microtomógrafo.

Codec versus contêiner

Um erro comum que os novatos cometem é confundir codec de vídeo digital com contêiner de vídeo digital. Um contêiner tem um determinado formato. Um wrapper contendo metadados de vídeo (e possivelmente de áudio). O vídeo compactado pode ser considerado uma carga útil de contêiner.

Normalmente, a extensão de um arquivo de vídeo indica seu tipo de contêiner. Por exemplo, o arquivo video.mp4 é provavelmente um contêiner MPEG-4 Part 14, e um arquivo chamado video.mkv é provavelmente matryoshka. Para ter certeza absoluta do formato do codec e do contêiner, você pode usar FFmpeg ou MediaInfo.

Um pouco de história

Antes de chegarmos Como?, vamos mergulhar um pouco na história para entender um pouco melhor alguns codecs mais antigos.

Codec de vídeo H.261 apareceu em 1990 (tecnicamente - em 1988) e foi criado para operar a uma taxa de transferência de dados de 64 Kbps. Já utilizou ideias como subamostragem de cores, macroblocos, etc. O padrão de codec de vídeo foi publicado em 1995 H.263, que se desenvolveu até 2001.

A primeira versão foi concluída em 2003 H.264 / AVC. Nesse mesmo ano, a TrueMotion lançou seu codec de vídeo gratuito com perdas chamado VP3. O Google comprou a empresa em 2008, lançando VP8 no mesmo ano. Em dezembro de 2012, o Google lançou VP9, e é compatível com cerca de ¾ do mercado de navegadores (incluindo dispositivos móveis).

AV1 é um novo codec de vídeo gratuito e de código aberto desenvolvido por Aliança para Mídia Aberta (AOM Media), que inclui as empresas mais famosas, como: Google, Mozilla, Microsoft, Amazon, Netflix, AMD, ARM, NVidia, Intel e Cisco. A primeira versão do codec, 0.1.0, foi publicada em 7 de abril de 2016.

Nascimento de AV1

No início de 2015, o Google estava trabalhando em VP10Xiph (que é propriedade da Mozilla) estava trabalhando em Daala, e a Cisco criou seu próprio codec de vídeo gratuito chamado Thor.

em seguida MPEG-LA limites anuais anunciados pela primeira vez para HEVC (H.265) e uma taxa 8 vezes maior que a do H.264, mas logo mudaram as regras novamente:

sem limite anual,
taxa de conteúdo (0,5% da receita) e
a taxa unitária é cerca de 10 vezes maior que o H.264.

Aliança para Mídia Aberta foi criado por empresas de diversos ramos: fabricantes de equipamentos (Intel, AMD, ARM, Nvidia, Cisco), provedores de conteúdo (Google, Netflix, Amazon), criadores de navegadores (Google, Mozilla) e outros.

As empresas tinham um objetivo comum – um codec de vídeo isento de royalties. Então aparece AV1 com uma licença de patente muito mais simples. Timothy B. Terryberry fez uma apresentação impressionante que se tornou a origem do atual conceito AV1 e de seu modelo de licenciamento.

Você ficará surpreso ao saber que pode analisar o codec AV1 através de um navegador (os interessados ​​​​podem acessar aomanalyzer.org).

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Codec universal

Vejamos os principais mecanismos subjacentes ao codec de vídeo universal. A maioria desses conceitos são úteis e usados ​​em codecs modernos, como VP9, AV1 и HEVC. Aviso que muitas das coisas explicadas serão simplificadas. Às vezes, exemplos do mundo real (como H.264) serão usados ​​para demonstrar as tecnologias.

1º passo – divisão da imagem

O primeiro passo é dividir o quadro em várias seções, subseções e além.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Para que? Existem muitas razões. Quando dividimos uma imagem, podemos prever com mais precisão o vetor de movimento usando pequenas seções para pequenas partes móveis. Já para um fundo estático você pode limitar-se a seções maiores.

Os codecs normalmente organizam essas seções em seções (ou pedaços), macroblocos (ou blocos de árvore de codificação) e múltiplas subseções. O tamanho máximo dessas partições varia, HEVC define para 64x64 enquanto AVC usa 16x16 e as subpartições podem ser divididas em tamanhos de até 4x4.

Você se lembra dos tipos de molduras do último artigo?! O mesmo pode ser aplicado aos blocos, então podemos ter um fragmento I, um bloco B, um macrobloco P, etc.

Para quem quiser praticar, observe como a imagem é dividida em seções e subseções. Para fazer isso, você pode usar o já mencionado no artigo anterior. Analisador Intel Video Pro (aquele que é pago, mas com versão de teste gratuita limitada aos primeiros 10 frames). Seções analisadas aqui VP9:

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

2ª etapa – previsão

Assim que tivermos seções, podemos fazer previsões astrológicas para elas. Para Previsões INTER deve ser transferido vetores de movimento e o restante, e para previsão INTRA é transmitido direção da previsão e o restante.

3º passo – transformação

Uma vez que tenhamos um bloco residual (seção prevista → seção real), é possível transformá-lo de forma que saibamos quais pixels podem ser descartados mantendo a qualidade geral. Existem algumas transformações que fornecem o comportamento exato.

Embora existam outros métodos, vamos examiná-los com mais detalhes. transformada discreta de cosseno (DCT - a partir de transformada discreta de cosseno). Principais funções do DCT:

  • Converte blocos de pixels em blocos de coeficientes de frequência de tamanhos iguais.
  • Condensa a energia para ajudar a eliminar a redundância espacial.
  • Fornece reversibilidade.

2 de fevereiro de 2017 Sintra R.J. (Cintra, RJ) e Bayer F.M. (Bayer FM) publicou um artigo sobre uma transformação semelhante ao DCT para compactação de imagens que requer apenas 14 adições.

Não se preocupe se não entender os benefícios de cada ponto. Agora vamos usar exemplos específicos para ver seu valor real.

Vamos pegar este bloco de pixels 8x8:

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Este bloco é renderizado na seguinte imagem de 8 por 8 pixels:

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Aplique DCT a este bloco de pixels e obtenha um bloco de coeficientes 8x8:

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

E se renderizarmos este bloco de coeficientes, obteremos a seguinte imagem:

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Como você pode ver, não se parece com a imagem original. Você pode ver que o primeiro coeficiente é muito diferente de todos os outros. Este primeiro coeficiente é conhecido como coeficiente DC, que representa todas as amostras da matriz de entrada, algo como uma média.

Este bloco de coeficientes possui uma propriedade interessante: separa os componentes de alta frequência dos de baixa frequência.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Em uma imagem, a maior parte da potência está concentrada em frequências mais baixas, portanto, se você converter a imagem em seus componentes de frequência e descartar os coeficientes de frequência mais altos, poderá reduzir a quantidade de dados necessários para descrever a imagem sem sacrificar muito a qualidade da imagem.

Frequência refere-se à rapidez com que o sinal muda.

Vamos tentar aplicar o conhecimento adquirido no caso de teste convertendo a imagem original para sua frequência (bloco de coeficientes) usando DCT e depois descartando parte dos coeficientes menos importantes.

Primeiro, convertemos para o domínio da frequência.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

A seguir descartamos parte (67%) dos coeficientes, principalmente a parte inferior direita.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Finalmente, reconstruímos a imagem a partir deste bloco de coeficientes descartados (lembre-se, deve ser invertível) e comparamos com o original.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Vemos que se assemelha à imagem original, mas existem muitas diferenças em relação ao original. Jogamos fora 67,1875% e ainda conseguimos algo parecido com o original. Foi possível descartar os coeficientes de forma mais criteriosa para obter uma imagem de qualidade ainda melhor, mas isso é um próximo assunto.

Cada coeficiente é gerado usando todos os pixels

Importante: cada coeficiente não é mapeado diretamente para um pixel, mas é uma soma ponderada de todos os pixels. Este gráfico incrível mostra como o primeiro e o segundo coeficientes são calculados usando pesos exclusivos para cada índice.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Você também pode tentar visualizar o DCT observando uma formação de imagem simples baseada nele. Por exemplo, aqui está o símbolo A gerado usando cada peso de coeficiente:

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

4º passo – quantização

Depois de descartarmos alguns coeficientes na etapa anterior, na última etapa (transformação) realizamos uma forma especial de quantização. Nesta fase é aceitável perder informações. Ou, mais simplesmente, quantizaremos os coeficientes para obter compressão.

Como você pode quantizar um bloco de coeficientes? Um dos métodos mais simples é a quantização uniforme, quando pegamos um bloco, dividimos por um valor (por 10) e arredondamos o resultado.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Podemos reverter esse bloco de coeficientes? Sim, podemos, multiplicando pelo mesmo valor pelo qual dividimos.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Esta abordagem não é a melhor porque não leva em conta a importância de cada coeficiente. Poderíamos usar uma matriz de quantizadores em vez de um único valor, e essa matriz poderia explorar a propriedade DCT quantizando a maioria do canto inferior direito e a minoria do canto superior esquerdo.

Etapa 5 - codificação de entropia

Depois de quantizarmos os dados (blocos de imagem, fragmentos, quadros), ainda podemos compactá-los sem perdas. Existem muitas maneiras algorítmicas de compactar dados. Vamos dar uma olhada rápida em alguns deles, para uma compreensão mais profunda você pode ler o livro Understanding Compression: Data Compression for Modern Developers ("Noções básicas sobre compactação: compactação de dados para desenvolvedores modernos").

Codificação de vídeo usando VLC

Digamos que temos um fluxo de personagens: a, e, r и t. A probabilidade (variando de 0 a 1) de quantas vezes cada personagem aparece em um fluxo é apresentada nesta tabela.

a e r t
Probabilidade 0,3 0,3 0,2 0,2

Podemos atribuir códigos binários únicos (de preferência pequenos) aos mais prováveis, e códigos maiores aos menos prováveis.

a e r t
Probabilidade 0,3 0,3 0,2 0,2
Código binário 0 10 110 1110

Comprimimos o fluxo, assumindo que acabaremos gastando 8 bits para cada caractere. Sem compactação, seriam necessários 24 bits por caractere. Se você substituir cada caractere pelo seu código, você economizará!

O primeiro passo é codificar o caractere e, que é igual a 10, e o segundo caractere é a, que é adicionado (não de forma matemática): [10][0] e, finalmente, o terceiro caractere t, o que torna nosso fluxo de bits compactado final igual a [10][0][1110] ou 1001110, que requer apenas 7 bits (3,4 vezes menos espaço que o original).

Observe que cada código deve ser um código exclusivo com um prefixo. Algoritmo de Huffman irá ajudá-lo a encontrar esses números. Embora esse método tenha suas falhas, existem codecs de vídeo que ainda oferecem esse método algorítmico para compactação.

Tanto o codificador quanto o decodificador devem ter acesso a uma tabela de símbolos com seus códigos binários. Portanto, também é necessário enviar uma tabela como entrada.

Codificação aritmética

Digamos que temos um fluxo de personagens: a, e, r, s и t, e sua probabilidade é apresentada nesta tabela.

a e r s t
Probabilidade 0,3 0,3 0,15 0,05 0,2

Usando esta tabela, construiremos intervalos contendo todos os caracteres possíveis, classificados pelo maior número.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Agora vamos codificar um fluxo de três caracteres: comer.

Primeiro selecione o primeiro caractere e, que está na subfaixa de 0,3 a 0,6 (sem incluir). Pegamos neste subintervalo e dividimo-lo novamente nas mesmas proporções de antes, mas para este novo intervalo.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Vamos continuar codificando nosso stream comer. Agora pegue o segundo personagem a, que está no novo subintervalo de 0,3 a 0,39, e então pegue nosso último caractere t e repetindo o mesmo processo novamente, obtemos o subintervalo final de 0,354 a 0,372.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Precisamos apenas selecionar um número no último subintervalo de 0,354 a 0,372. Vamos escolher 0,36 (mas você pode escolher qualquer outro número neste subintervalo). Somente com este número poderemos restaurar nosso stream original. É como se estivéssemos desenhando uma linha dentro dos intervalos para codificar nosso fluxo.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

A operação inversa (ou seja, decodificação) é igualmente simples: com nosso número 0,36 e nosso intervalo inicial, podemos executar o mesmo processo. Mas agora, utilizando este número, identificamos o fluxo codificado utilizando este número.

Com o primeiro intervalo, notamos que nosso número corresponde à fatia, portanto este é nosso primeiro caractere. Agora dividimos este subintervalo novamente seguindo o mesmo processo de antes. Aqui você pode ver que 0,36 corresponde ao símbolo a, e após repetir o processo chegamos ao último caractere t (formando nosso fluxo codificado original comer).

Tanto o codificador quanto o decodificador devem possuir uma tabela de probabilidades de símbolos, portanto é necessário enviá-la também nos dados de entrada.

Muito elegante, não é? Quem criou esta solução foi muito inteligente. Alguns codecs de vídeo usam essa técnica (ou pelo menos a oferecem como opção).

A ideia é compactar sem perdas um fluxo de bits quantizado. Certamente este artigo está faltando muitos detalhes, razões, compensações, etc. Mas se você é um desenvolvedor, deveria saber mais. Novos codecs tentam usar diferentes algoritmos de codificação de entropia, como ANOS.

Etapa 6 - formato bitstream

Depois de fazer tudo isso, resta descompactar os frames compactados no contexto das etapas executadas. O decodificador deve ser explicitamente informado das decisões tomadas pelo codificador. O decodificador deve ser fornecido com todas as informações necessárias: profundidade de bits, espaço de cores, resolução, informações de previsão (vetores de movimento, previsão INTER direcional), perfil, nível, taxa de quadros, tipo de quadro, número de quadro e muito mais.

Vamos dar uma olhada rápida no bitstream H.264. Nosso primeiro passo é criar um fluxo de bits H.264 mínimo (o FFmpeg por padrão adiciona todas as opções de codificação, como SEI NAL - descobriremos o que é um pouco mais adiante). Podemos fazer isso usando nosso próprio repositório e FFmpeg.

./s/ffmpeg -i /files/i/minimal.png -pix_fmt yuv420p /files/v/minimal_yuv420.h264

Este comando irá gerar um fluxo de bits bruto H.264 com um quadro, resolução 64×64, com espaço de cores YUV420. Neste caso, a imagem a seguir é usada como moldura.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Fluxo de bits H.264

Padrão AVC (H.264) determina que as informações serão enviadas em macroframes (no sentido de rede), chamados NAL (este é um nível de abstração de rede). O principal objetivo do NAL é fornecer uma apresentação de vídeo “amigável à web”. Este padrão deve funcionar em TVs (baseado em stream) e na Internet (baseado em pacotes).

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Existe um marcador de sincronização para definir os limites dos elementos NAL. Cada token de sincronização contém um valor 0x00 0x00 0x01, exceto o primeiro, que é igual a 0x00 0x00 0x00 0x01. Se lançarmos despejo hexadecimal para o fluxo de bits H.264 gerado, identificamos pelo menos três padrões NAL no início do arquivo.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Conforme dito, o decodificador deve conhecer não apenas os dados da imagem, mas também os detalhes do vídeo, quadro, cores, parâmetros utilizados e muito mais. O primeiro byte de cada NAL define sua categoria e tipo.

Identificador de tipo NAL descrição
0 Tipo desconhecido
1 Fragmento de imagem codificado sem IDR
2 Seção de dados de fatia codificada A
3 Seção de dados de fatia codificada B
4 Seção de dados de fatia codificada C
5 Fragmento IDR codificado de uma imagem IDR
6 Mais informações sobre a extensão SEI
7 Conjunto de parâmetros de sequência SPS
8 Conjunto de parâmetros de imagem PPS
9 Separador de acesso
10 Fim da sequência
11 Fim do tópico
... ...

Normalmente, o primeiro NAL de um fluxo de bits é PLC. Este tipo de NAL é responsável por informar sobre variáveis ​​de codificação comuns como perfil, nível, resolução, etc.

Se pularmos o primeiro marcador de sincronização, podemos decodificar o primeiro byte para descobrir qual tipo de NAL é o primeiro.

Por exemplo, o primeiro byte após o token de sincronização é 01100111, onde o primeiro bit (0) está no campo forbitden_zero_bit. Próximos 2 bits (11) nos diz o campo nal_ref_idc, que indica se este NAL é um campo de referência ou não. E os 5 bits restantes (00111) nos diz o campo nal_unit_type, neste caso é o bloco SPS (7) NAL.

Segundo byte (binário=01100100, feitiço=0x64, dezembro=100) no SPS NAL é o campo perfil_idc, que mostra o perfil que o codificador usou. Neste caso, foi utilizado um perfil alto limitado (ou seja, um perfil alto sem suporte bidirecional do segmento B).

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Se você olhar para a especificação bitstream H.264 para SPS NAL, encontraremos muitos valores para nome, categoria e descrição do parâmetro. Por exemplo, vejamos os campos pic_width_in_mbs_minus_1 и pic_height_in_map_units_minus_1.

Nome do parâmetro categoria descrição
pic_width_in_mbs_minus_1 0 ue (v)
pic_height_in_map_units_minus_1 0 ue (v)

Se realizarmos algumas operações matemáticas com os valores destes campos, obteremos resolução. Pode-se representar 1920 x 1080 usando pic_width_in_mbs_minus_1 com um valor de 119 ((119 + 1) * macroblock_size = 120 * 16 = 1920). Novamente, para economizar espaço, em vez de codificar 1920, fizemos isso com 119.

Se continuarmos verificando nosso vídeo criado em formato binário (por exemplo: xxd -b -c 11 v/minimal_yuv420.h264), então você pode ir para o último NAL, que é o próprio quadro.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Aqui vemos seus primeiros valores de 6 bytes: 01100101 10001000 10000100 00000000 00100001 11111111. Como se sabe que o primeiro byte indica o tipo NAL, neste caso (00101) é um fragmento IDR (5), e então você pode explorá-lo ainda mais:

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Utilizando as informações de especificação, será possível decodificar o tipo de fragmento (tipo de fatia) e número do quadro (núm_quadro) entre outros campos importantes.

Para obter os valores de alguns campos (ue(v), me(v), se(v) ou te(v)), precisamos decodificar o fragmento usando um decodificador especial baseado em código Golomb exponencial. Este método é muito eficiente para codificar valores de variáveis, especialmente quando há muitos valores padrão.

Significados tipo de fatia и núm_quadro deste vídeo são 7 (fragmento I) e 0 (primeiro quadro).

Um fluxo de bits pode ser considerado um protocolo. Se você quiser saber mais sobre o bitstream, consulte a especificação UIT H.264. Aqui está um diagrama macro mostrando onde estão os dados da imagem (YUV em forma compactada).

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Outros fluxos de bits podem ser examinados, como VP9, H.265 (HEVC) ou até mesmo nosso novo melhor bitstream AV1. Eles são todos semelhantes? Não, mas depois que você entende pelo menos um, fica muito mais fácil entender o resto.

Quer praticar? Explore o fluxo de bits H.264

Você pode gerar um vídeo de quadro único e usar o MediaInfo para examinar o fluxo de bits H.264. Na verdade, nada impede que você sequer olhe o código-fonte que analisa o fluxo de bits H.264 (AVC).

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Para praticar, você pode usar o Intel Video Pro Analyzer (já falei que o programa é pago, mas existe uma versão de teste gratuita com limite de 10 frames?).

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

visão global

Observe que muitos codecs modernos usam o mesmo modelo que acabamos de estudar. Aqui, vamos dar uma olhada no diagrama de blocos do codec de vídeo Thor. Ele contém todas as etapas pelas quais passamos. O objetivo deste post é pelo menos dar a você uma melhor compreensão das inovações e documentação nesta área.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Anteriormente, calculava-se que seriam necessários 139 GB de espaço em disco para armazenar um arquivo de vídeo com duração de uma hora com qualidade 720p e 30 fps. Se você usar os métodos discutidos neste artigo (previsões internas e entre quadros, transformação, quantização, codificação de entropia, etc.), então você pode obter (com base no fato de que gastamos 0,031 bits por pixel), um vídeo de bastante qualidade satisfatória, ocupando apenas 367,82 MB, e não 139 GB de memória.

Como o H.265 consegue uma taxa de compressão melhor que o H.264?

Agora que sabemos mais sobre como funcionam os codecs, é mais fácil entender como os codecs mais recentes podem fornecer resoluções mais altas com menos bits.

Se você comparar AVC и HEVC, vale lembrar que quase sempre se trata de uma escolha entre maior carga de CPU e taxa de compressão.

HEVC tem mais opções de seção (e subseção) do que AVC, mais instruções internas de previsão, codificação de entropia aprimorada e muito mais. Todas essas melhorias foram feitas H.265 capaz de comprimir 50% mais do que H.264.

Como funciona um codec de vídeo? Parte 2. O quê, por que, como

Первая часть: Noções básicas de trabalho com vídeo e imagens

Fonte: habr.com

Adicionar um comentário