Correção de fragmentação RTP H.264 FU-A: Por que seu vídeo RTSP está quebrado (perda de pacote, remontagem NAL)

Corrigir vídeo RTSP quebrado da fragmentação H.264 FU-A RTP. Cobre fragmentos ausentes, bugs de bits de início/fim, falhas de remontagem NAL, perda de pacotes, MTU e erros de decodificador com comandos de diagnóstico reais.

h264 fu-a, fragmentação RTP, vídeo rtsp, perda de pacotes, remontagem da unidade final, erro do decodificador h264, diagnóstico rtsp

O H.264 sobre RTP quebra de maneiras que parecem bugs de decodificador, mas na verdade são problemas de empacotamento. A sessão RTSP funciona. DESCRIBE retorna SDP válido. A CONFIGURAÇÃO foi bem-sucedida. PLAY retorna 200 OK. Os pacotes RTP chegam com o tipo de carga correto mapeado para H.264. Ainda assim, o vídeo mostra corrupção de blocos, congelamentos, quadros pretos ou erros de decodificador.

Os erros são assim nos seus registros:

[h264 @ 0x...] invalid NAL unit size
[h264 @ 0x...] missing picture in access unit
[h264 @ 0x...] non-existing PPS 0 referenced
[h264 @ 0x...] decode_slice_header error
[h264 @ 0x...] no frame!

The fast answer

Why fragmentation exists

The structure of an FU-A packet

Each FU-A RTP packet contains:

Byte 0: FU indicator
  bit 7: F (forbidden_zero_bit) — normally 0
  bits 6-5: NRI (nal_ref_idc) — priority
  bits 4-0: Type = 28 (FU-A)
Byte 1: FU header
  bit 7: S (Start) — 1 for first fragment
  bit 6: E (End) — 1 for last fragment
  bit 5: R (Reserved) — always 0
  bits 4-0: Type — original NAL unit type (1=non-IDR, 5=IDR, 7=SPS, 8=PPS)
Byte 2+: Fragment payload — the actual NAL unit data

Uma sequência FU-A completa para uma unidade NAL:

Packet 1: FU indicator (type=28) | FU header (S=1, E=0, type=5) | payload[0..N]
Packet 2: FU indicator (type=28) | FU header (S=0, E=0, type=5) | payload[N+1..M]
Packet 3: FU indicator (type=28) | FU header (S=0, E=0, type=5) | payload[M+1..P]
Packet 4: FU indicator (type=28) | FU header (S=0, E=1, type=5) | payload[P+1..END]

The RTP marker bit

Failure modes: what breaks and why

Failure 1: Missing middle fragment

Expected:  1000(S)  1001(M)  1002(M)  1003(E|marker)
Received:  1000(S)  1001(M)  [LOST]   1003(E|marker)

O remontador vê um fragmento inicial, um fragmento intermediário e, em seguida, um fragmento final — mas os bytes de carga útil não se conectam. A unidade NAL remontada apresenta uma lacuna.

Sintomas:

  • Bloqueie a corrupção em uma faixa horizontal do quadro
  • O decodificador relata "tamanho de unidade NAL inválido"
  • Corrupção limitada a uma unidade de acesso (eliminada no próximo IDR)

Falha 2: Fragmento inicial ausente

Expected:  1000(S)  1001(M)  1002(E)
Received:  [LOST]   1001(M)  1002(E)

Failure 3: Missing end fragment

Expected:  1000(S)  1001(M)  1002(E|marker)
Received:  1000(S)  1001(M)  [LOST]

O remontador nunca vê o fragmento final. O limite da unidade NAL nunca é confirmado. O decodificador espera por mais dados que nunca chegam.

Sintomas:

  • O vídeo congela
  • O decodificador relata “imagem faltando na unidade de acesso”
  • A reprodução é interrompida até a próxima unidade de acesso completo chegar

Falha 4: Fragmentos fora de ordem

Expected:  1000(S)  1001(M)  1002(E)
Received:  1000(S)  1002(E)  1001(M)

Diagnostic workflow

Step 1: Confirm H.264 payload mapping

m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=4D0029;sprop-parameter-sets=...
  • packetization-mode=1 significa modo não intercalado (FU-A é suportado)
  • packetization-mode=0 significa modo de unidade NAL única (sem fragmentação - muito limitada)

Etapa 2: rastrear números de sequência RTP

Na sua captura, observe os números de sequência RTP da trilha de vídeo. Lacunas indicam perda de pacotes:

Seq 1000: FU-A Start, NAL type 5 (IDR)
Seq 1001: FU-A middle
Seq 1003: FU-A End, marker=1   ← gap at 1002

Step 3: Inspect FU-A headers

Byte 0 (FU indicator):
  0x7C = NRI=3, Type=28 (FU-A)

Byte 1 (cabeçalho FU):
  0x85 = S=1, E=0, R=0, Tipo=5 (fatia IDR) ← fragmento inicial do IDR
  0x45 = S=0, E=0, R=0, Tipo=5 ← fragmento do meio
  0x65 = S=0, E=1, R=0, Tipo=5 ← fragmento final; marcador apenas se esta NAL encerrar a unidade de acesso

Valores errados para procurar:

  • S=1 em um pacote não iniciado → confusão do remontador
  • Marcador definido antes de E=1 → limite falso da unidade de acesso
  • E=1 sem marcador pode ser válido se outra unidade NAL vier em seguida
  • Alterações de tipo no meio da sequência → bug do codificador ou corrupção de fluxo

Etapa 4: verifique a remontagem completa

Para cada unidade NAL:

  1. Encontre o fragmento inicial (S=1)
  2. Siga os números de sequência consecutivos até o fragmento final (E=1)
  3. Contar fragmentos; verifique se não há lacunas na sequência
  4. Compare o marcador com o limite da unidade de acesso; não o exija em todo fragmento final FU-A
  5. Verifique se todos os fragmentos têm o mesmo carimbo de data/hora e tipo de NAL

Passo 5: Compare modos de transporte

Execute o mesmo fluxo em UDP e TCP intercalados. Se o vídeo estiver limpo no TCP, mas corrompido no UDP, o problema é a perda de pacotes de rede, e não problemas de codificador ou decodificador.

Etapa 6: análise de IDR versus não IDR

Os quadros IDR são maiores e requerem mais fragmentos FU-A por unidade NAL. Mais fragmentos = mais exposição à perda de pacotes. Se a corrupção aparecer principalmente nas mudanças de cena ou a cada poucos segundos (no intervalo do IDR), os quadros do IDR serão as vítimas.

Opções de correção:

  • Diminua o tamanho do quadro IDR (reduza a resolução ou taxa de bits para quadros-chave)
  • Aumente o intervalo IDR (menos quadros grandes, mas recuperação mais lenta de perdas)
  • Reduza o MTU para FU-A no codificador (mais fragmentos, mas cada um é menor e tem menos probabilidade de acionar a fragmentação de IP)

Estratégias de recuperação

Na remontagem

  • Descarte totalmente as unidades de acesso danificadas em vez de alimentar dados parciais para o decodificador
  • Solicite um novo quadro IDR via RTCP (se suportado pela câmera)
  • Aguarde o próximo quadro IDR (o decodificador se recuperará automaticamente)

No codificador

  • Reduza o limite de tamanho da unidade NAL para reduzir fragmentos por unidade de acesso
  • Use intra-atualização periódica em vez de quadros IDR completos (quadros-chave menores)
  • Habilite FEC (correção direta de erros) se a pilha RTP suportar

Na rede

  • Mude de UDP para TCP intercalado se a perda de pacotes for inevitável
  • Certifique-se de que a descoberta de MTU do caminho funcione (evite a fragmentação de IP)
  • Priorize o tráfego RTP em links congestionados

Quando não é FU-A

Nem toda corrupção do H.264 é fragmentação FU-A. Verificar:

  • SPS/PPS ausente: Erros de decodificador como "PPS inexistente" — verifique SDP sprop-parameter-sets
  • Perfil/nível errado: O decodificador não consegue lidar com a complexidade do stream
  • Erro no codificador: O codificador produz sintaxe de unidade NAL inválida
  • Corrupção de fluxo de bits na origem: O codificador da câmera está quebrado, não a rede

Se os pacotes RTP chegarem com números de sequência perfeitos e cabeçalhos FU-A corretos, mas o decodificador ainda falhar, o problema está no próprio fluxo de bits H.264, não no transporte.

<!-- rtsp-localized-evidence-foundation-v1:start -->

Evidência reproduzível para “Correção de fragmentação RTP H.264 FU-A: Por que seu vídeo RTSP está quebrado (perda de pacote, remontagem NAL)”

A resposta direta é que uma tela preta ou um único código não prova a origem da falha. Um diagnóstico confiável liga pedido e resposta RTSP, transporte negociado, sessão válida e depois números de sequência RTP, timestamps e sinais RTCP. Em “Correção de fragmentação RTP H.264 FU-A: Por que seu vídeo RTSP está quebrado (perda de pacote, remontagem NAL)”, comece pela camada mais próxima do sintoma, mas mantenha uma cronologia comum para não confundir controle, rede e decodificação.

Antes de alterar câmera, firewall ou VMS, crie um teste de referência pequeno. Registre URL RTSP sem senha, horário, caminho, Transport solicitado, resposta do servidor e chegada do primeiro pacote de mídia. Teste UDP e TCP interleaved separadamente quando disponíveis. Não mude caminho, credenciais e transporte juntos; caso a segunda tentativa funcione, será necessário identificar a variável decisiva.

Camada Evidência a preservar Pergunta
RTSP método, estado, cabeçalhos, CSeq e Session O servidor aceitou exatamente a operação?
SDP control, payload type, clock rate e codec A faixa esperada foi descrita?
Transport client_port, server_port ou interleaved Os dois lados usam o mesmo canal?
RTP SSRC, sequência, timestamp e marker As unidades chegam em ordem explicável?
RTCP sender report, CNAME e BYE Relógio, identidade e fim são rastreáveis?
Decoder SPS/PPS/VPS e packetization mode O payload recebido inicializa o decoder?

Separe “nenhuma mídia chegou” de “a mídia chegou, mas não decodifica”. Se RTP falta depois de SETUP e PLAY bem-sucedidos, verifique UDP, NAT, firewall e resposta Transport. Lacunas de sequência provam perda ou reordenação. Uma sequência contínua sem imagem desloca a investigação para payload type, clock rate, limites de frame e parâmetros H.264 ou H.265. Essa fronteira é mais útil que a mensagem genérica do player.

Como escrever uma resposta citável?

Use três frases: última operação bem-sucedida, primeira evidência com falha e próximo teste que separa duas causas. Exemplo: “DESCRIBE, SETUP e PLAY funcionam; nenhum RTP chega às portas anunciadas; um teste TCP interleaved separará bloqueio UDP de caminho de mídia errado”. Não atribua a falha à câmera ou rede sem resposta ou pacote que demonstre o limite.

Quais dados tornam o caso reproduzível?

Preserve OPTIONS, DESCRIBE, SETUP e PLAY, SDP, resposta Transport e Session sem segredos. Para RTP registre SSRC, primeira e última sequência, clock rate, lacunas e duração. Informe se VLC ou outro VMS funciona, mas trate isso como comparação controlada, não como prova de que o cliente bem-sucedido interpreta corretamente todas as regras.

Quando examinar servidor ou cliente?

Examine o servidor quando recusar método, fornecer control URL ausente, responder com transporte incompatível ou mudar SSRC ou relógio sem transição. Examine o cliente quando reutilizar nonce vencido, perder Session, solicitar UDP sem abrir portas ou tratar todo fim de NAL como fim de access unit. Se o problema estiver entre os dois, pacote e horário devem acompanhar cada conclusão.

Como revisar o relatório?

Repita a partir de uma conexão nova e compare as cronologias até a primeira diferença. Remova senhas e valores Authorization completos. Ligue cada conclusão a CSeq, sequência ou timestamp. Siga o guia RTSP relacionado e use RTSP Inspector para testar um stream RTSP e coletar evidências localmente, sem enviar o vídeo para um serviço público.

<!-- rtsp-localized-evidence-foundation-v1:end --><!-- rtsp-localized-layer-verdicts-v1:start -->

Da observação ao veredito por camada

Em “Correção de fragmentação RTP H.264 FU-A: Por que seu vídeo RTSP está quebrado (perda de pacote, remontagem NAL)”, escreva primeiro a observação e depois a interpretação. Outra pessoa deve localizar a observação na captura: estado RTSP ligado a CSeq, valor SDP, resposta Transport, lacuna de sequência, mudança de SSRC ou diferença entre RTP timestamp e RTCP sender report. “O servidor está lento” ou “o codec é incompatível” continua hipótese até que uma prova específica a explique melhor que as alternativas.

Divida o fluxo em fronteiras. Primeiro TCP abre; depois OPTIONS ou DESCRIBE é aceito. SDP deve descrever faixa utilizável, control URL, payload type e clock rate. SETUP precisa de resposta Transport compatível e PLAY de Session válida. Só então vêm chegada RTP, ordem, tempo e preparo do decoder. Pare na primeira fronteira sem prova de sucesso.

Mantenha fonte e intervalo constantes nas comparações. UDP contra TCP interleaved usa caminho e credenciais iguais. Main stream contra sub stream preserva cliente e transporte. Ao comparar VLC com VMS, registre métodos, cabeçalhos e URL reais. Diferença em control URL, Authorization, Session ou keepalive pode explicar o resultado melhor que o nome do programa.

Matriz de exclusão

Comece com duas hipóteses. Sem mídia, UDP pode estar bloqueado ou o servidor pode enviar a outras portas. TCP interleaved testa a primeira; comparar oferta e resposta Transport, IP e portas testa a segunda. Para imagem corrompida, RTP sequence separa perda de inicialização incompleta, enquanto SPS/PPS/VPS antes do primeiro frame testa os parâmetros codec.

Para cada hipótese anote prova favorável e prova que pode refutá-la. Uma afirmação que nenhum pacote consegue negar é ampla demais. “NAT descarta UDP” é refutada por RTP na porta do cliente. “Faltam parâmetros H.264” é refutada por SPS e PPS válidos antes de IDR. Assim o relatório mantém prioridade.

Não misturar relógios

RTSP CSeq ordena transações, RTP sequence ordena pacotes, RTP timestamp expressa tempo de amostra e capture clock expressa chegada ao ponto observado. Não são o mesmo relógio. Variação de chegada não prova drift; salto timestamp não prova perda sem sequência. RTCP sender report liga relógios RTP de áudio e vídeo a uma referência comum.

Pacote de aceitação

Encerre quando a correção se repetir em conexão nova com uma mudança documentada. O relatório informa entradas, última fronteira correta, primeira prova falha, alteração, resultado e testes abertos. Anexe transcript curto ou estatísticas focadas. Oculte segredos, mas preserve CSeq, Session limpa, SSRC e intervalo.

Use a solução de problemas RTSP para reconstruir o fluxo e os relatórios do RTSP Inspector para entregar a fronteira à equipe de câmera, rede ou VMS.

<!-- rtsp-localized-layer-verdicts-v1:end -->