惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
V
Vulnerabilities – Threatpost
TaoSecurity Blog
TaoSecurity Blog
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
G
GRAHAM CLULEY
S
Securelist
P
Palo Alto Networks Blog
MongoDB | Blog
MongoDB | Blog
A
Arctic Wolf
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
WordPress大学
WordPress大学
Project Zero
Project Zero
T
Threat Research - Cisco Blogs
L
Lohrmann on Cybersecurity
C
Cyber Attacks, Cyber Crime and Cyber Security
F
Fortinet All Blogs
博客园 - 叶小钗
B
Blog RSS Feed
C
Cisco Blogs
Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
G
Google Developers Blog
K
Kaspersky official blog
D
Docker
Latest news
Latest news
Cisco Talos Blog
Cisco Talos Blog
T
Tor Project blog
Cyberwarzone
Cyberwarzone
Security Latest
Security Latest
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Spread Privacy
Spread Privacy
Microsoft Azure Blog
Microsoft Azure Blog
C
Check Point Blog
J
Java Code Geeks
Simon Willison's Weblog
Simon Willison's Weblog
T
Tenable Blog
Recent Announcements
Recent Announcements
T
Tailwind CSS Blog
H
Help Net Security
L
LINUX DO - 热门话题
T
The Exploit Database - CXSecurity.com
Jina AI
Jina AI
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
NISL@THU
NISL@THU
美团技术团队
腾讯CDC

博客园 - KUDO

精解PSI-SI(二) DVB码流中业务信息与电子节目指南 什么是ECM,EMM,AU,EMU? showModalDialog()、showModelessDialog()方法使用详解 js收藏 ASP.NET 2.0 中改进的缓存功能 js 日历控件 - KUDO - 博客园 在VS2005中 GridView导入Excel的两点小技巧-附源码 Python 一门神奇的语言 如何实现选择DataGrid单元格时显示选择一行 获取checkbox onclick事件中的参数 javascript 技巧 网页及其控件有很多触发事件 网页代码常用小技巧总结续,网页制作学习 Microsoft .NET 框架资源基础 crm具体问题具体实现 js\css 让图片垂直居中 - KUDO - 博客园 制作随表格拉伸的背景图 基于aspnet Forms身份验证基本原理 - KUDO
精解PSI-SI(一)
KUDO · 2008-10-15 · via 博客园 - KUDO

Packet的概念

 (1)TS流是基于Packet的位流格式,每个包是188字节或者204字节(一般是188字节,204字节的格式仅仅是在188字节的Packet后部加上16字节的CRC数据,其他格式是一样的),整个TS流组成如下所示:    

  Packet     Packet    ......    Packet n

在实际使用中,因为TS流已经内部具有很强的错误处理能力,所以一般使用较多的是188字节一个包的格式,204字节一个包的格式据说一般在高清节目中使用较多.

 所有的Packet格式都是统一的,包括一个Packet header和Packet datas.其中Packet header包含了同步字节(该字节固定是0x47,表示这个包的数据开始是正确的),该Packet的唯一号码(即PID)和其他一些信息.格式如下(用C格式表示)

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;

以上结构刚好占用32 bits,即4个字节,因此一个TS流的Packet头部的4字节是header信息,分析该header信息就可以知道当前Packet的属性.剩下的184字节有可能是Video数据,也有可能是Audio数据,也有可能是DVB SI信息,怎 么区分呢?其实很简单,就是利用header中的PID信息.上一章说了PAT是节目关联表,它的PID是0x0000.这个PID就是对应这里 header的PID.换句话就是说,如果我们发现一个Packet的PID等于0x0000,那么说明这个Packet是DVB的PAT表格而不是 Video数据或者Audio数据.

实 际上,在信号编码成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);

  if(PID==0x100) 

  {

   SaveToVideoBuffer(buff+4);

  }

  else if(PID==0x103)

  {

   SaveToAudioBuffer(buff+4);

  }

  else

  {

   printf("unknown PID!"n");

    

 }

现 在的问题是,编码的时候分配好的PID,在解码的时候是怎么知道什么PID对应什么数据呢?这就是DVB SI表格的分析与处理了,请参考第三章.这里先 看一个实际的TS码流的例子.这里的数据是用UltraEdit用16进制格式打开TS码流文件得到的.文件是Taiwan-551.ts.

这 里仅仅截取了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",2进制是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个

请看解码程序<<Seekfor MPEG-2 decoder>>读取该文件的结果:

上图我们可以发现,Taiwan-551.ts有一个节目叫"DIMO",它的Video PID是0x07e5,Audio PID是0x07e6

还有一个节目叫"Service 1",没有Video PID,它的Audio PID是0x07f1(说明是一个广播节目而非电视节目)

这个数据刚好和我们刚才的分析是吻合的.

但 是我想大家还有疑问,为什么0x07e5代表Video PID,0x07e6代表其中一个Audio PID呢?这就是刚才提到的,这是TS流在编码的 时候就分配好了的.但是,在解码的时候是怎么知道0x07e5就代表的是Video而不是Audio呢?