ts packet解析
(1)TS流是基于Packet的位流格式,每个包是188字节或者204字节(一般是188字节,204字节的格式仅仅是在188字节的Packet后部加上16字节的CRC数据,其他格式是一样的),整个TS流组成如下所示:
Packet 1 Packet 2 ...... Packet n
在实际使用中,因为TS流已经内部具有很强的错误处理能力,所以一般使用较多的是188字节一个包的格式,204字节一个包的格式据说一般在高清节目中使用较多.
所有的Packet格式都是统一的,包括一个Packet header和Packet datas.其中Packet header包含了同步字节(该字节固定是0x47,表示这个包的数据开始是正确的),该Packet的唯一号码(即PID)和其他一些信息.格式如下(用C格式表示)
typedef struct { unsigned sync_byte:8;/*8 bits的同步字节,固定为0x47*/ unsigned transport_error_indicator:1;/*1 bit的错误指示信息,1表示当前Packet至少有1bit的传输错误,0表示所有数据都正确*/ unsigned payload_unit_start_indicator:1;/*负载单元开始标志。详细下面介绍*/ unsigned transport_priority:1;/*1 bit的传输优先级标志,1表示高优先级,0表示低优先级*/ unsigned PID:13;/*13 bits的Packet ID号码,唯一的号码对应不同的包*/ unsigned transport_scrambling_control:2;/*2 bits的加扰标志,00表示没有加扰,其他表示已被加扰*/ unsigned adaptation_field_control:2;/* 2 bits的附加区域控制,详细下面介绍*/ unsigned continuity_counter:4;/*4 bits的包递增计数器*/ }PACKET_HEADER;
payload_unit_start_indicator
这是1b长度字段,该字段用来表示ts包的有效净荷带有PES包或者PSI数据的情况。
当ts包带有PES包数据时,该字段具有以下特点:置为1,表示ts包的有效净荷以PES包的第一个字节开始;置为0,表示ts包的开始不是PES包。
当ts包带有PSI数据时,该字段具有以下特点:置为1,表示ts包带有PSI部分的第一个字节,即第一个字节带有指针pointer_field;置为0,表示ts包不带有一个PSI部分的第一个字节,即有效净荷中没有指针pointer_field。
对于空包该字段应该置为0;
也就是说,为1时,在前4个字节(包头)之后会有一个调整字节,它的数值决定了负载内容的具体开始位置。
PID
这个在头部的32b的字段十分重要,它是辨别码流信息性质的关键,是节目信息的“身份证”,不同的电视节目和业务信息SI对应有不同的PID值。对于一台节目解码接收机而言,为了找到他所要接收的电视节目,他首先通过PID值找到节目专用信息PSI与业务信息SI所对应的不同表,这些表包括PAT、PMT、
CAT、NIT、SDT、EIT和TDT等,通过这些有关节目的信息表,尤其是节目专用信息表,可以查到所要接受节目的PID值和对应的CRC,这样节目就可以被还原。除了PAT表包的PID永远为0外,还有两种包的PID是预留的:一个是空包,它用作码流填充,其PID是8191,是PID所有允许值0-8191的最后一个,
另一个是条件接收表包CAT,其PID值总是1。
transport_scrambling_control
如果传送流包首部包括调整字段,则不应该被加扰。对于空包。该字段的值置为“00”。
adaptation_field_control
这是一个2b长度的字段,表示传送流包首部是否跟随有调整字段和/或有效净荷。
00:保留
01:没有调整字段,仅含有184B长度的有效净荷
10:没有有效净荷,仅含有183B长度的调整字段
11:0~182B的调整字段后为有效净荷
continuity_counter
随着具有相同PID包的增加二增加,当它达到最大时,又恢复为0.如果调整字段控制值 transport_scrambling_control为“00”和“10”,该连续计数器不增加。
以上结构刚好占用32 bits,即4个字节,因此一个TS流的Packet头部的4字节是header信息,剩下的184个字节的内容由PID决定。分析该header信息就可以知道当前Packet的属性.剩下的184字节有可能是Video数据,也有可能是Audio数据,也有可能是DVB SI信息,怎 么区分呢?其实很简单,就是利用header中的PID信息.上一章说了PAT是节目关联表,它的PID是0x0000.这个PID就是对应这里 header的PID.换句话就是说,如果我们发现一个Packet的PID等于0x0000,那么说明这个Packet是DVB的PAT表格而不是 Video数据或者Audio数据.
其他184个字节里面基本都装的是音频或者视频解码数据。如果给定一个TS文件,怎么去寻找解码音视频解码数据呢?
每个TS包的前4个字节的包头里都有一个PID,首先,一个个遍历TS包,我们找到PID为0的TS包,这个包叫PAT,这个PAT包里包含了PMT的PID号,所以我们再遍历TS包又又可以找到名为PMT的TS包,PMT里包含了video TS包的PID和它的codec,audio TS包的PID和它的codec 。有了codec我们知道要选择什么解码器,有PID我们就可以获得解码数据。
我们先来说说video数据和audio数据是怎么分散在TS包里的。video和audio其实都是以一种叫PES(Packetized Elementary Stream)的形式组织的。一帧视频就是一个PES包。我们都知道一个TS包只有188个字节,除掉包头还剩184个字节,这是不可能放下一帧的。实际上一个PES包是分配在连续的几个TS包中,所以如果我们要获得一帧数据,那么我们需要把连续的几个TS包里的数据全部取出来才能组合成一个PES。那我们怎么知道一个PES的开始和结尾呢?那我们还是一个个遍历每一个TS包,寻找包头里payload_unit_start_indicator为1包,这个标志位代表着是一个PES的开始,那么我从这开始,一直到下一个payload_unit_start_indicator为1,这中间的TS包组成起来就是一个PES。
实际上,在信号编码成TS码流的时候,不同节目的Video,Audio等数据都分配了不同的PID.例如,一个节目有两路Video,三路Audio,那 么分配PID的时候可能是Video 1==0x100,Video 2==0x101,Audio 1==0x102,Audio 2==0x103, Audio 3==0x104,这样传输的TS码流中的PID就可能有以上的PID.因此,如果我们需要在程序中过滤出第一路Video和第二路 Audio就可以这样处理了(伪代码描述):
void Process_Packet(unsigned char*buff)
{
int PID=GETPID(buff);/*从当前的188字节缓冲区中获取PID信息*/
if(PID==0x100) /*PID等于第一路Video的PID,说明当前数据是Video数据*/
{
SaveToVideoBuffer(buff+4);/*把header后部的数据存到Video缓冲区,待后部处理*/
}
else if(PID==0x103)/*PID等于第二路Audio的PID,说明当前数据是Audio数据*/
{
SaveToAudioBuffer(buff+4);/*把header后部的数据存到Audio缓冲区*/
}
else/*其他PID则丢弃,当然如果PID是DVB系统保留的PID如PAT,PMT则必须处理*/
{
printf("unknown PID!\n");
}
}
现 在的问题是,编码的时候分配好的PID,在解码的时候是怎么知道什么PID对应什么数据呢?
这 里仅仅截取了3个Packet的信息,请注意图中用红色标注的部分,这就是TS流Packet的4个字节的头信息.这个TS流是采用每个包共188字节的 格式,因为两个头信息的间隔是188个字节(第一个0x47到第二个0x47的间隔).以后的所有的Packet都将是188字节的格式,这是 DVB TS标准规定的固定大小.那么这三个包分别包含的是什么数据,下面我们可以自己分析一下.
先 看第一个包,头信息数据是"0x47 0x07 0xe5 0x12",刚才已经知道了,header信息都是按位操作的(这就是为什么TS码流也可以叫 做位流的原因),特别要注意的是定义和传输的时候都是MSB first,也就是说,先出现的位是数据的最高位.先转化成2进制格式:
01000111 00000111 11100101 00010010
请对照上面的PACKET_HEADER结构:
typedef struct { unsigned sync_byte:8; unsigned transport_error_indicator:1; unsigned payload_unit_start_indicator:1; unsigned transport_priority:1; unsigned PID:13; unsigned transport_scrambling_control:2; unsigned adaptation_field_control:2; unsigned continuity_counter:4; }PACKET_HEADER;
那么对照一下,我们可以发现:
sync_byte=01000111,就是0x47,这是DVB TS规定的同步字节,固定是0x47.
transport_error_indicator=0,表示当前包没有发生传输错误.
payload_unit_start_indicator=0,含义请参考ISO13818-1标准文档
transport_priority=0,表示当前包是低优先级.
PID=00111 11100101即0x07e5,这代表是什么呢,暂时还不知道(实际上是Video PID,参考下图)
transport_scrambling_control=00,表示节目没有加密
adaptation_field_control=01即0x01,具体含义请参考ISO13818-1
continuity_counte=0010即0x02,表示当前传送的相同类型的包是第3个
依此类推,再看一下第二个包"0x47 0x07 0xe5 0x13",二进制是:01000111 00000111 11100101 00010011
sync_byte=01000111,就是0x47,这是DVB TS规定的同步字节,固定是0x47.
transport_error_indicator=0,表示当前包没有发生传输错误.
payload_unit_start_indicator=0,含义请参考ISO13818-1标准文档
transport_priority=0,表示当前包是低优先级.
PID=00111 11100101即0x07e5,这代表是什么呢,暂时还不知道(实际上是Video PID,参考下图)
transport_scrambling_control=00,表示节目没有加密
adaptation_field_control=01即0x01,具体含义请参考ISO13818-1
continuity_counte=0011即0x03,表示当前传送的相同类型的包是第4个(注意到了吧,以上两个包的PID都是0x07e5,所以这里的continuity_counte就递增一次)
第三个包是"0x47 0x07 0xf1 0x18",2进制是01000111 00000111 11110001 00011000.
sync_byte=01000111,就是0x47,这是DVB TS规定的同步字节,固定是0x47.
transport_error_indicator=0,表示当前包没有发生传输错误.
payload_unit_start_indicator=0,含义请参考ISO13818-1标准文档
transport_priority=0,表示当前包是低优先级.
PID=00111 11100101即0x07f1,这代表是什么呢,暂时还不知道(实际上是Audio PID,参考下图)
transport_scrambling_control=00,表示节目没有加密
adaptation_field_control=01即0x01,具体含义请参考ISO13818-1
continuity_counte=1000即0x08,表示当前传送的相同类型的包是第9个
参考博客:http://www.360doc.com/content/11/0824/08/7399771_142838446.shtml
ts packet解析的更多相关文章
- TS格式解析
1.TS格式介绍 TS:全称为MPEG2-TS.TS即"Transport Stream"的缩写.它是分包发送的,每一个包长为188字节(还有192和204个字节的包).包的结构为 ...
- TS流解析 二 *****
1.TS格式介绍 TS:全称为MPEG2-TS.TS即"Transport Stream"的缩写.它是分包发送的,每一个包长为188字节(还有192和204个字节的包).包的结构为 ...
- ts 协议解析
pes : http://wenku.baidu.com/link?url=KjcA0qXqZ1bWVQTa8i1YOmygofldSQL7Pjj-zGRw1e_6_LFmVLo5DIWF0SNwVn ...
- TS流解析 一
一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...
- TS流解析 四
一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...
- TS流解析 三
应该说真正了解TS,还是看了朋友推荐的<数字电视业务信息及其编码>一书之后,MPEG2 TS和数字电视是紧密不可分割的,值得总结一下其中的一些关系. ISO/IEC-13818-1:系统部 ...
- wusir FTP与HTTP文件传输之TCP Packet解析
向服务器传输文件(上传或下载)时,FTP与HTTP是两种最常用的应用层协议,这两个协议都是基于TCP协议之上.如果深入到数据包内(Packet)进行查看时,FTP与HTTP进行文件传输时有什么特征代码 ...
- TS 函数解析
------------------------------------------------------------------------------------ 函数传参: //let myA ...
- TS流的解析
个字节不一定都是有效数据,有一些可能为填充数据). 工作形式: 因为在TS流里可以填入很多种东西,所以有必要有一种机制来确定怎么来标识这些数据.制定TS流标准的机构就规定了一些数据结构来定义.比如: ...
随机推荐
- sql developer中英文切换
今天使用oracle sql developer时做调优建议时找到的建议显示为?的乱码,本人sql developer为中文版,修改为英文版后问题解决. 查看帮助菜单中的属性选项卡,user.lang ...
- libevent-signal(2)
上一节着重分析了event_init是如何集成signal,这一节从event_add展开分析 ev_events有四种类型 I/O事件: EV_WRITE和EV_READ 定时事件:EV_TIMEO ...
- echarts固定柱子宽度(barWidth)
series: [ { name: '', yAxisIndex: 0, type: ' ...
- Android(java)学习笔记55:LayoutInflater 和 findViewById
1. 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById(). 不同点是LayoutInflater是用来找res/layout/下的xml布局文件, ...
- 给于用户Agent权限设置
问题:有一个用户需要有create\alter\drop job人权限.默认是只有sysadmin成员才有这个权限.肯定不能将用户放到这个组 答案:所有JOB都属于msdb库中读取和写入信息.所以,肯 ...
- XCode插件因为升级不能用了怎么办?几个步骤教你搞定
之前XCode安装了自动注释的插件 VVDomenter.升级之后不能使用了怎么办?跟着我做吧. 1.打开xcode插件所在的目录:~/library/Application Support/Deve ...
- 【luogu P3627 [APIO2009]抢掠计划】 题解
题目链接:https://www.luogu.org/problemnew/show/P3627 把点权转化到边权上去. #include <stack> #include <que ...
- 【luogu P2731 骑马修栅栏】 题解
题目链接:https://www.luogu.org/problemnew/show/P2731 这个题是欧拉回路的模板题,那么在这里给出一个hierholzer的做法. 对于求欧拉回路的问题,有Fl ...
- 微软.net framework 源码学习
1. 直接下载.NET Framework源代码(下载地址),然后用Visual Studio打开查看. 2. 在线查看,网址:http://referencesource.microsoft.com ...
- Openresty最佳案例 | 第9篇:Openresty实现的网关权限控制
转载请标明出处: http://blog.csdn.net/forezp/article/details/78616779 本文出自方志朋的博客 简介 采用openresty 开发出的api网关有很多 ...