MPEG PSProgram Stream是MPEG-2标准ISO/IEC 13818-1中定义的一种容器格式主要用于将音视频等基本流复用为一个单一数据流以便于存储或传输。封装基本单元与流程MPEG PS封装的核心思想是将PESPacketized Elementary Stream包打包成PS 包。PES包本身是由原始的ESElementary Stream如H.264视频流或G.711音频流加上PES包头包含时间戳等信息封装而成的。封装流程通常遵循以下规则视频关键帧如H.264的IDR帧其PS包结构通常为PS Header→System Header→PSM→PES Header视频数据如SPS, PPS, IDR帧。这是因为SPS和PPS是解码器初始化所必需的信息需要与关键帧放在一起以确保能正确开始解码。视频非关键帧如P帧、B帧结构较简单通常为PS Header→PES Header视频数据。音频帧音频数据会被打包成音频PES包通常与视频PES包交错排列在PS包中形如PS Header→PES(video)→PES(audio)MPEG-PS 的分层结构MPEG-PS Program Stream ┌──────────────────────────────────────────┐ │ Pack (以0x000001BA开头) │ │ ┌───────────────────────────────────┐ │ │ │ Pack Header (SCR, mux_rate) │ │ │ └───────────────────────────────────┘ │ │ ┌───────────────────────────────────┐ │ │ │ System Header (可选全局流信息) │ │ │ └───────────────────────────────────┘ │ │ ┌────────────────────────────┐ ┌────────────────────────────┐ │ │ PES Packet (Video) │ │ PES Packet (Audio) │ │ │ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │ │ │ │ PES Header (PTS/DTS) │ │ │ │ PES Header (PTS/DTS) │ │ │ │ └───────────────────────┘ │ │ └───────────────────────┘ │ │ │ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │ │ │ │ Video ES (如I/P/B帧) │ │ │ │ Audio ES (音频帧) │ │ │ │ └───────────────────────┘ │ │ └───────────────────────┘ │ │ └────────────────────────────┘ └────────────────────────────┘ └──────────────────────────────────────────┘MPEG-PS 可能的分包方式(1) 每个NAL组成一个PES包SPSPPS都分别作为一个PES包。I帧被拆分成了多个PES每个PES分包小于1400。当PS作为RTP负载用于网络流传输时RTP 包的总大小通常受网络 MTU Maximum Transmission Unit 1400的限制。(1) 多个NAL组成一个PES包有下图可见多个SPS PPSI, P, B 帧共同组成了一个PES。这个PES很大10514 Byte一个 MPEG-PS 的十六进制片段并逐字段解析示例MPEG-PS 文件开头部分(十六进制)0000: 00 00 01 BA 44 00 04 00 04 01 01 89 C3 F8 00 00 0010: 01 BB 00 0C 80 04 E2 1F FF FF C4 F9 00 00 01 E0 0020: 00 20 80 80 05 21 00 07 FF E1 00 00 01 67 4D 00 0030: E0 2C 0D 0D 0D 13 01 01 01 01 12 00 00 01 B5 14(1) Pack Header 以0x00 00 01 BA开始00 00 01 BA → pack_start_code 44 00 04 00... → SCR (System Clock Reference系统时钟参考) 01 01 89 → mux_rate0x000001BAPack start code。SCR对应时间戳基准用于系统时钟同步。mux_rate表示码率通常表示播放码率对齐。(2) System Header以0x00 00 01 BB开始00 00 01 BB → system_header_start_code定义了整体系统层 码率限制等。在文件开头区域经常出现一次或者每个I帧前面出现不一定每个 pack 都有。参考 ITU H.222.0 Table 2-40(3) Program stream map (PSM)以0x00 00 01 BC开始00 00 01 BC → program_stream_map_start_code在文件开头区域经常出现一次或者每个I帧前面出现不一定每个 pack 都有。PSM的核心作用主要体现在流识别与导航解码器通过解析PSM可以知道当前PS流中包含了几个音视频流、每个流是什么编码格式如H.264、H.265、G.711音频等以及它们对应的PES包头的stream_id是什么。这样,当解码器在流中遇到一个以0xE0开头的PES包时就能根据PSM知道这里面是H.264视频数据并交给相应的视频解码器处理map_stream_id: 总是0xBC举个例子伪解析假设我们解析到一个 PSM:packet_start_code_prefix0x000001stream_id0xBCprogram_stream_map_length24elementary_stream_map_length12// elementary_stream_info[0]:stream_type0x1B(H.264)elementary_stream_id0xE0// elementary_stream_info[1]:stream_type0x04(MPEG-2Audio)elementary_stream_id0xC0解释0xE0 (Video stream 0) → H.264 视频流0xC0 (Audio stream 0) → MPEG-2 音频流这样解码器就可以正确地把数据交给相应的解码模块一些常见的 stream_type 值stream_type含义0x01MPEG-1 Video0x02MPEG-2 Video0x03MPEG-1 Audio0x04MPEG-2 Audio0x0FAAC Audio0x1BH.264/AVC Video0x24H.265/HEVC Video0x90~0xFF私有或厂商扩展类型详细参考 ITU H.222.0 Table 2-41(4) PES Packet视频流start code 0x00 00 01 E000 00 01 E0 → video_stream_id 00 20 → PES_packet_length 320xE0表示视频流 0第一个视频轨道。PTS_DTS_flags表示是否包含PTS/DTSPES Header 包含时间戳PTSPresentation Time Stamp。DTSDecoding Time Stamp若有B帧。详细参考 ITU H.222.0 chapter 2.4.3.6 Table 2-21。 TS和PS共用同一个标准.(5) ES视频数据片段 (以h264为例)00 00 01 67 → sps_header_code (h264 Video)PES Payload 部分就是编码后的h264 Video ES 数据。H.264采用 Annex B 格式0x00000167H264 SPS NAL start code0x00000168H264 PPS NAL start code0x00000165H264 I frame NAL start code⏰时间信息与同步PS封装中包含重要的时间信息以实现音视频同步SCR (System Clock Reference)存在于PS Header中用于系统时钟同步。PTS (Presentation Time Stamp)和DTS (Decoding Time Stamp)存在于PES包头中分别指示显示时间和解码时间对于音视频同步至关重要。主要应用场景安防监控与GB28181在安防领域尤其是在*GB28181**标准中规定可采用PS封装 over RTP进行视音频数据的网络传输。参考 GB28181 RTP的封装规范DVD光盘存储PS格式最初就是为DVD这类可靠稳定的存储介质设计的但是DVD基本上没人用了。