zoukankan      html  css  js  c++  java
  • 精解PSISI(一)

    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呢?

  • 相关阅读:
    spring mvc给参数起别名
    聊聊分布式定时任务中间件架构及其实现--转
    Batch Normalization的算法本质是在网络每一层的输入前增加一层BN层(也即归一化层),对数据进行归一化处理,然后再进入网络下一层,但是BN并不是简单的对数据进行求归一化,而是引入了两个参数λ和β去进行数据重构
    终端安全工具 gartner 排名
    When Cyber Security Meets Machine Learning 机器学习 安全分析 对于安全领域的总结很有用 看未来演进方向
    DNS隧道之DNS2TCP实现——dns2tcpc必须带server IP才可以,此外ssh可以穿过墙的,设置代理上网
    DNS隧道之DNS2TCP使用心得教程——是可以用来穿透qiang的,ubuntu下直接apt install dns2tcp
    DNS隧道工具汇总——补充,还有IP over DNS的工具NSTX、Iodine、DNSCat
    Data Mining and Machine Learning in Cybersecurity PDF
    ES failed to notify ClusterStateListener java.lang.IllegalStateException: environment is not locked
  • 原文地址:https://www.cnblogs.com/KUDO/p/1311852.html
Copyright © 2011-2022 走看看