解析TS流PAT和PMT 代码

合集下载

ts码流结构分析与监测

ts码流结构分析与监测

TR101-290三级错误、PSI/SI、PCR分析描述DVB系统测量标准之一TR 101-290定义的三个优先级,是码流监测的一项主要内容。

通过这三个优先级的监测,可以检验被监测的码流是否符合MPEG-2和DVB标准。

这三个优先级都包含许多不同的参数。

一、TR 101-290的第一优先级1、同步错误(TS Sync Loss)同步错误是衡量传输流质量的最重要的指标。

传输流失去同步,表明传输过程中有一部分数据丢失,将直接影响画面显示的质量。

严重的同步丢失现象则表明传输中断,同步字节出现错误。

2、同步字节错误(Sync Byte Error)同步字节错误和同步错误的区别在于传输数据包长为188字节或204字节,但同步字头的标准值为0×47,当出现同步字节错误时,同步字头的值为其他数值,表明在传输过程中部分数据出现错误,可能导致接收时出现马赛克,严重时导致解码器和DISPLAY软件解不出信号。

3、包识别丢失(PID Mssing)检测数据流中各套电视节目的图像/声音数据是否正确。

PID丢失,将导致DISPLAY软件无法正确解码这套节目。

4、节目相关表(PAT)PAT在DVB标准中用于指示当前节目及其在数据流中的位置。

PA T丢失,将导致解码器无法搜索到相应的节目包,使得接收端收不到图像。

如果PA T超时,则解码器工作时间延长。

5、节目对照表(PMT)PMT在DVB标准中用于指示该套节目视/音频数据在传输流中的位置。

某一套节目的PMT丢失,将导致解码器找不到该套节目视/音频数据,使得接收端收不到图像或声音。

PMT 传输超时,DISPLAY软件无法显示这套节目。

6、连续计数错误(Cont Count Error)对于每一套节目的视/音频数据包而言,连续计数错误是一个很重要的指标。

传输流包头连续计数不正确,表明当前传输流有丢包、错包、包重叠等现象,将导致解码器或DISPLAY 软件不能正确解码,图像出现马赛克等现象。

[ts码流分析]ETSITR101290监测三种级别错误

[ts码流分析]ETSITR101290监测三种级别错误

[ts 码流解析 ] ETSI TR101 290 监测的三种级别错误对于码流解析仪所供应 ETSI TR101 290 监测的三种级别错误,接收端将会出现以下现象。

级别 错误种类接收端现象同步丧失错 黑屏、静帧和马赛克、画面不流畅现 一象级 同步字节错 黑屏、静帧和马赛克、画面不流畅现 错 象误PAT 错误 找寻不到节目或节目找寻错误 连续计数错 马赛克PMT 间隔错误 找寻不到节目或节目找寻错误 PMT 加扰错误 找寻不到节目或节目找寻错误PID 错误 黑屏、静帧、马赛克等所有异常现象 传达错误黑屏、静帧和马赛克、画面不流畅现象二 CRC 错误黑屏、静帧和马赛克、画面不流畅现 级象错 PCR 间隔错误 视音频不相同步或图象颜色丧失 误PCR 非连续标志错 视音频不相同步或图象颜色丧失 PCR 抖动错误 视音频不相同步或图象颜色丧失 PTS 错误音视频不相同步TS 包加扰错 只对加扰节目有影响,为略微错误 CAT 错误无法正确办理 CA 信息,为略微错误NIT ID 错误 无异常现象,码流解析仪的三级错误 三NIT 间隔错误为略微错误。

级 NIT 其他错误错SI 重复率错误缓冲器错非指定 PID 错SDT ID 错SDT 当前间隔错SDT 其他间隔错 EIT ID 错EIT 当前间隔错 EIT 其他间隔错EIT PF 错 RST 错误TDT 错误空缓冲器错误数据延缓错误TR101-290: DVB系统测量标准TR101-290: DVB系统测量标准。

TR 101-290定义的三个优先级,是码流监测的一项主要内容。

经过这三个优先级的监测,能够检验被监测的码流可否吻合MPEG-2和DVB标准。

这三个优先级都包含好多不相同的参数。

PSI/SI: 数字电视业务信息,由 PSI 和 SI 两局部组成。

PSI 是 MPEG-2规定的,它由PAT 、 PMT 、CAT 和 NIT 4个表组成,其中PAT 、PMT 表最为重要。

PMT和PAT

PMT和PAT

PMT (Program Map Table) 节目映射表Meaning of PMT - "Program Map Table". A Program Specific Information table that supplies basic information about the services present in an Moving Pictures Experts Group 2 (MPEG-2) transport stream. The PMT lists all of the packet IDs (PID) for packets containing elements of a particular program such as audio, video, aux data, and Program Clock Reference (PCR). Packets in the same elementary stream all have the same PID and the decoder can select the elementary stream or streams it wants and reject the remainder. Also carried in the metadata is the information that some programs will be open and some may be subject to encryption节目映射表:数字电视与传统模拟电视节目选择的方式完全不同,传统电视的每一个频道对应一个节目,只要调到相应的频率,就可以看到节目。

而在数字电视信号中,一路码流对应多路节目,使用复用技术就可以做到了。

一个物理的频道只能给出包含多路节目的一路传输流。

要观看其中的某一路节目,还必须从该传输流中提取出该路节目的压缩包,然后再进行解码。

ts码流结构分析

ts码流结构分析

ts码流结构分析TS(Transport Stream)是一种常用的音视频码流传输格式,用于在数字广播系统和互联网传输中对音视频数据进行分组和传输。

TS码流结构分析指的是对TS码流的组成部分进行分析,了解各部分的作用和关系。

以下是对TS码流结构的详细分析。

TS码流由多个188字节的包(Packet)组成,每个包都包含了一部分音视频数据。

一个TS包由4个字节的同步字节(Sync Byte)开头,用于标识包的开始。

接下来的4位为传输误码纠正(Error Correction)信息,用于保证传输数据的完整性和准确性。

再接下来的1位为负荷优先级(Payload Unit Start Indicator),用于标识包中是否包含了新的数据单元。

然后是13位的PID(Packet Identifier),用于标识包中所包含的数据单元的类型。

接下来的2位为传输加密(Transport Scrambling Control),用于指定包中数据的加密方式。

再接下来的2位为控制报文(Adaptation Field Control),用于指定包中的控制信息是否存在。

最后的184字节为有效数据(Payload),用于传输音视频数据。

每个TS包中的PID用于标识包中所包含的数据单元的类型,常见的PID值有0x0000(PAT:Program Association Table)、0x0001(CAT:Conditional Access Table)、0x0010(NIT:Network Information Table)、0x0011(SDT:Service Description Table)等。

PAT表包含了整个TS流的所有节目以及对应的PMT(Program Map Table)的PID值。

CAT表用于传递整个TS流中的加密和访问控制信息。

NIT表用于传递整个TS流中的网络信息,包括网络ID和传输参数。

SDT表用于传递整个TS流中的节目信息,包括节目名称和节目号码。

解析pat和pmt代码

解析pat和pmt代码

#include <stdio.h>#include <stdlib.h>#include<string.h>int parse_TS(unsigned char *buffer, int FileSize);void parse_PAT(unsigned char *buffer, int len);unsigned char* Find_PMT(unsigned short pmt_pid);void parse_PMT(unsigned char *buffer, int len, unsigned short pmt_pid); void Read_Ts_Packet(FILE *file_handle ,unsigned char *packet_buf, int len); void pronum_pmtid_printf();void printf_prog_list();typedef struct {unsigned short program_num; //节目编号unsigned short pmt_pid; //节目对应的PMT表的PID}PROGRAM;typedef struct{unsigned char stream_type; //节目元素包类型unsigned short elementary_pid; //元素对应的pid}PRO_LIST;PROGRAM programs[10] = { {0,0} };unsigned int num = 0; //总的节目数PRO_LIST program_list[20] = { {0,0} };unsigned int p_list_num = 0;FILE *file_handle;unsigned int FileSize = 0;int main(){unsigned char buffer[188] = {0};unsigned char *pmt_buffer = NULL;unsigned int i = 0, j =0, ret = 0;file_handle = fopen("435.ts", "rb");if(file_handle == NULL){printf("open file error!\n");return 0;}elseprintf("open file success!\n");fseek( file_handle, 0, SEEK_END );FileSize = ftell( file_handle ); //求文件的长度(字节)。

TS流解析源码

TS流解析源码
/* TS流分析器*/
CTsParser::CTsParser()
{
m_pat_filter = NULL;
m_pat_buf = NULL;
m_pat_size = 0;
m_sdt_filter = NULL;
m_bufsize = 12*188*1024;
m_head = 0;
m_tail = 0;
if( spi.pmt_buf )
OCG_FREE( spi.pmt_buf );
position = m_pmtmap.GetNext( &pmt_pid, &spi, position );
}
m_pmtmap.RemoveAll();
/*清除SDT信息*/
position = m_sdtmap.GetFirst( &serv_id, &sdt );
p += 3;
memcpy( &sdt_multilingual_des->sdt_service_provider_name, p + 1, *p );
sdt_multilingual_des->sdt_service_provider_name[ *p ] = 0;
#include "Xml.h"
#include "osfile.h"
#include "TsParser.h"
#include "OcgMem.h"
#include "MptsTransfer.h"
#include "main.h"
#include "osfile.h"

传送流(TS)的基础知识

传送流(TS)的基础知识

传送流(TS)的基础知识数字电视的TS包和TS流的组成和功能综合考虑⼏下⼏个因素:(1)包的长度不能过短,否则包头开销所占⽐例过⼤,导致传输效率下降(2)包的长度不能过长,否则在丢失同步的情况下恢复同步的周期过长,导致较多的信息丢失(3)其他环境相适配,如纠错编码,宽带⽹等。

TS包按功能分为链接头,适配域,净荷。

链接头的长度固定,4个字节适配域的长度从0字节到184字节可变,可以没有,也可以扩展到整个TS包净荷数据的长度从0字节到184字节可变。

整个TS流是由许多长度为188字节的TS包周期性的排列⽽形成的。

ts包头包含4个字节的内容,主要负责TS包的同步、各种ES流的表⽰、TS包传输差错的检测和条件接收等功能。

(1)包同步(syn_bate)是包中的第⼀个字节,TS包以固定的8bit的同步字节开始,所有的TS传送包,同步字都是唯⼀的OX47,⽤于建⽴发送端和接收端包的同步。

(2)包差错指⽰(transport_error_indicator)⽤于从解码器向分接器指⽰传输误码。

若这个⽐特被设置,表⽰此TS包中所携带的净荷信息有错误,⽆法使⽤。

(3)净荷单元起始指⽰(payload_uint_start_indicator)标志PES包头以及包含节⽬特定信息的表(PMT,PAT)的头是否出现在该包中,在失步后的重新同步中起着重要的作⽤。

(4)传送优先级(transport_priority)⽤于表⽰包中含有重要数据,应予以优先传送。

(6)加扰控制(transport_scrambling_control)传送信息通过加⼊扰码来加密,各个基本码流可以独⽴进⾏加扰。

加扰控制字段说明TS包中的净荷数据是否加扰。

如果加扰,标志出解扰的密匙。

(5)包标识符PID(pid)PID是识别TS包的重要参数,⽤来识别TS包所承载的数据。

在TS码流⽣成时,每⼀类业务(视频,⾳频,数据)的基本码流均被赋予⼀个不同的识别号PID,解码器借助于PID判断某⼀个TS包属于哪⼀类业务的基本码流。

便携式IPTV测试仪TS码流解析的实现

便携式IPTV测试仪TS码流解析的实现

便携式IPTV测试仪TS码流解析的实现便携式IPTV测试仪是一种用于测试和分析IPTV系统性能的设备。

它可以通过对传输流中的TS码流进行解析和分析,提供关于传输质量、视频质量、音频质量等方面的信息。

下面将介绍便携式IPTV测试仪TS码流解析的实现过程。

首先,便携式IPTV测试仪需要具备对TS码流解析的功能,这需要通过硬件和软件的结合来实现。

硬件方面,测试仪需要具备高性能的处理器和足够的存储空间来处理和存储大量的数据。

同时,测试仪需要具备支持高速数据传输的接口,例如千兆以太网接口。

软件方面,测试仪需要具备强大的编解码功能,能够对TS码流进行解析和分析。

在实现过程中,首先需要从IPTV系统中获取到传输的TS码流。

通常,这可以通过测试仪的网络接口连接到IPTV系统中的交换机或路由器上,然后通过ARP、DHCP等协议获取到IPTV系统分配给测试仪的IP地址和相关配置信息。

获取到IP地址后,测试仪就可以通过该地址与IPTV系统建立TCP/IP连接,并获取到传输的TS码流。

获取到TS码流后,测试仪需要对其进行解析。

TS码流是一种多路复用的码流格式,其中包含多个音视频流、字幕、EPG等信息。

测试仪需要通过解析TS码流,将其中的各个流分离出来,并进行相应的解码处理。

这可以通过测试仪上的解码器来实现,解码器可以将TS码流中的音视频数据进行解码,并输出为可播放的音视频信号。

在解析TS码流的过程中,测试仪可以获取到各个流的相关信息。

例如,测试仪可以通过解析PAT(Program Association Table)和PMT (Program Map Table)信息,获取到TS码流中包含的节目信息。

同时,测试仪还可以通过解析PCR(Program Clock Reference)信息,获取到TS码流的传输时钟参考,用于判断流的同步状态。

除了对TS码流的解析,测试仪还可以对解析后的音视频数据进行质量分析。

通过分析视频数据的码率、帧率、分辨率等参数,测试仪可以评估视频的质量。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<stdio.h>#include<stdlib.h>#include<string.h>#define ts_path "/home/huohuo/huangwork/work/birds.ts" //TS文件的绝对路径void Read_Ts_Packet(FILE *file_handle,unsigned char *packet_buf,int len); //读一个TS流的packetint parse_TS(unsigned char *buffer,int FileSize); //分析TS流,并找出PA T的PID和PAT的tablevoid parse_PAT(unsigned char *buffer,int len); //分析PA T,并找出所含频道的数目和PMT的PIDvoid pronum_pmtid_printf(); //打印PMT的PID unsigned char* Find_PMT(unsigned short pmt_pid); //找出PMT的tablevoid parse_PMT(unsigned char *buffer,int len,unsigned short pmt_pid); //解析PMT,找出其中的Video和Audio的PIDvoid printf_program_list(); //打印PMT table中包含的stream的类型和PIDunsigned char* Find_video_audio(unsigned short program_pid,unsigned char type); //找出Video或者Audio的tabletypedef struct{unsigned short program_num; //program's numunsigned short pmt_pid; //}PROGRAM;typedef struct{unsigned char stream_type;unsigned short elementary_pid;}PRO_LIST;PROGRAM programs[10] = {{0,0}}; //用来存储PMT的PID和数量unsigned int num = 0; //total programPRO_LIST program_list[10] = {{0,0}}; //用来存储PMT中stream的类型和PIDunsigned int program_list_num = 0;FILE *file_handle; //指向TS流的指针unsigned int FileSize = 0;int main(){unsigned char buffer[188] = {0};unsigned char *pmt_buffer, *Video_or_Audio_buffer;unsigned int i=0,j=0,ret=0;pmt_buffer = (unsigned char*)malloc(sizeof(char)*188); //给buffer分配空间memset(pmt_buffer,0,sizeof(char)*188);//清空bufferVideo_or_Audio_buffer = (unsigned char*)malloc(sizeof(char)*188);memset(Video_or_Audio_buffer,0,sizeof(char)*188);file_handle = fopen(ts_path,"rb+"); //以二进制方式打开TS文件if(NULL == file_handle) //判断是否打开文件{perror("fopen");printf("open file error!\n");return 0;}elseprintf("open file success!\n");fseek(file_handle,0,SEEK_END); //指针file_handle将以SEEK_END位置偏移0个位置,即将指针移动到文件尾FileSize = ftell(file_handle); // 计算file_handle到文件头的偏移字节数,即计算文件的大小printf("file size = %d\n",FileSize);rewind(file_handle); // equivalent (void) feek(file_handle,0L,SEEK_SET) 将file_handle 指针移动到文件头位置printf("find PAT begin-------->\n");for(i=0;i<FileSize/188;i++){Read_Ts_Packet(file_handle,buffer,188); //读TS的packet函数,每次读188个字节到bufferret = parse_TS(buffer,188); //解析188个字节的TS's packet,并打印找到的PA T’s table。

如果解析成功即找到PA T,则返回1,否则返回0if(ret == 1){break;}else{printf("There is no PAT table!\n");}}if(ret == 1){parse_PAT(buffer,188); //解析PAT,并找出所含频道的数目和PMT的PID }pronum_pmtid_printf(); //打印PMT的PIDrewind(file_handle);printf("find PMT begin -------->\n");for(i=0;i<num;i++){pmt_buffer = Find_PMT(programs[i].pmt_pid); //根据PMT的PID找到PMT's tableprintf("PMT table -------->\n");for(j=0;j<188;j++){printf("0x%x ",pmt_buffer[j]); //打印PMT}if(pmt_buffer){parse_PMT(pmt_buffer,188,programs[i].pmt_pid); //解析找到的PMT,得到Video、Audio等的PID}memset(pmt_buffer,0,sizeof(char)*188);printf("\n");}printf_program_list(); //打印elementary 流的PID和type。

rewind(file_handle);printf("find Audio and Video begin-------->\n");for(i=0;i<program_list_num;i++){Video_or_Audio_buffer = Find_video_audio(program_list[i].elementary_pid,program_list[i].stream_type); //根据PID找到elementary流printf("the program's PID is 0x%x\n",program_list[i].elementary_pid);printf("the program's Table --------->\n");for(j=0;j<188;j++){printf("0x%x ",Video_or_Audio_buffer[j]); //打印elementary's table }memset(Video_or_Audio_buffer,0,sizeof(char)*188);printf("\n");}free(pmt_buffer);free(Video_or_Audio_buffer);pmt_buffer = NULL;Video_or_Audio_buffer = NULL;fclose(file_handle);printf("\n");return 1;}/*************************************************** read one TS packet's data* *************************************************/void Read_Ts_Packet(FILE *file_handle,unsigned char *packet_buf,int len){fread(packet_buf,188,1,file_handle);}int parse_TS(unsigned char *buffer,int FileSize){unsigned char *temp = buffer;short pat_pid;int i = 0;if(buffer[0] != 0x47){printf("it's not a ts packet!\n");return 0;}while(temp < buffer + FileSize){pat_pid = (temp[1] & 0x1f)<<8 | temp[2];if(pat_pid != 0)printf("finding PAT table ....\n");else{printf("already find the PA T table\n");printf("pat_pid = 0x%x\n",pat_pid);printf("pat table ------->\n");for(i=0;i<=187;i++){printf("0x%x ",buffer[i]);}printf("\n");return 1;}temp = temp + 188;}return 0;}/******************************************************** parse PAT table, get the PMT's PID* ********************************************************/ void parse_PAT(unsigned char *buffer,int len){unsigned char *temp, *p;char adaptation_control;int adaptation_length,i=0;unsigned short section_length,prg_No,PMT_Pid;temp = buffer;adaptation_control = temp[3] & 0x30;if(adaptation_control == 0x10)temp = buffer + 4 + 1;else if (adaptation_control == 0x30){adaptation_length = buffer[4];temp = buffer + 4 + 1 +adaptation_length + 1; }else{return ;}section_length = (temp[1]&0x0f)<<8 | temp[2];p = temp + 1 +section_length;temp = temp + 8;while(temp < p - 4){prg_No = (temp[0]<<8) | (temp[1]);if(prg_No == 0){temp = temp + 4;continue;}else{PMT_Pid = (temp[2]&0x1f)<<8 | temp[3];programs[num].program_num = prg_No;programs[num].pmt_pid = PMT_Pid;// printf("pmt_pid is ox%x\n", PMT_Pid);num ++;temp = temp + 4;}}}void pronum_pmtid_printf(){unsigned int i;printf("PAT table's program_num and PMT's PID:\n");for(i=0;i<num;i++){printf("program_num = 0x%x (%d),PMT_Pid = 0x%x (%d)\n",programs[i].program_num,programs[i].program_num,programs[i].pmt_pid,programs[i].pmt_pid);}}void printf_program_list(){unsigned int i;printf("All PMT Table's program list: \n");for(i=0;i<program_list_num;i++){printf("stream_type = 0x%x, elementary_pid = 0x%x\n",program_list[i].stream_type,program_list[i].elementary_pid);}printf("\n");}unsigned char* Find_PMT(unsigned short pmt_pid){unsigned int i=0,j=0;int pid;unsigned char *buffer;buffer = (unsigned char *)malloc(sizeof(char)*188);memset(buffer,0,sizeof(char)*188);rewind(file_handle);for(j=0;j<FileSize/188;j++){Read_Ts_Packet(file_handle,buffer,188);if(buffer[0] != 0x47){printf("It's not TS packet !\n");}else{pid = (buffer[1] & 0x1f)<< 8 | buffer[2];if(pid == pmt_pid){printf("PMT Table already find!\n");return buffer;}elseprintf("finding PMT table.......\n");}}}unsigned char* Find_video_audio(unsigned short program_pid,unsigned char type) {unsigned int i = 0, j = 0 ;int pid;unsigned char *buffer;buffer = (unsigned char *)malloc(sizeof(char)*188);memset(buffer,0,sizeof(char)*188);rewind(file_handle);for(j=0;j<FileSize/188;j++){Read_Ts_Packet(file_handle,buffer,188);if(buffer[0] != 0x47){printf("It's not TS packet !\n");}else{pid = (buffer[1] & 0x1f)<< 8 | buffer[2];if(program_pid == pid){if(type == 0x02)printf("Find a program and this program is Video type!\n");else if(type == 0x03)printf("Find a program and this program is Audio type!\n");elseprintf("Find a program but this program is other type !\n");return buffer;}elseprintf("finding Video or Audio table.....\n ");}}}void parse_PMT(unsigned char *buffer,int len,unsigned short pmt_pid){unsigned char *temp, *p;char adaptation_control;int adaptation_length,i=0;int program_info_length;int ES_info_length;unsigned short section_length,pid;temp = buffer;adaptation_control = temp[3] & 0x30;if(adaptation_control == 0x10){temp = buffer + 4 +1;}else if (adaptation_control == 0x30){adaptation_length = buffer[4];temp = buffer + 5 + adaptation_length + 1;}elsereturn;section_length = (temp[1]&0x0f)<<8 | temp[2];p = temp + 1 + section_length;// temp = temp + 10;program_info_length = (temp[10] & 0x0f) << 8 | temp[11];temp = temp + 12 + program_info_length ;for(;temp < p - 4;){program_list[program_list_num].stream_type = temp[0],program_list[program_list_num].elementary_pid = (temp[1]&0x1f) << 8 | temp[2];ES_info_length = (temp[3]&0x0f) << 8 | temp[4];temp = temp + 4 + ES_info_length + 1;program_list_num ++ ;}}。

相关文档
最新文档