ts码流解析工作总结

近段时间,由于工作需要,初步研究学习了TS流的解析,多少有些心得体会,这里与大家分享一下(大牛可以无视,呵呵)。


已编码的音视频数据,按照PES格式进行第一次打包,即PES包。一系列PES包,也有一种叫法叫PES分组。


PES包有几个比较重要的字段(摘自13818标准文档):

分组起始码前缀字段  packet_start_code_prefix 

24位代码,它和后面的stream_id构成了标识分组开始的分组起始码。它是一个值为'0000 00000000 0000 0000 0001' (0x000001)的位串。

流标识字段  stream_id 

在节目流中,它规定了基本流的号码和类型。

PES分组长度字段  PES_packet_length 

16位字段,指出了PES分组中跟在该字段后的字节数目。值为0表示PES分组长度要么没有规定要么没有限制。这种情况只允许出现在有效负载包含来源于传输流分组中某个视频基本流的字节的PES分组中。

PTS DTS标志字段 PTS_DTS_flags 

2位字段。当值为'10'时,PTS字段应出现在PES分组标题中;当值为'11'时,PTS字段和DTS字段都应出现在PES分组标题中;当值为'00'时,PTS字段和DTS字段都不出现在PES分组标题中。值'01'是不允许的。

PES标题数据长度字段  PES_header_data_length

8位字段。指出包含在PES分组标题中的可选字段和任何填充字节所占用的总字节数。该字段之前的字节指出了有无可选字段。

(详细介绍或者其他字段,大家可以参看13818标准中文版 从第39页开始)


初步解析时,判断PES开头码,判断数据类型,根据PES_packet_lengh与PES_header_data_length,计算整个PES的长度与有效荷载数据的长度,以便荷载编码数据提取。这里务必注意PES_packet_lengh为0的情况。


当然PES包是不允许直接传输的,标准规定,PES包需要进行第二次打包,打包为TS、或者PS格式的数据包,才能进行传输。


从应用角度上来说,TS码流适用于网络情况不太理想的环境,它提供了有效的容错处理机制;PS码流适用于基本无错的环境,比如局域网,DVD之类。

从解析工作流程上来说,TS的解析工作量要比PS多些。


*************************************************************************************************************************************************

先简单地说说TS码流。

TS数据长度定位188字节,也就是说无论一个TS包中有效数据有没有,有多少,最终打包大小都是188字节(小日本儿搞了一个192字节的标准,暂时无视)

每个TS数据包,以0x47作为起始码,也叫同步字节。

也就是说,对于一段经典的TS码流,每隔188字节,一定能检测到一个0x47的字节。如果不能,则说明数据流有异常。


TS数据包荷载的数据基本分为两类:PSI信息数据表 和 PES分组数据

PSI表共有一下4种:

节目相关表

节目映射表

条件存取表

网络信息表


可以比较通俗地理解:TS包为了保证编码数据的有效传输,需要以上各类信息表作为传输控制参数,然后PES分组则是需要被传输的有效数据。



这里也从标准文档中摘录几个比较重要的字段(摘自13818中文版,从第29页开始):

同步字节字段  sync_byte 

一个固定的值为 '0100 0111' (0x47)的8位字段。在选择其它经常出现的字段值时,应避免与该字段发生冲突。


传输错误指示符字段  transport_error_indicator 

一个1位标志。置'1'时表示相关传输流分组中至少有一个不可纠正的位差错。该位可能被传输层外部的实体置'1'。置'1'后,除非错误被纠正,值不会恢复为'0'。


有效负载数据单元起始指示符字段  pay_load_unit_start_indicator (这个字段的介绍特别详细,一定要弄明白)

一个1位标志位,对于携带PES分组(参见2.4.3.6)或PSI数据(参见2.4.4)的传输流分组有标准的含义。

在传输流分组的有效负载数据包含PES分组数据时,该标志位有以下意义:'1'表示传输流分组的有效负载数据以PES分组的首字节开始,'0'表示该传输流分组不以PES分组开始。若值为'1',则有且仅有1个PES分组在传输流分组开始,它也适用于流类型6的专用流(参见表2-29)。

在传输流分组的有效负载数据包含PSI数据时,该标识位有以下意义:若传输流分组携带有PSI段的第一个字节,则该值应为'1',以表示传输流分组中有效负载数据的首字节带有point_field。若传输流分组不包含PSI段的第一个字节,则该值应为'0',以表示传输流分组中有效负载数据的首字节无point_field。参见2.4.4.1和2.4.4.2。这也适用于流类型5的专用流(参见表2-29)。

对空的分组而言,该标志位置'0'。

对于只携带专用数据的传输流分组,该位的意义在本规范未作规定。


PID字段 PID 

13位字段,指示分组有效负载数据中存储的数据类型。PID值0x0000被保留用于节目相关表(参见表2-25)。PID值0x0001被保留用于条件存取表(参见表2-27)。PID值0x0002~0x000F也被保留。PID值0x1FFF被保留用于空的分组(参见PID表)。

 PID表

描  述

0x0000

PAT

0x0001

CAT

0x0002~0x000F

保留

0x0010…0x1FFE

可以赋给network_PID,Program_map_IP,elementary_PID或作其它用途

0x1FFF

空的分组

注:PID值为0x0000,0x0001,和0x0010…0x1FFE的传输分组允许携带PCR


适应字段控制字段  adaption_field_control 

2位字段,指出传输流分组标题后面是否有适应字段及(或)有效负载数据,参看下表。


描  述

00

ISO/IEC保留,以供将来使用

01

没有适应字段,仅有有效负载

10

仅有适应字段,没有有效负载

11

跟有有效负载的适应字段

GB/T XXXX.1解码器会丢弃adaption_field_control字段值为'00'的传输流分组。对空的分组而言,该字段值应为'01'。

适应字段长度字段  adaption_field_length 

8位字段,指示紧随其后adaption_field的字节长度。值为0用于在传输流分组中插入单个填充字节。当适应字段控制的值为'11'时,该字段值应在0到182之间。当适应字段控制的值为'10'时,该字段值应为183。对于携带PES分组的传输流分组,在没有足够的PES分组数据来完全填满传输流分组有效负载字节时,需要填充。通过定义一个比其内部包含的数据元素的长度之和还要长的适应字段来完成填充,这样适应字段后所剩的有效负载字节恰好能容纳有用的PES分组数据。适应字段中多余的空间被填入填充字节。

这是对携带PES分组的传输流分组所允许的唯一的填充方法。对携带PSI的传输流分组,2.4.4中描述了另一种填充方法。


解析工作:

找到数据流中第一个出现0x47的字节,判断是否为TS码流的起始(往后多查找 188 * n组字节,看看是否都是0x47),取从0x47开始的188字节,进入TS包解析模块。

首先解析PID为0的PAT表,若当前包不是,则丢弃该包,进入下一个ts包,直到完成PAT表解析。

从PAT包中解析出PMT表所在的TS包的PID值,然后逐个解析后续TS包,直接找到对应PID的TS包,然后按照标准解析PMT表。

(一般来说,简单的TS码流数据,解析以上两个表即可,也不会有其他PSI表了,初学者也需要首先了解上述两个表)

如果有其他PSI表,也需要同样解析。

在PMT中能解析出编码传输数据所在TS包的PID值,根据这些PID值,逐个解析后续TS包,只要包含对应的PID,则说明该TS包中荷载了PES分组数据。

到这里,计算出PES包的起始位置,开始PES的解析流程。

后续的TS包,逐个补充该PES包,直到完成一个PES包的提取工作。


以上就是一个比较粗略的TS码流解析流程。


笔者在学习过程中,在以下方面遇到过困难,写出来,望各位朋友注意:


一个TS数据段解析后剩余一部分不足188长度数据,需要与下一个TS数据段前一部分数据,组装一个TS包


读取某字节数据,并转为int数据时,注意用byte,不要用char,如:

int adaptation_field_length = (byte)_ts_buf[4]; 

而不要:int adaptation_field_length = (int)_ts_buf[4]; 


对于PES_packet_lengh为0的情况,采用检测下一个PES包起始位减去当前起始位的方式获取包长度。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值