MPEG2 TS基本概念和数据结构

MPEG2 TS是一种传输流,用于多路节目复用。它包括ES(原始流)、PES(分组原始流)、TS(传输流)和PS(节目流)。TS由188字节分组构成,含同步字节、PID等信息。PSI(节目专用信息)如PAT、PMT等用于解析多路节目。PMT包含节目元素的PID,PAT指定PMT的位置。TS和PS可以互相转换,适应不同环境。
摘要由CSDN通过智能技术生成

(1)ES- Elementary Streams ( 原始流 ) ,对视频、音频信号及其他数据进行编码压缩后的数据流称为原始流。原始流包括访问单元,比如视频原始流的访问单元就是一副图像的编码数据。
(2) PES- Packetized Elementary Streams (
分组的原始流 ) ,原始流形成的分组称为 PES 分组,是用来传递原始流的一种数据结构
(3)
节目是节目元素的集合。节目元素可能是原始流,这些原始流有共同的时间基点,用来做同步显示。
(4)
传输流和节目流 TS-Transport Stream 翻译为 传输流 ”PS-Program Stream   翻译为 节目流 ”PS 用来传输和保存一道节目的编码数据或其他数据。 PS 的组成单位是 PES 分组。 TS 用来传输和保存多道节目的编码数据或其他数据, TS 的组成单位是节目。 PS 适用于不容易发生错误的环境,以及涉及到软件处理的应用,典型应用如 DVD 光盘的文件存储 TS 适用于容易发生错误的环境,典型应用就是数字电视信号的传输。 TS PS 是可以互相转换的,比如从 TS 中抽取一道节目的内容并产生有效的 PS 是可能。
(5)
传输流分组和 PES 分组原始流分成很多 PES 分组,保持串行顺序,一个 PES 分组只包含一个原始流的编码数据。 PES 分组长度很大,最大可为 64K 字节。 PES 分组分为 分组首部 (header)” 有效负载 (payload)” 有效负载 指跟随在首部字节之后的字节。首部的前 4 个字节构成分组的起始码,标识了该分组所属原始流的类型和 ID 号。 TS 分组也就是传输流数据形成的数据包。每个 TS 分组长度为 188 字节,包括 分组首部 有效负载,前 4 个字节是分组首部,包含了这个分组的一些信息。有些情况下需要更多的信息时,需在后面添加 调整字段 (adaption field)” 。两者之间的关系 :PES 分组是插入到 TS 分组中的,每个 PES 分组首部的第一字节就是 TS 分组有效负载的第一字节。一个 PID 值的 TS 分组只带有来自一个原始流的数据。
(6)PSI
全称 Program Specific Information ,意为节目专用信息。传输流中是多路节目复用的,那么,怎么知道这些节目在传输流中的位置,区分属于不同节目呢?所以就还需要一些附加信息,这就是 PSI PSI 也是插入到 TS 分组中的,它们的 PID 是特定值。 MPEG-2 中规定了 4 PSI ,包括 PAT( 节目关联表 ) CAT( 条件访问表 ) PMT( 节目映射表 ) NIT( 网络信息表 ) ,这些 PSI 包含了进行多路解调和显示节目的必要的和足够的信息。应用中可能包括更多的信息,比如 DVB-T 中定义了 SDT( 服务描述表 ),EIT( 环境信息表 ),BAT( 节目组相关表 ),TDT( 时间日期表 ) 等,统称为 DVB-SI( 服务信息 ) PSI PID 是特定的,含 PSI 的数据包必须周期性的出现在传输流中。
PMT (Program Map Table ) 节目映射表 PMT 所在分组的 PID PAT 指定,所以要先解出 PAT ,再解 PMT PMT 中包含了属于同一节目的视频、音频和数据原始流的 PID 。找到了 PMT ,解多路复用器就可找到一道节目对应的每个原始流的 PID ,再根据原始流 PID ,去获取原始流。
PAT (Program Association Table ) 节目关联表 PAT 所在分组的 PID=0 PAT 中列出了传输流中存在的节目流 PAT 指定了传输流中每个节目对应 PMT 所在分组的 PIDPAT 的第一条数据指定了 NIT 所在分组的 PID ,其他数据指定了 PMT 所在分组的 PID
CAT (Conditional Access Table ) 条件访问表 CAT 所在分组的 PID=1CAT 中列出了条件控制信息 (ECM) 和条件管理信息 (EMM) 所在分组的 PID CAT 用于节目的加密和解密 NIT( Network Information Table) 网络信息表 NIT 所在分组的 PID PAT 指定 NIT 提供一组传输流的相关信息,以及于网络自身特性相关的信息,比如网络名称,传输参数 ( 如频率 , 调制方式等 ) NIT 一般是解码器内部使用的数据,当然也可以做为 EPG 的一个显示数据提供给用户做为参考。几种 PSI 之间的关系,如下图所示:首先 PAT 中指定了传输流中所存在的节目,及每个节目对应的 PMT PID 号。 比如 Program 1 对应的 PMT PID=22, 然后找到 PID=22 TS 分组,解出 PMT ,得到这个节目中包含的原始流的 PID ,再根据原始流的 PID 去找相应的 TS 分组,获取原始流的数据,然后就可以送入解码器解码了。
数据结构( 1 TS 分组 前面提到, TS 分组由 188 个字节构成,其结构如下:
transport_packet(){
sync_byte                              //8
transport_error_indicator              //1
payload_unit_start_indicator           //1
transport_priority                     // 1

PID                                    //13
transport_scrambling_control           // 2
adaptation_field_control               //2
continuity_counter                     //4
if(adaptation_field_control=='10'  || adaptation_field_control=='11'){
  adaptation_field()
}
if(adaptation_field_control=='01' || adaptation_field_control=='11') {
  for (i=0;i<N;i++){
   data_byte                         
  }
}
}

前面 32bit 的数据即 TS 分组首部,它指出了这个分组的属性。

sync_byte    同步字节,固定为 0x47 ,表示后面的是一个 TS 分组,当然,后面包中的数据是不会出现 0x47

transport_error_indicator 传输错误标志位,一般传输错误的话就不会处理这个包了

payload_unit_start_indicator 这个位功能有点复杂,字面意思是有效负载的开始标志,根据后面有效负载的内容不同功能也不同,后面用到的时候再说。

transport_priority    传输优先级位, 1 表示高优先级,传输机制可能用到,解码好像用不着。

PID    这个比较重要,指出了这个包的有效负载数据的类型,告诉我们这个包传输的是什么内容。前面已经叙述过。

transport_scrambling_control 加密标志位,表示 TS 分组有效负载的加密模式。 TS 分组首部 ( 也就是前面这 32bit) 是不应被加密的, 00 表示未加密。

  adaption_field_control    翻译为 调整字段控制 ,表示 TS 分组首部后面是否跟随有调整字段和有效负载。 01 仅含有效负载, 10 仅含调整字段, 11 含有调整字段和有效负载。为 00 的话解码器不进行处理。空分组没有调整字段

  continuity_counter    一个 4bit 的计数器,范围 0-15 ,具有相同的 PID TS 分组传输时每次加 1 ,到 15 后清 0 。不过,有些情况下是不计数的。如下: (1)TS 分组无有效负载 (2) 复制的 TS 分组和原分组这个值一样 (3) 后面讲到的一个标志 discontinuity_indicator 1

adaptation_field() 调整字段的处理

data_byte 有效负载的剩余部分,可能为 PES 分组, PSI ,或一些自定义的数据。


2   PAT 数据结构如下:
program_association_section() {
   table_id                                // 8
   section_syntax_indicator                // 1
   '0'                                     // 1
   reserved                                // 2
   section_length                          // 12
   transport_stream_id                     // 16
   reserved                                // 2
   version_number                          // 5
   current_next_indicator                  // 1
   section_number                          // 8
   last_section_number                     // 8
   for (i=0; i<N;i++) {
       program_number                      // 16
       reserved                            // 3
     if(program_number == '0') {
         network_PID                       // 13
       }
     else {
        program_map_PID                    // 13
      }
  }
 CRC_32                                    //  32
}

table_id    固定为 0x00 ,标志是该表是 PAT

section_syntax_indicator 段语法标志位,固定为 1

section_length          表示这个字节后面有用的字节数,包括 CRC32 。假如后面的字节加上前面的字节数少于 188 ,后面会用 0XFF 填充。假如这个数值比较大,则 PAT 会分成几部分来传输。

transport_stream_id      该传输流的 ID ,区别于一个网络中其它多路复用的流。

version_number 范围 0-31 ,表示 PAT 的版本号,标注当前节目的版本.这是个非常有用的参数,当检测到这个字段改变时,说明 TS 流中的节目已经变化了,程序必须重新搜索节目.

current_next_indicator 表示发送的 PAT 是当前有效还是下一个 PAT 有效。

section_number 分段的号码。 PAT 可能分为多段传输,第一段为 00 ,以后每个分段加 1 ,最多可能有 256 个分段

last_section_number 最后一个分段的号码

  program_number 节目号

network_PID 网络信息表( NIT )的 PID ,网络信息表提供了该物理网络的一些信息,和电视台相关的。节目号为 0 时对应的 PID network_PID

program_map_PID 节目映射表的 PID ,节目号大于 0 时对应的 PID ,每个节目对应一个

CRC_32    CRC32 校验码

上面 program_number network_PID program_map_PID 是循环出现的。 program_number 等于 0 时对应 network_PID program_number 等于其它值时对应 program_map_PID

 

(3)PMT   PMT 数据结构如下:
TS_program_map_section() {
table_id                               // 8
section_syntax_indicator              //  1
'0'                                   //  1
reserved                              //  2
section_length                        //  12
program_number                        //  16
reserved                              //  2
version_number                        //  5
current_next_indicator                //  1
section_number                        //  8
last_section_number                   //  8
reserved                              //  3
PCR_PID                               //  13
reserved 4
program_info_length                   //  12
for (i=0; i<N; i++) {
  descriptor()
}
for (i=0;i<N1;i++) {
  stream_type                           //  8
  reserved                              //  3
  elementary_PID                        //  13
  reserved                              //  4
  ES_info_length                        //  12
  for (i=0; i<N2; i++) {
   descriptor()
  }
}
CRC_32                                 //  32
}

table_id    固定为 0x02 ,标志是该表是 PMT

section_syntax_indicator section_length        version_number        current_next_indicator 以上四个字段意思和 PAT 相同,可参考上面解释

section_number   last_section_number 以上两个字段意思和 PAT 相同,不过值都固定为 0x00 ,我觉得这样的原因可能是因为 PMT 不需要有先后顺序,因为先定义哪个节目都是无所谓。

program_number 节目号,表示该 PMT 对应的节目

PCR_PID PCR (节目时钟参考)所在 TS 分组的 PID ,根据 PID 可以去搜索相应的 TS 分组,解出 PCR 信息。

program_info_length 该节目的信息长度,在此字段之后可能会有一些字节描述该节目的信息

stream_type 指示了 PID elementary_PID PES 分组中原始流的类型,比如视频流,音频流等,见后面的表

elementary_PID 该节目中包括的视频流,音频流等对应的 TS 分组的 PID

ES_info_length 该节目相关原始流的描述符的信息长度。 stream_type 对应的类型。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值