45.FFmpeg学习笔记 - ts格式解析2

如下图所示 用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包

47 60 00 10 00 00 B0 0D 00 00 C1 00 00 00 01E0
81 0C 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数据组合成一帧数据。开始下一轮组帧。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值