写在前面
- 学习流媒体的代码中,对于如何获取ps视频流中的实际视频数据产生疑问,所以结合文档编写了一个ps视频流解析器,同时收集部分知识列举在这里。
ps_parser ps视频流文件解析器
- 通过解析ps文件打印出ps中的视频信息
- 跳过音频帧
- 解析ps格式
c++
复制代码
┌──────────────────────────────┐
│ Program Stream (PS) │
├──────────────────────────────┤
│ Pack Header │ ← 🟢 Start Code: BA
├──────────────────────────────┤
│ System Header (可选) │ ← 🟡 Start Code: BB
├──────────────────────────────┤
│ Program Stream Map (可选) │ ← 🔷 Start Code: BC
├──────────────────────────────┤
│ PES Packet(s) │ ← 🎬 Start Code: E0 (视频), C0 (音频)
│ PES Packet(s) │
└──────────────────────────────┘
C++
复制代码
0x000001BA Pack Header(包头)
0x000001BB System Header(系统头)
0x000001BC Program Stream Map(程序流映射)
0x000001BD 私有流1(Private Stream 1,通常音频)
0x000001BE Padding Stream(填充流)
0x000001BF 私有流2(Private Stream 2)
0x000001E0~0x000001EF 视频流(0xE0开始)
0x000001C0~0x000001DF 音频流(0xC0开始)
字段名 |
长度(字节) |
描述 |
pack_start_code |
4 |
固定为 0x000001BA ,标识为 Pack Header |
system_clock_reference_base [32~30] |
3 bit |
SCR(系统时钟参考)高位,用于同步音视频 |
marker_bit |
1 bit |
必须为1,固定位 |
system_clock_reference_base [29~15] |
15 bit |
SCR 中间位 |
marker_bit |
1 bit |
必须为1 |
system_clock_reference_base [14~0] |
15 bit |
SCR 低位 |
marker_bit |
1 bit |
必须为1 |
system_clock_reference_extension |
9 bit |
SCR 的扩展部分 |
marker_bit |
1 bit |
必须为1 |
program_mux_rate |
22 bit |
码率(单位:50字节/秒) |
marker_bit |
1 bit |
必须为1 |
reserved |
5 bit |
保留位 |
pack_stuffing_length |
3 bit |
后续 stuffing 字节的数量(padding) |
字段名 |
长度(字节) |
描述 |
system_header_start_code |
4 |
固定为 0x000001BB ,标识为 System Header |
header_length |
2 |
剩余字段长度(不含前6字节) |
marker_bit |
1 bit |
必须为1 |
rate_bound |
22 bit |
最大码率(单位:50字节/秒) |
marker_bit |
1 bit |
必须为1 |
audio_bound |
6 bit |
最大音频流数量 |
fixed_flag |
1 bit |
固定比特率标志 |
CSPS_flag |
1 bit |
成分流同步标志 |
system_audio_lock_flag |
1 bit |
音频锁定标志 |
system_video_lock_flag |
1 bit |
视频锁定标志 |
marker_bit |
1 bit |
必须为1 |
video_bound |
5 bit |
最大视频流数量 |
packet_rate_restriction_flag |
1 bit |
包速率限制标志 |
reserved_bits |
7 bit |
保留位 |
stream_id (重复N次) |
1 |
流 ID(0xE0 开头为视频,0xC0 开头为音频) |
P_STD_buffer_bound_scale |
1 bit |
缓冲大小标志 |
P_STD_buffer_size_bound |
13 bit |
缓冲区大小 |
Program Stream Map 字段格式
字段名 |
长度(字节) |
描述 |
program_stream_map_start_code |
4 |
固定为 0x000001BC ,表示是 Program Stream Map |
program_stream_map_length |
2 |
后续字段总长度(不包括前6字节) |
current_next_indicator |
1 bit |
当前有效标志(一般为1) |
reserved_1 |
2 bit |
保留位 |
program_stream_map_version |
5 bit |
映射版本号 |
reserved_2 |
7 bit |
保留位 |
marker_bit |
1 bit |
必须为1 |
program_stream_info_length |
2 |
描述符区长度(可选信息) |
descriptor (可变) |
N |
若干描述符,长度为上面字段决定 |
elementary_stream_map_length |
2 |
Elementary stream 区长度 |
stream_type |
1 |
流类型(如 SVAC = 0x80,H.264 = 0x1B) |
elementary_stream_id |
1 |
对应的 ES 流 ID(例如视频一般是 0xE0) |
elementary_stream_info_length |
2 |
描述符区长度 |
descriptor (可变) |
N |
流相关的描述符 |
CRC_32 |
4 |
CRC 校验(ISO/IEC 13818-1 定义) |
pes packet 格式
C++
复制代码
┌────────────────────────────────────────────┐
│ PES Packet (Packetized ES) │
├────────────────────────────────────────────┤
│ Start Code Prefix: 0x000001 (3 bytes) │ ← 固定起始码
├────────────────────────────────────────────┤
│ Stream ID (1 byte) │ ← 如 E0: 视频, C0: 音频
├────────────────────────────────────────────┤
│ PES Packet Length (2 bytes) │ ← 从可选字段起的长度
├────────────────────────────────────────────┤
│ Optional PES Header (可选字段) │ ← 包含 PTS/DTS 等
├────────────────────────────────────────────┤
│ ES Payload (实际音/视频数据) │
└────────────────────────────────────────────┘
C++
复制代码
┌────────────────────────────────────────────┐
│ Optional PES Header Flags │
├────────────────────────────────────────────┤
│ '10' (2 bits) │ ← 固定值
│ Scrambling Control (2 bits) │ ← 是否加密
│ Priority / Alignment / Copyright... │ ← 共 8 位标志
├────────────────────────────────────────────┤
│ PTS_DTS_flags (2 bits) │ ← 是否含 PTS/DTS
│ ESCR_flag / ES_rate_flag / CRC_flag 等 │ ← 共 8 个控制标志
├────────────────────────────────────────────┤
│ PES_header_data_length (1 byte) │ ← 后续可选字段长度
├────────────────────────────────────────────┤
│ [PTS / DTS / ESCR / ES_rate / ...] │ ← 可选字段(依 flags 而定)
└────────────────────────────────────────────┘
字段名称 |
位数 |
长度(字节) |
内容定义 |
'10' |
2 位 |
- |
固定值 10 ,表示是 MPEG-2 PES。 |
Scrambling Control |
2 位 |
- |
是否加扰(00 表示未加扰)。 |
Priority |
1 位 |
- |
数据优先级(通常为0)。 |
Data Alignment Indicator |
1 位 |
- |
若为1表示此处对齐视频帧/音频帧起始点。 |
Copyright |
1 位 |
- |
是否为版权内容(通常为0)。 |
Original or Copy |
1 位 |
- |
是否为原始内容。 |
字段名称 |
位数 |
长度(字节) |
内容定义 |
PTS DTS Flags |
2 位 |
- |
10 表示有 PTS,11 表示有 PTS 和 DTS。 |
ESCR Flag |
1 位 |
- |
ESCR(扩展系统时钟参考)是否存在。 |
ES Rate Flag |
1 位 |
- |
ES(Elementary Stream)码率字段是否存在。 |
DSM Trick Mode Flag |
1 位 |
- |
是否包含 trick mode 数据(快进、快退等)。 |
Additional Copy Info Flag |
1 位 |
- |
是否包含复制信息。 |
PES CRC Flag |
1 位 |
- |
是否包含 CRC 校验。 |
PES Extension Flag |
1 位 |
- |
是否包含扩展字段。 |
PES Header Data Length |
8 位 |
1 字节 |
表示紧随其后的 header 数据长度(例如 PTS、DTS)。 |
参考文档