Desenvolvendo um analisador de TS usando Python (parte 1)

Introdução
O MPEG‑2 Transport Stream (TS) é um formato de contêiner digital usado para a transmissão e o armazenamento de áudio, vídeo e dados. Ele foi definido originalmente pela norma ISO/IEC 13818‑1 e é utilizado por sistemas de televisão digital como DVB, ATSC e ISDB‑T. Um transport stream consiste numa sequência síncrona de pacotes com 188 bytes cada; cada pacote inclui um cabeçalho de 4 bytes, um campo opcional de adaptação e uma carga útil de até 184 bytes[1]. O cabeçalho contém um byte de sincronismo com valor fixo 0x47, um identificador de pacote (Packet Identifier – PID) de 13 bits e um contador de continuidade de 4 bits, além de indicadores que assinalam a presença de campo de adaptação e de carga útil[2]. O sincronismo com o byte 0x47 e o tamanho fixo de 188 bytes permitem que receptores identifiquem rapidamente os limites de pacotes e reconstruam os fluxos multiplexados.
A estrutura do TS também define tabelas de sinalização denominadas Program Specific Information (PSI). A Program Association Table (PAT) relaciona todos os programas disponíveis no stream; cada entrada associa um número de programa a um PID no qual está localizada a Program Map Table (PMT) correspondente[3]. A PMT, por sua vez, descreve os fluxos elementares de um programa (vídeo, áudio, legendas etc.), informando o PID e o tipo de cada stream[4]. A transmissão periódica dessas tabelas é obrigatória para que os receptores possam decodificar corretamente os serviços multiplexados.
Outro campo importante do TS é o Program Clock Reference (PCR). Esse valor de 42 bits é inserido no campo de adaptação de pacotes cujo PID está indicado no campo PCR PID da PMT; ele serve para sincronizar áudio e vídeo no decodificador. Segundo a norma, os primeiros 33 bits do PCR são baseados em um relógio de 90 kHz e os 9 bits restantes em um relógio de 27 MHz, e o valor deve ser transmitido pelo menos a cada 100 ms com precisão melhor que ±500 ns[1].
A análise de TS exige, além do entendimento da estrutura, a verificação de conformidade com diretrizes como o relatório ETSI TR 101 290. Esse relatório define indicadores de primeira prioridade essenciais para garantir a decodificação: perda de sincronismo (TS sync loss), erro no byte de sincronismo, erro na PAT (ausência ou formato incorreto), erro no contador de continuidade, erro na PMT e PIDs não referenciados[2]. Um analisador de TS precisa monitorar esses parâmetros e apontar falhas para que transmissores e receptores mantenham a qualidade de serviço.
O objetivo deste artigo é mostrar como desenvolver, em Python, um analisador de TS com interface gráfica. Como estudo de caso, utilizaremos o projeto fornecido em anexo, ilustrando passo a passo como ler pacotes, construir as tabelas PSI, calcular métricas do TR 101 290 e apresentar os resultados em uma GUI desenvolvida com PyQt5.
Conceitos teóricos do padrão MPEG‑TS
Estrutura do pacote TS
Um pacote MPEG‑TS possui tamanho fixo de 188 bytes. O primeiro byte do cabeçalho é o sync byte com valor 0x47. A seguir vêm diversos campos: o PID (identificador de pacote, 13 bits), o contador de continuidade (4 bits), o bit Payload Unit Start Indicator (PUSI) e flags que indicam a presença de campo de adaptação e/ou de carga útil[1]. O manual da TSDuck descreve esses campos: PID (13 bits), contador de continuidade (4 bits), PUSI, controle de escrambling, flag de campo de adaptação e flag de payload. Quando o campo de adaptação está presente, ele pode conter um PCR, dados privados ou bytes de preenchimento[1]. A combinação de cabeçalho, campo de adaptação e payload totaliza exatamente 188 bytes.Informação específica de programa (PSI)
A PSI define quatro tabelas principais: PAT, PMT, CAT e NIT. As tabelas CAT e NIT estão relacionadas ao acesso condicional e informações de rede; aqui focaremos na PAT e na PMT.
- PAT (Program Association Table) – lista todos os programas disponíveis. Cada entrada contém o número do programa (16 bits) e o PID da PMT correspondente. O programa 0 é reservado para apontar a NIT; se não existir NIT no stream, utiliza‑se por convenção o PID 0x0010. As seções da PAT são transmitidas sempre no PID 0x0000.
- PMT (Program Map Table) – para cada programa listado na PAT, existe uma PMT. A tabela contém o campo PCR PID, indicando qual PID carrega o PCR, e uma lista de fluxos elementares com seus stream type e PIDs. Com base nessa tabela, o receptor sabe quais PIDs correspondem ao vídeo, ao áudio, a legendas ou a dados associados ao serviço.
Essas tabelas são transmitidas periodicamente no TS. A ausência de uma PAT ou de uma PMT impede a decodificação, motivo pelo qual esses erros estão entre os indicadores de primeira prioridade do TR 101 290.
Program Clock Reference (PCR) e sincronismo
O PCR é um valor de 42 bits transmitido em pacotes cujo PID está indicado na PMT. Ele é usado pelo decodificador para gerar um relógio de sistema (STC) que sincroniza áudio e vídeo. Conforme explicado anteriormente, os primeiros 33 bits do PCR se baseiam em um relógio de 90 kHz e os 9 bits restantes em 27 MHz; a norma recomenda que o PCR seja transmitido pelo menos a cada 100 ms e que o erro máximo permitido seja de ±500 ns. Erros de repetição ou precisão do PCR são monitorados como indicadores de segunda prioridade no TR 101 290[1].
Indicadores de conformidade (TR 101 290)
O documento ETSI TR 101 290 recomenda três níveis de prioridade para a avaliação do transport stream. Na primeira prioridade encontram‑se os erros que impedem a decodificação e que devem ser monitorados continuamente:
- Perda de sincronismo (TS sync loss) – ocorre quando dois bytes de sincronismo consecutivos são corrompidos; caracteriza uma falha grave e suspende a validade dos demais indicadores.
- Erro no byte de sincronismo – o indicador Sync byte error é acionado sempre que o byte no início de um pacote não for 0x47.
- Erro na PAT – a tabela PAT (PID 0x0000) deve aparecer pelo menos a cada 0,5 s; sua ausência ou estrutura incorreta impede que os programas sejam localizados.
- Erro no contador de continuidade – o contador de continuidade (4 bits) deve incrementar de forma cíclica (mod 16) a cada pacote com payload; ordens incorretas, duplicações ou perda de pacotes provocam este erro.
- Erro na PMT – a PMT de cada programa deve aparecer no PID indicado pela PAT ao menos a cada 0,5 s; ausência ou erro torna a decodificação impossível.
- Erro de PID – PIDs presentes no TS mas não referenciados por nenhuma PMT são considerados anômalos.
Erros de segunda prioridade abrangem parâmetros de transporte, CRC, PCR e PTS; a terceira prioridade refere‑se principalmente à sinalização de rede e a questões de buffer. Neste artigo focaremos nos indicadores de primeira prioridade.
Descrição do projeto e ferramentas
Arquitetura geral
O arquivo ts_analyser_gui.py fornece uma aplicação gráfica escrita em Python que emula o layout de uma ferramenta comercial de análise de TS. A aplicação utiliza PyQt5 para a interface e está organizada em duas classes principais:
- TSAnalyserOptionsDialog – diálogo modal no qual o usuário seleciona o arquivo TS a analisar, escolhe a origem do stream (arquivo, ASI ou rede) e define o tipo de análise e de padrão. Ao escolher um arquivo, o diálogo calcula uma taxa de bits aproximada com base no tamanho do arquivo. O botão "Start" chama um callback que inicia a análise.
- MainWindow – janela principal com três áreas: uma árvore de serviços à esquerda, abas de informação PSI/SI à direita e uma barra de ferramentas com botão "Select Source". As abas incluem a visualização das tabelas PSI, resultados do TR 101 290, estatísticas de PCR, bitrates, dispersão de PID e informações de fluxos elementares. A classe contém métodos auxiliares para preencher a árvore com dados de demonstração e construir as abas.
O projeto fornece apenas a interface gráfica; a funcionalidade de parsing é delegada a um módulo externo chamado transport_stream_parser. Caso o módulo não esteja disponível, a análise real é desativada, mas a GUI permite navegar nas estruturas de demonstração.
Dependências
Para executar o analisador, são necessárias as seguintes dependências:
- Python 3.10+ – linguagem de programação usada.
- PyQt5 – biblioteca para criação de interfaces gráficas.
- Matplotlib (opcional) – utilizada neste artigo para gerar diagramas ilustrativos.
- TransportStreamParser – módulo responsável por parsear o TS e extrair PAT/PMT, fluxos elementares e outras informações. Ele não faz parte do arquivo em anexo e deve ser implementado ou incorporado conforme a necessidade.
Desenvolvimento do analisador de TS
Nesta seção apresentamos o passo a passo da implementação, explicando trechos representativos do código fornecido. O foco é mostrar como ler pacotes TS, extrair as tabelas PSI, calcular métricas de conformidade e apresentar os resultados ao usuário.
1. Leitura e validação de pacotes TS
A função compute_analysis é responsável por varrer o arquivo TS e coletar estatísticas. O código abre o arquivo em modo binário e lê blocos de 188 bytes em um laço:

Cada pacote é verificado quanto ao sync byte. Caso ele não seja 0x47, conta‑se uma perda de sincronismo. Em seguida computam‑se o PID, o controle de campo de adaptação e o contador de continuidade. O campo adaptation_field_control indica se o pacote contém apenas payload (1), apenas adaptação (2) ou ambos (3). O contador de continuidade é utilizado para identificar perda ou duplicação de pacotes; para cada PID espera‑se que o valor incremente módulo 16 conforme pacotes consecutivos.
Se o campo de adaptação estiver presente (valores 2 ou 3), o código lê o tamanho do campo e verifica se o flag de PCR (bit 4 do campo de flags) está ativo. Caso esteja, extrai‑se o PCR de 42 bits e armazenam‑se os valores para cálculo de estatísticas:

2. Classificação por categoria
Após extrair o PID, o analisador classifica cada pacote em cinco categorias: vídeo, áudio, null, psi_si e others. Para isso, define‑se um conjunto de códigos stream_type (0x01, 0x02, 0x1B para vídeo; 0x03, 0x04, 0x0F para áudio) e, a partir das informações da PMT obtidas pelo TransportStreamParser, constrói‑se uma lista de PIDs de áudio e vídeo. O PID 0x1FFF é reservado para pacotes nulos [1]. PIDs de tabelas PSI incluem 0x0000 (PAT), 0x0010 (NIT), 0x0011 (SDT) e os PIDs das próprias PMTs. Qualquer PID não classificado nessas listas é contabilizado como others. O analisador conta o número de pacotes em cada categoria e calcula a taxa de bits multiplicando a porcentagem de pacotes pelo bitrate total estimado. Essa informação é exibida na aba "Bitrates" com barras de progresso coloridas.
3. Verificação dos indicadores TR 101 290
Ao final da varredura, o método compute_analysis cria uma lista tr_indicators com os contadores de erros de primeira prioridade:
- TS Sync Loss – número de pacotes em que o sync byte não é 0x47.
- Sync Byte Error – neste código coincide com o indicador anterior; a implementação diferencia apenas no nome.
- PAT Error – definido como 1 se o parser não encontrou nenhum programa na PAT; a ausência da tabela impede a decodificação de programas.
- Continuity Count Error – incrementado sempre que o contador de continuidade de um PID não corresponde ao esperado.
- PMT Error – número de programas presentes na PAT mas sem PMT correspondente.
- PID Error – contagem de PIDs que não se enquadram em áudio, vídeo, PSI/SI ou pacote nulo (0x1FFF). Estes PIDs não referenciados configuram um erro de acordo com o TR 101 290.
Para cada indicador com valor diferente de zero, a GUI destaca a linha correspondente em vermelho na aba "TR 101 209" (nome usado na interface). O usuário pode assim identificar rapidamente qual tipo de falha ocorreu.
4. Dispersão de PIDs e continuidade
Além dos contadores de erros, o analisador calcula a dispersão do PID 0x0000 (PAT). Ele registra todos os índices de ocorrência desse PID e calcula a diferença entre posições consecutivas para determinar a distribuição dos intervalos. Uma dispersão regular indica que a PAT está sendo transmitida de forma homogênea; intervalos muito grandes ou irregulares podem sinalizar problemas na multiplexação. A aba "PID Dispersion" apresenta, para o PID analisado, o número de pacotes recebidos, os intervalos mínimo/máximo, a média e uma tabela com a contagem de cada intervalo.
5. Estatísticas de PCR e PES
Os valores de PCR coletados permitem calcular estatísticas como diferença mínima, máxima e média entre PCRs consecutivos. Essa informação auxilia na verificação de jitter e precisão do relógio, parâmetros de segunda prioridade conforme o TR 101 290.
O analisador também detecta cabeçalhos PES (prefixo 0x000001) em PIDs de áudio e vídeo. Para cada PID registra o número de PES encontrados e, quando possível, o Presentation Time Stamp (PTS) do primeiro quadro. Essas estatísticas são exibidas na aba "ES Info" e ajudam a correlacionar o fluxo elementar com a sinalização da PMT.
6. Interface gráfica e apresentação dos resultados
Após concluir a análise, o método run_analysis repovoa a árvore de serviços com os programas e fluxos elementares extraídos pelo parser. Cada nó exibe o PID e uma descrição legível obtida pela função stream_type_description, que associa códigos stream_type a descrições (por exemplo, 0x1B → H.264/AVC). A primeira aba do painel direito mostra a hierarquia PSI (PAT e PMT); as demais abas apresentam os resultados de análise: indicadores do TR 101 290, barras de bitrates, estatísticas de PCR, dispersão de PIDs e informações de ES. A aba "T2‑MI" está vazia no código disponível, mas demonstra como integrar outras análises futuras.
Metodologia passo a passo
Para desenvolver um analisador de TS semelhante, recomenda‑se o seguinte roteiro, relacionando teoria e prática:
- Compreender o padrão MPEG‑TS. Estude a estrutura dos pacotes, campos de cabeçalho e tabelas PSI/PMT. Utilize documentos como o manual da TSDucke o TR 101 290 para conhecer os indicadores de conformidade.
- Definir dependências e ambiente. Instale Python, PyQt5 e um parser de TS. Opcionalmente use bibliotecas como matplotlib para gerar gráficos.
- Construir a interface gráfica. Use o Qt Designer ou construa manualmente uma janela com árvore de serviços e diferentes abas para as informações de PSI, bitrates, PCR e dispersão de PIDs. Crie um diálogo modal para a seleção do arquivo TS.
- Ler o arquivo TS. Abra o arquivo em modo binário e leia pacotes de 188 bytes em um laço. Verifique o sync byte (0x47) e, quando incorreto, conte um erro de sincronismo. Extraia o PID e o contador de continuidade conforme indicado no cabeçalho.
- Analisar o campo de adaptação. Quando presente, verifique se o PCR está contido no pacote. Extraia seu valor de 42 bits e calcule diferenças entre PCRs para monitorar jitter e precisão.
- Classificar os pacotes. A partir das PMTs, mantenha conjuntos de PIDs de áudio e vídeo e os PIDs de tabelas PSI. Para cada pacote, classifique‑o em vídeo, áudio, null (0x1FFF), PSI/SI ou outros, contabilizando a ocorrência de cada categoria. Use esses dados para calcular bitrates de cada serviço.
- Verificar erros de continuidade. Para cada PID, registre o valor do contador de continuidade e certifique‑se de que ele incrementa módulo 16; inconsistências indicam perda ou duplicação de pacotes.
- Construir as tabelas PSI. Utilize um parser para ler PAT e PMT e construir uma estrutura de dicionários onde cada programa aponta para o seu PID de PMT e lista de fluxos elementares.
- Calcular indicadores do TR 101 290. Com base nas estatísticas coletadas, conte erros de sincronismo, PAT, continuidade, PMT e PIDs não referenciados. Calcule ainda a dispersão de PIDs e as estatísticas de PCR.
- Exibir os resultados na GUI. Preencha as abas da interface com tabelas e gráficos que mostrem os erros, bitrates, dispersão e informações de ES. Destaque erros com cores e forneça descrições claras para que o usuário identifique rapidamente problemas.
A figura abaixo resume o fluxo de execução do analisador.

Discussão dos resultados
O analisador proposto fornece uma visão abrangente do transport stream. Ao classificar os pacotes por categoria, é possível visualizar a porcentagem de banda ocupada por vídeo, áudio, dados de sinalização (PSI/SI), pacotes nulos e outras classes. Esse diagnóstico auxilia na verificação de bitrate shapers e multiplexadores. Os indicadores de primeira prioridade permitem detectar falhas que impossibilitam a decodificação. Por exemplo, uma alta contagem de erros de sincronismo sugere corrupção do sinal ou perda de alinhamento na leitura do arquivo. A ausência de PAT ou PMT indica que o stream está incompleto ou corrompido. Erros de continuidade refletem perda de pacotes ou falhas de transporte – o TR 101 290 recomenda que esses parâmetros sejam monitorados continuamente. A dispersão do PID 0x0000 (PAT) evidencia se a tabela está sendo transmitida em intervalos regulares. No código de exemplo, gaps e ocorrências são calculados e exibidos. Uma dispersão muito irregular pode indicar problemas na multiplexação ou na ferramenta de geração de TS. As estatísticas de PCR (diferenças entre valores consecutivos) permitem observar a estabilidade do relógio; diferenças grandes podem levar a erros de sincronismo, conforme apontado no TR 101 290.
Conclusão
Desenvolver um analisador de TS em Python é uma tarefa viável e didática para compreender os mecanismos de transporte de conteúdo em televisão digital. Este artigo explorou a estrutura dos pacotes MPEG‑TS, as tabelas PSI (PAT/PMT) e os indicadores de conformidade do TR 101 290. A implementação apresentada mostrou como ler e verificar pacotes, extrair sinalização, calcular métricas de integridade e apresentar os resultados em uma interface amigável.
Integrar um parser de TS e estender a análise para outros padrões (segunda e terceira prioridades do TR 101 290, ATSC A/78a, T2‑MI) são caminhos naturais para evolução da ferramenta. A utilização de bibliotecas como PyQt5 permite criar interfaces profissionais, enquanto Python oferece recursos para manipulação binária e processamento de dados. Compreender esses conceitos é essencial para engenheiros de transmissão e desenvolvedores de soluções de monitoramento.
Para mais detalhes visite o repositório OTA-TS: https://github.com/aragonxpd154/OTA-TS, lá possui um exemplo de analisador de TS simples.

Referencias:
[1] O artigo da Wikipédia "MPEG transport stream" explica que o PCR é transmitido no campo de adaptação e que seus 33 primeiros bits são baseados em 90 kHz, enquanto os 9 bits restantes provêm de um relógio de 27 MHz; o desvio máximo permitido no PCR é ±500 ns.
[2] O TR 101 290 lista os indicadores de primeira prioridade: perda de sincronismo, sync byte diferente de 0x47, ausência ou erro de PAT, erro no contador de continuidade, ausência ou erro de PMT, e PIDs que não aparecem em nenhuma PMT. Cada indicador possui precondições e limites de repetição definidos em ISO/IEC 13818‑1.
[3] Ver An introduction to MPEG‑TS – all you should know before using TSDuck, versão 9, onde se descreve que um TS é composto por pacotes de 188 bytes com cabeçalho de 4 bytes, campo de adaptação opcional e payload de até 184 bytes. O documento também informa que um TS pode multiplexar até 8192 fluxos elementares, cada um identificado por um PID de 13 bits.
[4] No mesmo manual da TSDuck é explicado que o cabeçalho de 4 bytes inclui o sync byte (0x47), o PID (13 bits), o contador de continuidade (4 bits), o bit Payload Unit Start Indicator (PUSI), flags de controle de escrambling, e indicadores para a presença de campo de adaptação e de payload.
[5] A PAT é repetida no PID 0 e contém uma lista de serviços com o seu service id e o PID da PMT de cada serviço. Essa descrição aparece no manual da TSDuck, no capítulo sobre PSI.
[6] A PMT fornece um campo PCR PID apontando o PID que carrega o PCR e lista os fluxos elementares de um serviço com seus tipos e PIDs. A definição detalhada da PMT encontra‑se no manual da TSDuck.
[7] Ainda de acordo com a TSDuck, o campo de adaptação pode transportar o Program Clock Reference (PCR/OPCR), dados privados e bytes de preenchimento ("stuffing").
[8] Ainda de acordo com a TSDuck, o campo de adaptação pode transportar o Program Clock Reference (PCR/OPCR), dados privados e bytes de preenchimento ("stuffing").
[9] O TR 101 290 especifica que erros de segunda prioridade incluem falhas de repetição e precisão do PCR, bem como discrepâncias no PTS/DTS, CRC e buffer.