请求详解MPEG2 TS(Transport Stream)字节结构、音视频负载机制并附示例
我来帮你把MPEG-2 TS的字节结构拆得明明白白,再给你实打实的字节示例,这样你就能把轨道信息的逻辑彻底搞懂!
MPEG-2 TS 核心字节结构拆解
先敲个重点:每个TS包固定188字节,开头是0x47同步字节,剩下187字节由可变长度头部(4-16字节) + 负载数据组成。
一、TS包头部:必懂的基础字段
头部紧跟同步字节,核心字段按顺序拆解:
- 传输错误指示(1bit):
0代表包无错误,1表示包损坏(直接跳过即可) - 有效负载单元起始指示(1bit):
1意味着负载开头是新的PES/PSI表起始(比如PAT/PMT的开头),0则是上一个数据的续传 - 传输优先级(1bit):
1标记高优先级流,0为普通优先级 - PID(13bit):最关键的字段!用来区分不同类型的流:
0x0000= PAT表(节目关联表,找PMT的入口)0x0001= CAT表(条件访问,用于加密流)0x0002-0x000F= 系统预留PID- 其他PID对应PMT、音视频PES流等
- 传输加扰控制(2bit):
00未加密,01/10加密(对应不同密钥),11未定义 - 自适应字段控制(2bit):决定头部是否包含自适应字段:
01:仅基础头部(固定4字节,最常见)11:基础头部+自适应字段(头部长度=4+自适应字段长度)00/10:很少见,分别代表无负载/仅自适应字段
- 连续计数器(4bit):同PID的包会从0-15循环计数,用来检测丢包
头部字节示例(基础4字节版)
0x47 0x40 0x00 0x10
拆解细节:
0x47:同步字节,固定不变0x40(二进制01000000):错误指示0,有效负载起始1,优先级0,PID高5位000000x00:PID低8位00000000→ 完整PID=0x0000(对应PAT表)0x10(二进制00010000):加扰控制00,自适应字段控制01,连续计数器0000
二、负载里的音视频轨道信息:靠PSI表传递
这里要澄清一个误区:TS包的负载不会直接存储轨道信息,而是通过PSI(节目特定信息)表来描述,核心是PAT和PMT两个表:
1. PAT表(PID=0x0000):找到PMT的入口
PAT的作用是告诉我们:每个节目对应的PMT表用的是哪个PID。
PAT完整TS包示例(简化核心部分)
0x47 0x40 0x00 0x10 // 同步字节+头部(有效负载起始=1,PID=0x0000) 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x0A // PAT表起始:表ID=0x00,section长度=0x000A(实际10字节) 0x00 0x01 // 节目号=0x0001(第一个节目) 0xE0 0x01 // PMT的PID=0x0001(高2位是固定标识,去掉后为0x0001) 0x00 0x00 // CRC校验码(简化示例) // 剩余字节为填充数据(凑满188字节)
2. PMT表(PID由PAT指定):音视频轨道的详细清单
PMT是核心,里面会列出当前节目下所有音视频流的PID,以及对应的编码类型:
PMT完整TS包示例(简化核心部分)
0x47 0x40 0x01 0x11 // 同步字节+头部(有效负载起始=1,PID=0x0001,连续计数器=1) 0x02 0x00 0x10 0x00 0x00 0x00 0x00 0x16 // PMT表起始:表ID=0x02,section长度=0x0016(实际22字节) 0x00 0x01 // 节目号=0x0001(和PAT对应) 0xE0 0x10 // PCR时钟参考的PID=0x0010(通常和视频流PID一致) 0x00 0x00 // 节目信息长度=0(无额外描述) // 第一个流(视频): 0x1B // 流类型=0x1B(H.262/MPEG-2视频,最常用) 0xE0 0x10 // 视频流PID=0x0010 0x00 0x00 // ES信息长度=0(无额外编码参数) // 第二个流(音频): 0x03 // 流类型=0x03(MP2音频) 0xE0 0x11 // 音频流PID=0x0011 0x00 0x00 // ES信息长度=0 0xXX 0xXX 0xXX 0xXX // CRC校验码 // 剩余字节为填充数据
常见流类型对应:
0x1B:H.262/MPEG-2视频0x1E:H.264视频0x10:AAC音频0x03:MP2音频0x01:MPEG-1视频
三、实际音视频负载:PES包
当你拿到视频/音频流的PID(比如上面的0x0010),对应的TS包负载就是PES(分组 Elementary Stream)包,PES开头有自己的头部(包含时间戳PTS/DTS),后面才是真正的音视频编码数据:
PES包起始示例
0x00 0x00 0x01 0xE0 // PES起始码前缀(固定0x000001)+ 流ID=0xE0(视频流) 0x00 0x0C // PES包长度=12字节 0x80 0x80 // PES头部标志:标记PTS/DTS存在 0x05 // PES头部长度=5字节 0x21 0xXX 0xXX 0xXX 0xXX // PTS时间戳(5字节,用于音视频同步) // 后面就是H.262编码的NAL单元数据
四、快速上手小技巧
- 用工具辅助分析:比如
tsduck(命令行工具,tsdump可直接解析TS包每个字段),或者Elecard Stream Eye(可视化分析工具) - 自己生成测试文件:用
ffmpeg生成极简TS流,比如ffmpeg -i input.mp4 -c:v mpeg2video -c:a mp2 output.ts,然后用十六进制编辑器打开对照结构
内容的提问来源于stack exchange,提问作者Manobendronath Biswas
相关产品推荐
相关产品推荐

