TS 文件格式解析

https://blog.csdn.net/cabbage2008/article/details/49281729

TS 流都是固定等长的188字节包



如下图所示 用UltraEdit打开的一个TS流,我们发现每隔188个字节就有一个47(可以看做是包头)


TS的包头占用四个字节

以第一个包为例:

47 60 00 10 00 00 B0 0D 00 00 C1 00 00 00 01 E0
81 0C 8C BE 32 FF FF ……………………………..
………………………………………………………
………………………………………………………
………………………………….FF

我们将其按照位进行划分 (0~31位,共4个字节 32位)

1. 0~7    位: 同步位置   第一个字节 如 十六进制 47  (01000111)

2. 8~10  位: 第9位是有效载荷单元起始符:(1表示起始符 0 表示后续数据) 一个TS包是188字节  而一帧数据远远大于188字节  所以一帧数据被拆分成多个TS包。
                              起始符为1 的表示该帧的第一个TS包 里面含有当前帧的描述信息 PTS(Presentation Time
                                       Stamp)表示该帧数据的时间位置以及当前帧含有的数据量(TS包个数,大部分不描述
                                        用0代替)
                              起始符为0的TS包  存放当前帧的剩余信息
                          只会出现三个十六进制数字之一: 0 4 6,其它说明包错误    如当前为 6

                         0: 二进制 0000  (有效载荷单元起始符 为0)   这里借用了PID一位
                         4: 二进制 0100  (有效载荷单元起始符 为1)   这里借用了PID一位
                         6: 二进制 0110  (有效载荷单元起始符 为1)   这里借用了PID一位

3. 11~23位:PID(packet ID)  是每个节目的唯一标识    如当前为 0 0 0 (第一个包为 000)(除了pid=000 标识第一个包  其它数字都是随机可选的  无须按某种序列排序)

4. 24~27位:四位刚好可以用一个16进制数字标识   这里表示其负载类型 (其存放有效数据)    当前为1 表示负载中只有有效载荷
                        0:保留值,供未来使用   (碰到丢弃即可)
                        1:负载中只有有效载荷
                        2:负载中只有自适应字段
                        3:先有自适应字段,再有有效载荷
                        
                        自适应字段长度, 占一个字节
                        自适应字段内容,占得字节由长度自适应字段长度决定,多余的字节用0xFF填充

5.28~31位:无须考虑  直接跳过  简单理解为相同PID的顺序码

PES  (Packetized Elementary Stream) 打包的元流 简单说一个个PES包去掉PES包头剩下的就是一帧帧的数据

 有效载荷单元起始符 为1 的TS包会含有部分PES包头

一个TS流由一组组188字节的包组成

所有的事务都是有始有终,如何寻找第一个TS包将是我们本节的主题。



如图所示,一般来说第一个TS包一般在第一个位置,本例举出一个特殊情况

在寻找第一个TS包时,不断读取TS包,直到找到pid=000的位置,并将读取过的TS包置入缓冲区

本节将粗略讲述在确定好第一个包位置后如何找后续包

一个TS流如下图所示:


第一个TS包

47 60 00 10 00 00 B0 0D 00 00 C1 00 00 00 01E0
81 0
C 8C BE 32 FF FF ……………………………..
………………………………………………………
………………………………………………………
………………………………….FF

包头:47 60 00 10 

指针:00

tableid:00

固定值:B

section_length:0 0D(值:13)

transport_stream_id:00 00

version number & current_next_indicator:C1

section_number:00

last_section_number:00

program_number:00 01

program_map_PID:E081  (PMT的pid为081 前三位为保留位)

CRC_32:0C 8C BE 32 

第二个TS包

47 60 81 10   (47 同步字节  6 说明数据正确  pid = 081  1 负载中只含有有效载荷)

00 02 B0 17 00 01 C1 00 00 E8 10 F0 00  1B E8 10
F0 00  03 E8 14  F0 00 66 74 A4 2D FF FF FF FF FF
...................................................................................
...................................................................................
...................................................................................

.......................................................................FF

包头:47 60 81 10   (47 同步字节  6 说明数据正确  pid = 081  1 负载中只含有有效载荷)
指针:00
tableid:02
固定值:B
section_length:0 17(值:23 表示到后面FF总共有23个字节)
program_number:00 01
reserved&version_number&current_next_indicator:C1
section_number:00
last_section_number:00
PCR_PID:E8 10
program_info_length: F0 00 (前四位不算 后12位表示后面节目描述信息长度 此处无)
此时剩余23-9=14字节-4字节(CRC)  = 10字节/5 = 2  N=2 此处有两个流类型
第一流类型:
stream_type: 1B  H264流
elementary_PID:E8 10 前3位为保留位取后13位  则PID=810 表示此PID的都是H264流
ES_info_length:F0 00 前4位为保留位 后12位为描述信息长度 此处为0
第二流类型:
stream_type: 03  音频流
elementary_PID:E8 14  前3位为保留位取后13位  则PID=814 表示此PID的都是音频流
ES_info_length:F0 00 前4位为保留位 后12位为描述信息长度 此处为0


CRC: 66 74 A4 2D

03 E8 14 : 03 表示流是音频流 MP3 格式   814  表示  pid=814 的TS包存储的是MP3格式的音频流

1B E8 10: 1B表示流是视频流h264格式    810  表示  pid=810 的TS包存储的是h264格式的视频流


第一个TS包 一般叫做 PAT (Program Association Table,节目相关表)

第二个TS包 一般叫做PMT  (Program Map Table,节目映射表)


第三个TS包

00000170h: 47 48 14 10 00 00 01 C0 (PTD 为814 前面 4 说明含有有效载荷起始符为1 含有PES包头)
00000180h: 01 88 80 80 05 21 00 01 96 07 FF FD 85 00 33 22
00000190h: 22 11 22 11 11 11 11 11 11 24 82 41 00 90 40 00
000001a0h: 00 00 00 00 40 00 .................................................
...............................................................................
................................................................................
00000220h: 70 34 5B CE 64 B7 D2 F5 4E 07 50 8E 11 1E 60 61
00000230h: 21 32 11 59

第四个TS包
00000230h: 47 08 14 11 68 4D 8C CB A7 24 92 45   (PTD 为814 前面为 0 说明有效载荷起始符为0 不含有PES包头)
00000240h: B8 EE A7 1C C4 ……………………………….
…………………………………………………………………….
…………………………………………………………………….
000002e0h:C8 31 B5 59 8C B7 3A 7B 53 9D AB 73 54 E6 D8 0D
47(同步字节)0(0 说明有效载荷起始符为0 不含有PES包头)
814PID  1 (负载中只有有效载荷,没有自适应字段,后面的都是一帧数据 本例为MP3(由第二个TS包知道))

第五个TS包
000002f0h:47 08 14 32 99 00 FF FF FF FF FF FF FF FF FF FF
00000300h:FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
…………………………………………………………………….
…………………………………………………………………….
…………………………………………………………………….
00000380h:FF FF FF FF FF FF FF FF FF FF FF FF FF FF 52 DE
00000390h:E6 B5 D0 76 CD CB B2 24 B3 92 AD 4E CD 19 D2 CC
000003a0h:82 D4 78 10 80 6C 0E 99 49 A4 59 C0
47(同步字节)0(0 说明有效载荷起始符为0 不含有PES包头)
814PID  3 (先有自适应字段,再有有效载荷)
自适应字段长度: 0x 99   表示占用 153个字节
00: 各个指示器都为0 表示不含其它信息
跳到第153个字节 到52 开始时真正的帧数据

第六个TS包
000003a0h: 47 48 14 13
000003b0h:00 00 01 C0 01 88 80 80 05 21 00 01 A6 E7 FF FD
000003c0h:85 00 54 44 22 22 34 21 12 11 22 22 21 48 90 00
....................................................................................................
....................................................................................................
....................................................................................................
00000460h:B4 12 54 02 48 19 F3 D8
47(同步字节)4(4 说明含有有效载荷起始符为1 含有PES包头)
814PID  1 (负载中只有有效载荷,没有自适应字段,后面的都是一帧数据 本例为MP3(由第二个TS包知道))

注意: 本TS包 又包含PES头信息 说明开始下一帧

第七个TS包
00000460h: 47 48 10 30 07 10 00 00
00000470h:01 0F 7E 88 00 00 01 E0 00 00 80 C0 0A 31 00 01
00000480h:96 07 11 00 01 7E 91 00 00 00 01 67 4D 40 1E 96
…………………………………………………………………
…………………………………………………………………
…………………………………………………………………
00000520h:D2 99 71 F3
47(同步字节)4(4 说明含有有效载荷起始符为1 含有PES包头)
810PID  3 (先有自适应字段,再有有效载荷,后面的都是一帧数据 本例为h264(由第二个TS包知道) 流ID E0
自适应字段长度, 0x07  说明后面7个字节后为PES包头或者h264数据

第八个TS包
00000520h: 47 08 10 11 64 C9 FC 5A 40 40 BD 8C
……………………………………………………………………
……………………………………………………………………
…………………………………………………………………….
000005d0h:18 91 2F 18 98 2D B2 AF EE 0E 3D 53 FB B2 91 FE
47(同步字节)0(0 说明有效载荷起始符为0 不含有PES包头)
810PID  1 (负载中只有有效载荷,没有自适应字段,后面的都是一帧数据 本例为h264(由第二个TS包知道))

1. 首先找到PID为0x00的TS包,找到里面的节目映射表(PMT)PID,因为可能有几个节目信息。所以可能有几个PMT_PID,以一个为例

2.接着查找该PMT_PID的TS包,通常就紧接着。在该PMT包中找音频和视频的PID。以视频为例。

3.开始提取一帧ES数据“

   3.1  查找视频PID的TS包

   3.2  找PES包头,方法:TS包头第2个字节的高6位(有效载荷单元起始指示符)为1的TS包,跳过自适应字段,找到PES包头,提取时间戳,再跳至ES数据,这就是一帧ES数据的开始部分。

  3.3  查找有效载荷单元起始指示符为0的TS包。跳过TS包头,跳过自适应字段,提取后面的ES数据

  3.4  同3.3接着查找

  3.5  当碰到有效载荷单元起始指示符又变为1的视频TS包,就知道这是下一帧的开始了,将前面的所有ES数据组合成一帧数据。开始下一轮组帧。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值