Trilha 16 · Imagens, áudio e vídeo

Vídeo: frames e codecs

Como H.264 comprime vídeo em 100× — I-frames, P-frames, B-frames, motion vectors, GOPs e a diferença entre H.264, HEVC e AV1.

① Intuição

Vídeo é sequência temporal — use isso

Um vídeo de 1080p a 30fps tem ~1.5 Gbps de dados brutos. Netflix streaming usa 5–10 Mbps. Compressão de 100–300×. Como?

A chave é que frames consecutivos são quase idênticos. Em vez de transmitir cada frame completo, codecs modernos transmitem apenas as diferenças (deltas) em relação ao frame anterior. Mas há mais: o codificador encontra onde cada bloco de 16×16 pixels se moveu no frame anterior — isso são os motion vectors. A diferença entre o bloco predito e o real (o residual) é geralmente muito próxima de zero e comprime muito bem.

Seek e I-frames: o player de vídeo precisa de um I-frame completo como ponto de partida para poder decodificar os P e B-frames seguintes. Por isso, quando você arrasta a barra de progresso ("scrub"), o player salta para o I-frame mais próximo. Quanto mais espaçados os I-frames (GOP grande), pior é a experiência de seek — mas melhor é a compressão.
② Visualização interativa

I-frames vs. P-frames

Navegue pelos frames e alterne entre modo I-frame (completo) e P-frame (delta). Observe quais pixels mudaram entre frames.

FRAME 1I-FRAME (completo)
I
I
P
P
P
ESTATÍSTICAS DO FRAME
Tipo: I-Frame
Dados transmitidos: 720 bytes
Pixels totais: 240
TIPOS DE FRAME (H.264/HEVC)
I-Frame — Intra: frame completo, sem referência.
P-Frame — Predicted: delta do frame anterior.
B-Frame — Bidirectional: usa frame anterior E posterior.
GOP — GROUP OF PICTURES
I
P
P
P
B
P
B
P
P
B
I
P
Um GOP típico começa com I-frame e tem 10–30 frames. O I-frame permite "seek" aleatório no vídeo.
③ Explicação técnica

Estrutura GOP e tipos de frame

// Estrutura de um GOP (Group of Pictures) em H.264
// Sequência típica: I B B P B B P B B P ... I

// I-Frame (Intra): frame completo, sem referência
const iFrame = {
  tipo: "I",
  dados: encodeFullFrame(pixelData),  // DCT + quantização por bloco
  tamanho: "grande",                // ~10-50x um P-frame
};

// P-Frame (Predicted): delta em relação ao frame anterior
const pFrame = {
  tipo: "P",
  motionVectors: [               // onde cada bloco 16×16 foi em relação ao frame ref
    { dx: +3, dy: 0 },          // este bloco se moveu 3px para direita
    { dx: 0,  dy: +1 },          // este bloco se moveu 1px para baixo
  ],
  residual: encodeDelta(diff),   // erro de predição (quase zeros!)
  tamanho: "pequeno",             // ~5-20x menor que I-frame
};

// B-Frame (Bidirectional): usa frame anterior E posterior
const bFrame = {
  tipo: "B",
  refAnterior: prevFrame,
  refPosterior: nextFrame,       // exige buffer extra no decodificador
  tamanho: "muito pequeno",
};

Bitrates e codecs modernos

// Cálculo de bitrate para diferentes qualidades

// Vídeo bruto: 1080p 30fps
const rawBitrate = 1920 * 1080 * 3 * 8 * 30;  // ~1.5 Gbps !

// Após compressão H.264:
const streamingSD  = "1–3 Mbps";   // Netflix 720p
const streamingHD  = "5–10 Mbps";  // Netflix 1080p
const streaming4K  = "15–25 Mbps"; // Netflix 4K HDR
const bluray4K     = "50–128 Mbps";// Blu-ray Ultra HD

// Taxa de compressão H.264: ~100:1 sobre vídeo bruto
// HEVC/H.265: ~150:1 (50% menor que H.264 mesma qualidade)
// AV1: ~180:1 (30% menor que HEVC, codec aberto)

// Modos de controle de bitrate:
// CBR: bitrate constante — bom para streaming ao vivo
// VBR: bitrate variável — cenas complexas = mais bits, simples = menos
// CRF: qualidade constante — encoder decide o bitrate automaticamente
Motion estimation é o passo mais caro: para cada bloco 16×16 do frame atual, o encoder busca no frame de referência o bloco mais parecido — uma busca que poderia ser O(resolução²) por bloco. Codecs modernos usam busca hierárquica (começa no pixel 1/4 de resolução, refina) e SIMD para acelerar. Um encoder lento como x265 veryslow pode levar 10 segundos de CPU para codificar 1 segundo de vídeo.
④ Projeto para programar

Compressor de vídeo simples

Mini projeto: capture frames da câmera com getUserMedia + Canvas. Para cada frame, calcule a diferença em relação ao frame anterior (subtração pixel a pixel). Visualize os pixels que mudaram (delta frame) em tempo real.

Projeto principal: implemente motion compensation simples: divida cada frame em blocos 16×16. Para cada bloco, encontre o bloco mais parecido no frame anterior (busca em janela de ±8 pixels). Calcule o residual (diferença) e compare a compressão total: motion vectors + residual vs. frame bruto.

Desafio extra: use a MediaRecorder API do browser para gravar vídeo de câmera em tempo real com diferentes bitrates (bits/segundo). Compare o tamanho de arquivo e a qualidade visual. Experimente formatos: WebM (VP8/AV1) vs. MP4 (H.264).

⑤ Exercícios rápidos

Teste sua intuição

Qual é o papel dos I-frames numa sequência de vídeo comprimido?
Como um P-frame consegue ser muito menor que um I-frame?
Por que HEVC (H.265) e AV1 conseguem melhor compressão que H.264?
⑥ Aplicações no mundo real

Onde você encontra isso

📺

Streaming (Netflix, YouTube)

Netflix usa HEVC para 4K HDR e AV1 para SD/HD em TVs e celulares. O conteúdo é codificado em múltiplas resoluções e qualidades (Adaptive Bitrate / ABR). O player mede a velocidade de download a cada 2–4 segundos e troca para o segmento de melhor qualidade que a conexão suporta.

📹

Videoconferência em tempo real

Zoom, Meet e Teams usam H.264 ou AV1 com codificação em tempo real (<50ms de latência). Não podem usar B-frames (exigem frame futuro) e GOP deve ser pequeno (I-frame a cada 2–3s) para tolerância a perda de pacotes UDP. Quando perde um P-frame, a imagem congela até o próximo I-frame.

🎮

Game streaming (Twitch, cloud gaming)

GeForce Now, Xbox Cloud Gaming e PS Remote Play usam NVENC/AMF (codificação em hardware na GPU) para codificar H.264/HEVC em tempo real a 60fps sem impactar o jogo. Latência alvo <50ms desde o input até o pixel na tela do jogador remoto. Cada frame precisa ser codificado em <16ms.

← Anterior: Codificação de Huffman ✓ Concluir trilha: Imagens, áudio e vídeo