TS码流分析

版权声明:本文为博主原创文章,转载请提提我 https://blog.csdn.net/hushiganghu/article/details/76830176

概述

  • ES流(Elementary Stream) 基本码流,不分段的音频、视频或其他信息的连续码流。
  • PES流 把基本流ES分割成段,并加上相应头文件打包成形的打包基本码流。

  • PS流(Program Stream) 节目流,将具有共同时间基准的一个或多个PES组合(复合)而成的单一数据流(用于播放或编辑系统,如m2p)。

  • TS流(Transport Stream) 传输流,将具有共同时间基准或独立时间基准的一个或多个PES组合(复合)而成的单一数据流(用于数据传输)。

*NOTE:
TS流和PS流的区别:TS流的包结构是长度是固定的;PS流的包结构是可变长度的。 这导致了 TS流的抵抗传输误码的能力强于PS流 (TS码流由于采用了固定长度的包结构, 当传输误码破坏了某一TS包的同步信息时,接收机可在固定的位置检测它后面包中的同步信息,从而恢复同步,避免了信息丢失。 而PS包由于长度是变化的,一旦某一 PS包的同步信息丢失, 接收机无法确定下一包的同步位置,就会造成失步,导致严重的信息丢失。 因此,在信道环境较为恶劣,传输误码较高时,一般采用TS码流;而在信道环境较好,传输误码较低时,一般采用PS码流。)

由于TS码流具有较强的抵抗传输误码的能力,因此目前在传输媒体中进行传输的MPEG-2码流基本上都采用了TS码流的包格。

TS流生成流程图

这里写图片描述

从上图可以看出,视频ES和音频ES通过打包器和共同或独立的系统时间基准形成一个个PES, 通过TS复用器复用形成的传输流。 注意这里的TS流是 位流格式(分析Packet的时候会解释),也即是说TS流是可以按位读取的。

TS流的格式

TS流是基于Packet的位流格式,即由n个包组成;每个包是188个字节(或204个字节,在188个字节后加上了16字节的CRC校验数据)

包头

这里写图片描述

name bit位 描述
sync_byte 8 bits 同步字节,固定是0x47
transport_error_indicator 1 bits 错误指示信息(1:该包至少有1bits传输错误)
payload_unit_start_indicator 1 bits 负载单元开始标志(packet不满188字节时需填充)
transport_priority 1 bits 传输优先级标志(1:优先级高)
PID 13 bits Packet ID号码,唯一的号码对应不同的包
transport_scrambling_control 2 bits 加密标志(00:未加密;其他表示已加密)
adaptation_field_control 2 bits 附加区域控制
continuity_counter 4 bits 包递增计数器

TS流中PID的分配

TS流中PID的分配

PID值
PAT 0x0000
CAT 0x0001
TSDT 0x0002
预留 0x0003 至0x000F
NIT ST 0x0010
SDT , BAT, ST 0x0011
EIT, ST 0x0012
RST, ST 0x0013
TDT, TOT, ST 0x0014
网络同步 0x0015
预留使用 0x0016 至 0x001B
带内信令 0x001C
DIT 0x001E
SIT 0x001F

术语

业务与事件

这里写图片描述

PSI/SI表

如上图所示,现实情况下,举个例子,在上图位于Services,而比如CCTV1~CCTV14对应不同的components,

PAT 节目关联表 Program Association Tabl

PID为0x0000 ,TS码流解析从PAT表开始

PAT表携带以下信息

TS流ID transport_stream_id 该ID标志唯一的流ID
节目频道号 program_number 该号码标志TS流中的一个频道,该频道可以包含很多的节目(即可以包含多个Video PID和Audio PID)
PMT的PID program_map_PID 表示本频道使用哪个PID做为PMT的PID。因为可以有很多的业务,因此DVB规定PMT的PID可以由用户自己定义

PAT数据包分为两个部分,一个是PAT数据包头部(前8个Byte),一个是循环部分

/*头部部分 8个Byte*/
program_association_section()
{  
    unsigned table_id                     : 8; //固定为0x00 ,标志是该表是PAT表  
    unsigned section_syntax_indicator     : 1; //段语法标志位,固定为1  
    unsigned0’                          : 1; //0  
    unsigned reserved_1                   : 2; // 保留位  
    unsigned section_length               : 12; //段长度字节,表示从下一个字段开始到CRC32(含)之间有用的字节数  
    unsigned transport_stream_id          : 16; //该传输流的ID,区别于一个网络中其它多路复用的流  
    unsigned reserved_2                   : 2;// 保留位
    unsigned version_number               : 5; //范围0-31,表示PAT的版本号  
    unsigned current_next_indicator       : 1; //发送的PAT是当前有效还是下一个PAT有效  
    unsigned section_number               : 8; //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段  给出section号,在sub_table中,第一个section其section_number为"0x00",每增加一个section,section_number加一
    unsigned last_section_number          : 8;  //最后一个分段的号码 ,sub_table中最后一个section的section_number

    /*循环部分 4个Byte*/
  for(i=0;i<N;i++)
  {
    program_number                        :16;  //节目号
    reserved                              :3;   //保留位
    network_id 或 program_map_PID         :13;  //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID;其余情况是program_map_PID(PMT的PID)
  }
    CRC_32                                :32;      
}

PMT 节目映射表 Program Map Table

1

(1) 当前频道中包含的所有Video数据的PID

(2) 当前频道中包含的所有Audio数据的PID

(3) 和当前频道关联在一起的其他数据的PID(如数字广播,数据通讯等使用的PID)

PMT 表头

TS_program_map_section() {
    table_id                      :8; //固定为0x02 标识PMT表
    section_syntax_indicator      :1; //固定为0x01
    '0'                           :1; //
    reserved                      :2; // 保留位
    section_length                :12 //该字段的头两bit必为‘00’,剩余10bit指定该分段的字节数,紧随section_length 字段开始,并包括CRC。此字段中的值应不超过1021(0x3FD)。
    program_number                :16 //指出TS流中Program map section的版本号
    reserved                      :2  // 保留位
    version_number                :5  //指出TS流中Program map section的版本号 
    current_next_indicator        :1  //当该位置1时,当前传送的Program map section可用;  
                                      //当该位置0时,指示当前传送的Program map section不可用,下一个TS流的Program map section有效
    section_number                :8  //固定为0x00
    last_section_number           :8  //固定为0x00
    reserved                      :3  //保留
    PCR_PID                       :13 //指明TS包的PID值,该TS包含有PCR域,  
                                      //该PCR值对应于由节目号指定的对应节目。  
                                      //如果对于私有数据流的节目定义与PCR无关,这个域的值将为0x1FFF。
    reserved                      :4  //保留位
    program_info_length           :12 //节目信息长度。该字段的头两比特必为‘00’,剩余10 比特指定紧随program_info_length 字段的描述符的字节数 ,
                                      //(之后的是N个描述符结构,一般可以忽略掉,这个字段就代表描述符总的长度,单位是Bytes)紧接着就是频道内部包含的节目类型和对应的PID号码了
    for (i = 0; i < N; i++) {
        descriptor()
    }
    for (i = 0; i < N1; i++) {
        stream_type              :8 //流类型,标志是Video还是Audio还是其他数据。这里是MPEG2视频类型 
        reserved                 :3 //保留位
        elementary_PID           :13 //该节目的音频或视频PID
        reserved                 :4 //保留位
        ES_info_length           :12 //该字段的头两比特必为‘00’,剩余10比特指示紧随ES_info_length字段的相关节目元描述符的字节数。
        for (i = 0; i < N2; i++) {
        descriptor()
    }
    }
    CRC_32                       :32 
}

猜你喜欢

转载自blog.csdn.net/hushiganghu/article/details/76830176
今日推荐