PS流包格式
1,PS流的基本组成
PS流由很多个PS包组成.
每个PS包由如下组成:
PS header + SYS header(I帧)+PSM header(I帧) +PES header+ PES packet n
如:
不含音频非I帧顺序为:PS header | PES header | h264raw data
含音频顺序如下:PS 包=PS头|PES(video)|PES(audio)
PS包主要由固定包头,系统头,和PES包组成,其具体组成如下图所示:

PS流总是以0x000001BA开始,以0x000001B9结束,对于一个PS文件,有且只有一个结束码0x000001B9,不过对于网传的PS流,则应该是没有结束码的.

1.1 PS header:

PS头最小长度14个字节
pack_start_code字段:起始码,占位32bit,标识PS包的开始,固定为0x000001BA;

program_mux_rate字段:速率值字段,占位22bit,正整数,表示P-STD接收此字段所在包的PS流的速率;这个值以每秒50字节作为单位;禁止0值;
Marker_bit:标记字段,占位1bit,固定为’1’;
Marker_bit:标记字段,占位1bit,固定为’1’;
stuffing_byte:填充字段,固定为0xFF;长度由pack_stuffing_length确定;

1.2 system header
system header 只有关键帧的时候,才会存在

 system_header_start_code字段:系统头部起始码,占位32bit,值固定为0x000001BB,标志系统首部的开始;
 header_length字段:头部长度字段,占位16bit,表示此字段之后的系统首部字节长度;
SYS头长度18个字节,则header_length=18-4-2=18-6=12
 Marker_bit字段:占位1bit,固定值为1;
 rate_bound字段:整数值,占位22bit,为一个大于或等于PS流所有PS包中的最大program_mux_rate值的整数;可以被解码器用来判断是否可以对整个流进行解码;
 Marker_bit字段:占位1bit,固定值为1;
 audio_bound字段:占位6bit;取值范围0到32间整数;大于或等于同时进行解码处理的PS流中的音频流的最大数目;
 fixed_flag字段:标志位,占位1bit;置位1表示固定比特率操作,置位0则为可变比特率操作;
 CSPS_flag字段:CSPS标志位,占位1bit;置位1表示此PS流满足标准的限制;
 system_audio_lock_flag字段:标志位,占位1bit,表示音频采样率和STD的system_clock_frequency之间有一特定常数比例关系;
 system_video_lock_flag字段:标志位,占位1bit,表示在系统目标解码器system_clock_frequency和视频帧速率之间存在一特定常数比例关系;
 Marker_bit字段:占位1bit,固定值为1;
 video_bound字段:整数,占位5bit,取值范围0到16;大于或等于同时进行解码处理的PS流中的视频流的最大数目;
 packet_rate_restriction_flag字段:分组速率限制标志字段,占位1bit,若CSPS_flag == 1,则此字段表示哪种限制适用于分组速率;若CSPS_flag == 0,则此字段无意义;
 reserved_bits字段:保留字段,占位7bit,固定为’1111111’;

若stream_id ==’1011 1000’,则其后的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段对应PS流中的所有音频流;若stream_id ==’1011 1001’,则其后的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段对应PS流中的所有视频流;若取其他值,则应大于’1011 1100’,且按照标准对应Stream id(详见附录1)
 P-STD_buffer_bound_scale字段:占位1bit,表示用来解释后面P-STD_buffer_size_bound字段的比例因子;如果之前的stream_id表示音频流,则此值应为0,若之前的stream_id表示视频流,则此值应为1,对于其他stream类型,此值可以0或1;
 P-STD_buffer_size_bound字段:占位13bit,无符号整数;大于或等于所有PS流分组的P-STD输入缓冲区大小BSn的最大值;若P-STD_buffer_bound_scale == 0,则P-STD_buffer_size_bound以128字节为单位;若P-STD_buffer_bound_scale == 1,则P-STD_buffer_size_bound以1024字节为单位;
在恒定比特率的操作期间,system_clock_reference字段值应遵从下面的线性公式:
SCR_base(i)=((c1×i+c2) DIV 300) % 233
SCR_ext(i)=((c1×i+c2) DIV 300) % 300
其中:c1 对所有i均有效的实型常数;c2 对所有i均有效的实型常数;
i 在GB/T XXXX.1复合流中包含任何system_clock_reference字段的最后一位的字节索引。
system_video_lock_flag =1 时 SCFR=system_clock_frequency / frame_rate_in_the_P-STD

system_audio_lock_flag =1时
SCASR=(system_clock_frequency) / audio_sample_rate_in_the_P-STD

1.3 PSM header
目前的系统头部好像是没有用到的,所以对于系统头部的解析,我们一般只要先首先判断是否存在系统头(根据系统头的起始码0x000001BB),然后我们读取系统头的头部长度,即header_length部分,然后根据系统头部的长度,跳过PS系统头,进入下一个部分,即PS的payload,PES包;在固定包头和系统头之后,就是PS包的payload,即PES包;若PSM存在,则第一个PES包即为PSM。
PSM只有关键帧的时候,才会存在。PSM用来提供es流的描述信息,以及各es流之间的关系。
IDR包含了SPS,PPS和I帧;每个IDR NALU前一般都会包含SPS、PPS等NALU,因此将SPS、PPS、IDR的NALU 封装为一个PS 包,包括PS头,PS system header,PSM,PES;所以一个IDR NALU PS 包由外到内顺序是:PS header| PS system header | PSM| PES。对于其它非关键帧的PS包,就简单多了,直接加上PS头和PES 头就可以了。顺序为:PS header | PES header | h264raw data。以上是对只有视频video 的情况,如果要把音频Audio也打包进PS 封装,只需将数据加上PES header 放到视频PES 后就可以了。顺序如下:PS 包=PS头|PES(video)|PES(audio);

 Packet start code prefix字段:包头起始码,固定为0x000001,占位24bit;与后面的字段map_stream_id一起组成分组开始码,标志着分组的开始;
 map_stream_id字段:类型字段,标志此分组是什么类型,占位8bit;如果此值为0xBC,则说明此PES包为PSM;
 program_stream_map_length字段:长度字段,占位16bit;表示此字段之后PSM的总长度,最大值为1018(0x3FA);
 current_next_indicator字段:标识符,占位1bit;置位1表示当前PSM是可用的,置位0则表示当前PSM不可以,下一个可用;
 program_stream_map_version字段:版本字段,占位5bit;表示PSM的版本号,取值范围1到32,随着PSM定义的改变循环累加;若current_next_indicator == 1,表示当前PSM的版本号,若current_next_indicator == 0,表示下一个PSM的版本号;
 elementary_stream_map_length字段:长度字段,占位16bit;表示在这个PSM中所有ES流信息的总长度;包括stream_type, elementary_stream_id, elementary_stream_info_length的长度,即N*32bit;是不包括具体ES流描述信息descriptor的长度的;
 stream_type字段:类型字段,占位8bit;表示原始流ES的类型;这个类型只能标志包含在PES包中的ES流类型;值0x05是被禁止的;常见取值类型有MPEG-4 视频流:0x10;H.264 视频流:0x1B;G.711 音频流:0x90;因为PSM只有在关键帧打包的时候,才会存在,所以如果要判断PS打包的流编码类型,就根据这个字段来判断;

 elementary_stream_id字段:流ID字段,占位8bit;表示此ES流所在PES分组包头中的stream_id字段的值;其中0x(C0DF)指音频,0x(E0EF)为视频;

1.4 PES header



PES包的起始码是(0x000001), 起始码之后是stream_id(1个字节), 在之后的两个字节是PES包的长度,再往后的两个字节不用理,再往后的一个字节说明了PES header的长度,PES header 之后就是 PES的负载了,即ES流。
 PES分组长度字段 PES_packet_length
16位字段,指出了PES分组中跟在该字段后的字节数目,通常是静荷长度+13(该字段后本身头结构的长度)。
 PTS DTS标志字段 PTS_DTS_flags
2位字段。当值为’10’时,PTS字段应出现在PES分组标题中;当值为’11’时,PTS字段和DTS字段都应出现在PES分组标题中;当值为’00’时,PTS字段和DTS字段都不出现在PES分组标题中。值’01’是不允许的。
 PES标题数据长度字段 PES_header_data_length
8位字段。指出包含在PES分组标题中的可选字段和任何填充字节所占用的总字节数。该字段之前的字节指出了有无可选字段。
 展现时间戳字段 PTS , 解码时间戳字段 DTS
PTS/DTS的值以系统时钟频率的1/300(即90 kHz)为单位。 system_clock_frequency =300*90000=27M
对编码展现时间戳频率的约束:
PTS(k)=((system_clock_frequency×tpn(k)) DIV 300) % 233
其中,tpn(k)是展现单元Pn(k)的展现时间,即每帧的时间戳(ms).
DTS(j)=((system_clock_frequency×tdn(j)) DIV 300) % 233
其中,tdn(j)是存取单元An(j)的解码时间。
其中PTS和DTS使用的是90KHZ时钟单位,即1PTS表示1/90000秒,PTS和DTS虽然是33位,但占用了5个字节.
如: tp(n)= 1547524052, (2019/1/15 11:47:32)
PTS(n)= tp(n)27M/300=154752405290000
如果是以微妙为单位,即tp(k)= tp(n)*1000000us,
PTS(n)= tp(n)*27M/300=(tp(k)/1000000)271000000/300=tp(k)*9/100;
 特技方式控制字段 trick_mode_control

 片内参考字段 intra_slice_refresh
1位标志。置’1’时表示PES分组的视频数据编码片中可能有丢失的宏块;置’0’时,表示上述情况可能不出现。更多的信息可参见GB/T XXXX.2。解码器可以用前一个解码画面中同一个位置的宏块来代替丢失的宏块。
 填充字节字段 stuffing_byte
8位字段,其值恒定为’1111 1111’。可以由编码器插入以满足通道的需求等。解码器丢弃该字段。一个PES分组标题中只能出现32个填充字节。
 PES分组数据字节字段 PES_packet_data_byte
该字段应该是来自于由分组的stream_id或PID所指定的基本流的连续数据字节。当基本流数据符合GB/T XXXX.2或GB/T XXXX.3时,该字段应该是与本标准的字节相对齐的字节。基本流的字节序应得到保持。该字段的字节数N由PES_packet_length字段规定。N应等于PES_packet_length减去在PES_packet_length字段的最后一个字节与第一个 PES_packet_data_byte间的字节数。

 结构图

再来看另一图:

PS流包格式之PS/SYS/PSM/PES头相关推荐

  1. GB28181 PS流传输格式详解

    1.PS流传输格式预览 1.视频关键帧的封装 RTP + PS header + PS system header + PS system Map + PES header +h264 data 2. ...

  2. ps流组成 PS封装 (PS+SYS+PSM+PES+RAW )概述

    在工作中,招标时要对设备进行gb28181检测,需要对音视频数据进行封装,封装方式为PS流,封装实现如下: 简要概述:整体机制均有udp发送,发送的数据要封装为rtp格式,rtp负载即为PS流. PS ...

  3. ffmpeg解码ps流部分代码以及PS播放器demo

    之前的设备研发算是告一段落了,最近一直在忙视频监控平台的架构以及实现,想把自己的设备接到自己的平台里,设备上的码流是ps流,要在平台里解码ps流->解码成h264->yuv->rgb ...

  4. PES,TS,PS,RTP等流的打包格式解析之PS流

    本篇描述PS流的封装格式 1.PS头封装格式 PS流是对PES的进一步封装,是将具有共同时间基准的一个或多个PES包组合而成的单一的数据流:其基本单位是PS包,PS流由很多个PS包组成,PS包主要由固 ...

  5. 音视频学习(十)——ps流

    1. 简介 PS的封装格式需要支持MPEG2/MPEG4/H.264等视频和MPEG系列的音频,支持在多个层次加入私有数据,方便解码.拖动和加入延时,同时考虑到标准的PS.TS 和 RTP 封装方式间 ...

  6. 通过海康SDK预览获取回调的PS流数据自己解析然后前端播放

    最近在玩视频相关的,也算是一步一步的深入吧. 第一版: 用海康SDK进行历史数据下载: https://blog.csdn.net/qq_16504067/article/details/114538 ...

  7. RTP载荷PS流全面分析

    1.PS流封包格式 视频关键帧的封装:    RTP|PS header|PS system header|PS system Map|PES header|H264 data 视频非关键帧的封装:R ...

  8. PS流详解(载荷H264)

    目录 PS简介 标准结构 标准H264流结构 定长音频帧和其他流式私有数据的结构 PS流封装标准 PSH结构 PES包结构 PSM包结构体 元素流 PS 封装规则 H264元素流封装规则 音频元素流封 ...

  9. 对海康28181摄像头PS流解码的支持(一)

    背景 我们的项目是基于sip的IMS系统,需要添加对海康28181摄像头的支持,所以分为以下几步: 向海康摄像头发起点播请求,基于sip. PS流过来后,剥出h264流. 对h264流进行解码. 一. ...

最新文章

  1. MegEngine亚线性显存优化
  2. 电脑主板跳线_电脑基础进阶必学知识,详解电脑主板跳线!
  3. 机器学习数据预处理之缺失值:样本删除
  4. 众筹网02_项目环境搭建
  5. AAAI 2022 | 北航提出基于特征纯化的视线估计算法,让机器更好地“看见”
  6. drools dmn_使用Drools的DMN运行时示例
  7. Oracle网格控制器OMA端安装Yast
  8. 测试硬盘怀道的软件,硬盘坏道检测工具(HDDScan)
  9. 自动加减工单结存算法实现
  10. 微软修复了国家安全局上报的Windows严重漏洞
  11. 科学计数法 与 普通数字 转换
  12. 七彩虹计算机主板维修,七彩虹C .H61U v28主板维修一例
  13. RK3188 5.1平台PCM2708 USB声卡调试
  14. js 中 throttle 的实现
  15. java abcd_Java的一个小题目,字母abcd 对应1234类推,输入单词得到对应的数字和...
  16. @keyframes详解与实例
  17. Android的USB通信(AOA连接)
  18. 基于JAVA房屋租赁及其管理系统
  19. 如何破解SQLyog 企业版,无限期试用
  20. pat是什么意思中文_pat是什么意思

热门文章

  1. 刘可-寂寞才说爱 试听+下载+歌词
  2. 来听听一位『大龄程序员』的心声
  3. 豆瓣电台WP7客户端 开发记录1
  4. 经典励志文章:一碗阳春面
  5. 上海科技大学计算机浙江分数线,2018上海科技大学录取分数线
  6. 激战2电信服务器哪个最多,玩家浅谈 激战2电信一区服务器派系之争
  7. java毕业设计软件源代码SSM家庭理财|个人理财管理系统|记账系统
  8. 算法作业1:遍历与枚举
  9. 爬取豆瓣图书排行榜前十并使用图表的形式展示
  10. 艾兰岛编辑器-玩家角色