mpeg-ps视频流

写在前面

  • 学习流媒体的代码中,对于如何获取ps视频流中的实际视频数据产生疑问,所以结合文档编写了一个ps视频流解析器,同时收集部分知识列举在这里。

ps_parser ps视频流文件解析器

  • 通过解析ps文件打印出ps中的视频信息
  • 跳过音频帧
  • 解析ps格式

PsHeader格式

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开始)

packHeader 字段格式

字段名 长度(字节) 描述
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)

systemHeader 字段格式

字段名 长度(字节) 描述
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 (实际音/视频数据)              │
└────────────────────────────────────────────┘

PES header 头信息

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)。

参考文档

相关推荐
ningqw2 小时前
SpringBoot 常用跨域处理方案
java·后端·springboot
你的人类朋友2 小时前
vi编辑器命令常用操作整理(持续更新)
后端
胡gh2 小时前
简单又复杂,难道只能说一个有箭头一个没箭头?这种问题该怎么回答?
javascript·后端·面试
一只叫煤球的猫3 小时前
看到同事设计的表结构我人麻了!聊聊怎么更好去设计数据库表
后端·mysql·面试
uzong3 小时前
技术人如何对客做好沟通(上篇)
后端
颜如玉4 小时前
Redis scan高位进位加法机制浅析
redis·后端·开源
Moment4 小时前
毕业一年了,分享一下我的四个开源项目!😊😊😊
前端·后端·开源
why技术5 小时前
在我眼里,这就是天才般的算法!
后端·面试
绝无仅有5 小时前
Jenkins+docker 微服务实现自动化部署安装和部署过程
后端·面试·github
程序视点5 小时前
Escrcpy 3.0投屏控制软件使用教程:无线/有线连接+虚拟显示功能详解
前端·后端