本篇描述PS流的封装格式

1.PS头封装格式

PS流是对PES的进一步封装,是将具有共同时间基准的一个或多个PES包组合而成的单一的数据流;其基本单位是PS包,PS流由很多个PS包组成,PS包主要由固定包头,系统头,和PES包组成,其具体组成如下图所示:

PS流有一个结束码MPEG_program_end_code:占位32bit,其值为0x000001B9,PS流总是以0x000001BA开始,以0x000001B9结束,对于一个PS文件,有且只有一个结束码0x000001B9,不过对于网传的PS流,则应该是没有结束码的;

具体PS包头字段组成顺序如下:

pack_start_code字段起始码,占位32bit,标识PS包的开始,固定为0x000001BA

‘01’字段占位2bit;

SCR字段:占位46bit,其中包含42bit的SCR值和4个bit的marker_bit值;其中SCR值由system_clock_reference_base和system_clock_reference_extension两部分组成;字节顺序依次是:

system_clock_reference_base [32..30]:占位3bit;

marker_bit:占位1bit;

system_clock_reference_base [29..15]:占位15bit;

marker_bit:占位1bit;

system_clock_reference_base [14..0]:占位15bit;

marker_bit:占位1bit;

system_clock_reference_extension:占位9bit;

marker_bit:占位1bit;

program_mux_rate字段速率值字段,占位22bit,正整数,表示P-STD接收此字段所在包的PS流的速率;这个值以每秒50字节作为单位;禁止0值;

Marker_bit标记字段,占位1bit,固定为’1’;

Marker_bit标记字段,占位1bit,固定为’1’;

Reserved字段:保留字段,占位5bit;

pack_stuffing_length字段长度字段,占位3bit;规定了此字段之后填充字段的长度;

stuffing_byte填充字段,固定为0xFF;长度由前一字段确定;

system_header字段:系统头部字段,只有当下一个字段的值为系统头部起始码0x000001BB时才存在,长度不定,其组成字段顺序如下所示:

system_header_start_code字段:系统头部起始码,占位32bit,值固定为0x000001BB,标志系统首部的开始;

header_length字段头部长度字段,占位16bit,表示此字段之后的系统首部字节长度;

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’;

LOOP:当下一个bit为1时进入

stream_id字段占位8bit,表示其后的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段所涉及的流的编码和基本流的号码;若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);PS流中的每个原始流都应在每个系统首部中通过这种机制精确地规定一次它的P-STD_buffer_bound_scale和P-STD_buffer_size_bound;

‘11’字段占位2bit;

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字节为单位;

LOOP End;

目前的系统头部好像是没有用到的,所以对于系统头部的解析,我们一般只要先首先判断是否存在系统头(根据系统头的起始码0x000001BB),然后我们读取系统头的头部长度,即header_length部分,然后根据系统头部的长度,跳过PS系统头,进入下一个部分,即PS的payload,PES包;在固定包头和系统头之后,就是PS包的payload,即PES包;若PSM存在,则第一个PES包即为PSM。

2.PSM格式介绍

PSM提供了对PS流中的原始流和他们之间的相互关系的描述信息;PSM是作为一个PES分组出现,当stream_id == 0xBC时,说明此PES包是一个PSM;PSM是紧跟在系统头部后面的;PSM是作为PS包的payload存在的;

PSM由很多字段组成,其字节顺序如下所示:

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不可以,下一个可用;

Reserved保留字段,占位2bit;

program_stream_map_version字段版本字段,占位5bit;表示PSM的版本号,取值范围1到32,随着PSM定义的改变循环累加;若current_next_indicator == 1,表示当前PSM的版本号,若current_next_indicator == 0,表示下一个PSM的版本号;

Reserved保留字段,占位7bit;

marker_bit标记字段,占位1bit,固定为1;

program_stream_info_length字段长度字段,占位16bit;表示此字段后面的descriptor字段的长度;

Descriptor字段:program Stream信息描述字段,长度由前个字段确定;

elementary_stream_map_length字段长度字段,占位16bit;表示在这个PSM中所有ES流信息的总长度;包括stream_type, elementary_stream_id, elementary_stream_info_length的长度,即N*32bit;是不包括具体ES流描述信息descriptor的长度的;

LOOP:

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(C0~DF)指音频,0x(E0~EF)为视频;

elementary_stream_info_length字段长度字段,占位16bit;表示此字段之后的,ES流描述信息的长度;

Descriptor:描述信息,长度由前个字段确定;表示此类型的ES流的描述信息,这个描述信息的长度是不包含在elementary_stream_map_length字段里面的;

LOOP End;

CRC_32:CRC字段,占位32bit,CRC校验值;

如果要解析原始流编码类型,则需要解析PSM,我们需要找到0x000001BC的位串,然后根据PSM的结构进行解析;如果不需要解析,则在找到PSM的开始码之后,找到此字段的长度字段,跳过此长度即可,直接解析后面的PES包;

PS总结:

解析PS包,要先找到PS包的的起始码0x000001BA位串,然后解析出系统头部字段,之后进入PS包的负载,判断是否有PSM,根据PSM确定payload的PES包中所负载的ES流类型;然后再根据ES流类型和ID从PES包中解析出具体的ES流;解包过程则相反;若要从PS流中找出来帧类型,必须将PS包解析成ES并组成完整的帧,然后在帧数据开始根据NAL头来进行帧的类型的判断;

PSM只有在关键帧打包的时候,才会存在;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);

附录1:stream_id类型定义

stream_id

Note

stream coding

1011 1100

1

program_stream_map

1011 1101

2

private_stream_1

1011 1110

padding_stream

1011 1111

3

private_stream_2

110x xxxx

ISO/IEC 13818-3 or ISO/IEC 11172-3 audio
stream number x xxxx

1110 xxxx

ITU-T Rec. H.262†|†ISO/IEC 13818-2 or ISO/IEC 11172-2 video stream number xxxx

1111 0000

3

ECM_stream

1111 0001

3

EMM_stream

1111 0010

5

ITU-T Rec. H.222.0†|†ISO/IEC 13818-1 Annex A or ISO/IEC 13818-6_DSMCC_stream

1111 0011

2

ISO/IEC_13522_stream

1111 0100

6

ITU-T Rec. H.222.1 type A

1111 0101

6

ITU-T Rec. H.222.1 type B

1111 0110

6

ITU-T Rec. H.222.1 type C

1111 0111

6

ITU-T Rec. H.222.1 type D

1111 1000

6

ITU-T Rec. H.222.1 type E

1111 1001

7

ancillary_stream

1111 1010 Ö 1111 1110

reserved data stream

1111 1111

4

program_stream_directory

PES,TS,PS,RTP等流的打包格式解析之PS流相关推荐

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

    本篇介绍RTP包封装格式 1.RTP包头格式 RTP包头占位12个字节,其字段组成如下图所示: V字段:RTP协议版本号,占位2bit,当前协议为V=2: P字段:填充字段,占位1bit,如果P=1, ...

  2. 海康摄像头PS流格式解析(RTP/PS/H264)

    海康威视视频录像以PS格式打包,解析的过程按照PS包-->system header--->program stream map--->音视频PES包一路下来,海康在包中自定义了一些 ...

  3. 视频流中ES,PES,PS,TS,RTP概念说明

    ES:又称为原始流,直接从编码器出来,可以是编码过的H264,MJPEG,音频AAC,音频G711等.ES只包含一种内容的视频,如只含视频或者只含音频. PES: ES流经PES打包器形成,将ES流分 ...

  4. ps流 转发_一种国标PS流转RTMP直播流的实时转换方法与流程

    本发明属于视频技术领域,具体涉及一种国标ps流转rtmp直播流的实时转换方法. 背景技术: ps流全称是节目流(programstream),将一个节目的多个组成部分按照它们之间的互相关系进行组织并加 ...

  5. 海康sdk捕获码流数据通过JavaCV推成rtmp流的实现思路(PS流转封装RTMP)

    海康sdk捕获码流数据通过JavaCV推成rtmp流的实现思路(PS流转封装RTMP) 问题分析 转码推rtmp PS流转封装 码云(Gitee)主页:https://gitee.com/banmaj ...

  6. unity pico串流与打包时手柄配置细节

    1.改动select action时 选择"Pico Live Preview Controller"方可在串流时使用手柄功能键位(左右手柄改法相同) 且在select value ...

  7. 【java笔记】字符流,Properties,序列化,打印流

    字符流 字符流=字节流+编码 package demo04;import java.io.FileInputStream; import java.io.FileNotFoundException; ...

  8. RTP中H264封装NALU格式详细解析

    名词解释:NAL NAL的英文全称为Network Abstract Layer,即网络抽象层,在H264/AVC视频编解码标准中,整个系统框架分为两个层面,视频编解码层面(VCL)和网络抽象层面(N ...

  9. java中的常用的文件流_Java 基础(四)| IO 流之使用文件流的正确姿势

    image.png 一.什么是 IO 流? 想象一个场景:我们在电脑上编辑文件,可以保存到硬盘上,也可以拷贝到 U 盘中.那这个看似简单的过程,背后其实是数据的传输. 数据的传输,也就是数据的流动.既 ...

最新文章

  1. 17岁「天才少女」被8所世界名校录取,最终选择MIT计算机系,还说学成后肯定回国...
  2. 可逆加密算法 php,php可逆加密的方法及原理
  3. HTTP和HTTPS的区别(转)
  4. presto集群安装
  5. Edge 修改字符编码(详细图文)
  6. 链路两段不同网段怎么通信_交换机互联不同vlan及不同网段通信问题总结
  7. Linux基础——Linux 基本指令 touch, cp 和 mv
  8. IDEA新特性真牛逼:提前知道代码怎么走!
  9. SQL 数据表基本操作
  10. Norton Internet Security 序列号提取(卡饭)
  11. 个人学习(解决)练习ssm框架遇到的问题No qualifying bean of type ‘service.BookTypeService‘ available:
  12. 元学习:实现通用人工智能的关键!
  13. appstore的几个核心关键词排名降到最后,有没有可以解决的办法?
  14. 网络变压器作用(续):T件和扼流圈(K件)组成的网络变压器及其作用
  15. 单位内用lk作负载均衡,大家看看
  16. sql server 2008 r2 产品密钥
  17. 非接触式IC卡存储结构
  18. 探寻人工智能型CRM系统的作用?
  19. 【算法】广度优先遍历 (BFS)
  20. Mysql注入 -- 延时注入

热门文章

  1. Hadoop学习笔记-NN与2NN
  2. Android Compose——一个简单的新闻APP
  3. 【HDL系列】乘法器(2)——阵列乘法器
  4. 杭电oj 2063 过山车(匈牙利算法)
  5. 个人简历管理系统(5)-Dao
  6. 简洁大方的程序员市场总监合适简历模板
  7. OpenCV4、C++:未定义标识符 “CV_RGB2GRAY“ 的解决方案
  8. 从前端到全端:JavaScript逆袭之路
  9. Python变强有这70个项目就够了,一定要收藏
  10. STA系列 - 芯片的鲁棒性OCV之set_time_derate