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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

因为工作接触到了各种不同的音视频封装格式,常见的国标PS流,onvif的RTP流和TS流等,都说好记性不如烂笔头,抽空总结下,也好在以后能随时查阅,因水平问题,可能会有地方有疏漏和问题,还请指教

一、PES流

PES流是对原始ES流进行的第一层封装,PES流的基本单位是PES包,由包头和payload组成,ES流即音视频裸流,是从编码器里面出来的原始视频音频流;ES流只包含一种内容,里面是视频或者音频;封装时不对其进行改变,只在前面添加头部,如私有头,解码时,将私有头剥掉,将原始ES码流送进解码器解码,这也是解码通用性,若是修改了,则其他解码器就没法解码了;PES和ES一样,都是单一原始码流,一般我遇到的是一帧数据放在一个PES包里面,但是一个PES包的最大长度为65535字节,因此一帧数据有可能被分为多个PES;其包头格式如下:

可以看出,PES包是由固定包头,可选包头和负载三部分组成,其中固定包头固定6个字节;PES包长度字段占位16bit,最大值为65536,

故一帧可能会分为多个PES包;下面依次介绍其每个字段的含义:

Packet start code prefix:包头起始码,固定为0x000001,占位24bit;

Stream id:(UI)PES包中的负载流类型,一般视频为0xe0,音频为0xc0,占位8bit;

PES packet length:(UI)PES包长度,包括此字节后的可选包头和负载的长度,占位16bit;

Optional PES Header,顺序依次为:

’10’字段:占位2bit;

PES scrambling control:加密模式,占2bit;00未加密,01或10或11由用户定义;

PES priority:有效负载的优先级,占位1bit;值为1比值为0的负载优先级高;

Data alignment indicator:数据定位指示器,占位1bit;

Copyright:版权信息,1为有版权,0无版权,占位1bit;

Original or copy:原始或备份,1为原始,0为备份,占位1bit;

后面是7个flags(一般我们关注的就是PTS DTS的标志位):

PTS_DTS_flags:PTS和DTS标志位,占位2bit;10表示首部有PTS字段,11表示有PTS和DTS字段,00表示都没有,01被禁止,不会出现此种情况;

ESCR_flag:ESCR标志,占位1bit;1表示首部有ESCR字段,0则无此字段

ES_rate_flag:ES_rate字段,占位1bit;1表示首部有此字段,0无此字段;

DSM_trick_mode_flag:占位1bit;1表示有8位的DSM_trick_mode_flag字段,0无此字段;

Additional_copy_info_flag:占位1bit;1表示首部有此字段,0表示无此字段;

PES_CRC_flag:占位1bit;置1表示PES分组有CRC字段,0无此字段;

PES_extension_flag:占位1bit;扩展标志位,置1表示有扩展字段,0无此字段;

PES header data length:(UI)PES首部中可选字段和填充字段的长度;占位8bit;可选字段的内容由上面7个flags来进行控制;

Optional fields:可选字段的描述信息区域,其内容由上面的7个flag来控制;

PTS/DTS字段:显示时间戳/解码时间戳,占位40bit,当PTS_DTS_flags == 1x时此字段存在;时间占用33个bit,PTS和DTS的内容是在这40bit中取33位,方式相同;

PTS(presentation time stamp)显示时间戳和DTS(Decoding Time Stamp)解码时间戳,是用来音视频同步的,是打在PES包的包头里面的,PTS/DTS是相对SCR(系统参考)的时间戳,是以90000为单位的,PTS/DTS到ms的转换公式是PTS/90,系统时钟频率(H264采样频率?)为90Khz,所以转换到秒为PTS/90000,所以如果是以ms为单位的播放器,PTS/DTS是要使用公式ms=pts/90来转换才行的,而如果是以时钟频率为单位的话,则直接将PTS/DTS送进去解码即可;如果没有B帧,PTS和DTS的顺序应该是一致的,如果有B帧,则需要先解码P帧,才能解出来B帧,所以需要PTS和DTS来控制解码时间和显示时间;

字节顺序依次:

start_code:起始码,占位4bit;若PTS_DTS_flags == ‘10’,则说明只有PTS,起始码为0010;若PTS_DTS_flags ==
‘11’,则PTS和DTS都存在,PTS的起始码为0011,DTS的起始码为0001;(PTS的起始码后2个bit与flag相同)

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

marker_bit:占位1bit;

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

marker_bit:占位1bit;

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

marker_bit:占位1bit;

PTS/DTS  =
(PTS1 & 0x0e) << 29 + (PTS2 & 0xfffe) << 14 + (PTS3 & 0xfffe ) >> 1;

ESCR字段:此字段占位48bit,由33bit的ESCR_base字段和9bit的ESCR_extension字段组成,ESCR_flag
== 1时此字段存在;数据依次顺序:

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

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

marker_bit占位1bit;

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

marker_bit:占位1bit;

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

marker_bit:占位1bit;

ESCR_extension(UI)占位9bit;周期数,取值范围0~299;循环一次,base+1;

marker_bit:占位1bit;

ES rate字段:目标解码器接收PES分组字节速率,禁止为0,占位24bit,ES_rate_flag
== 1时此字段存在;数据顺序为:

marker_bit:占位1bit;

ES_rate占位22bit;

marker_bit占位1bit;

Trick mode control字段:表示哪种trick mode被应用于相应的视频流,占位8个bit,DSM_trick_mode_flag
== 1时此字段存在;其中trick_mode_control占前3个bit,根据其值后面有5个bit的不同内容;

如果trick_mode_control == ‘000’,依次字节顺序为:

field_id:占位2bit;

intra_slice_refresh :占位1bit;

frequency_truncation:占位2bit;

如果trick_mode_control == ‘001’,依次字节顺序为:

rep_cntrl:占位5bit;

如果trick_mode_control == ‘010’,依次字节顺序为:

field_id:占位2bit;

Reserved:占位3bit;

如果trick_mode_control == ‘011’,依次字节顺序为:

field_id:占位2bit;

intra_slice_refresh:占位1bit;

frequency_truncation:占位2bit;

如果trick_mode_control== ‘100’,依次字节顺序为:

rep_cntrl:占位5bit;

其他情况,字节顺序为:

reserved :占位5bit;

Additional copy info字段:占8个bit,Additional_copy_info_flag
== 1时此字段存在;数据顺序为:

marker_bit:占位1bit;

copy info字段:占位7bit;表示和版权相关的私有数据;

Previous PES CRC字段:占位16bit字段,包含CRC值,PES_CRC_flag
== 1时此字段存在;

PES extension字段:PES扩展字段,PES_extension_flag
== 1时此字段存在;内容如下,字节顺序依次为:

PES_private_data_flag:占位1bit,置1表示有私有数据,0则无;

Pack_header_field_flag:占位1bit,置1表示有Pack_header_field字段,0则无;

Program_packet_sequence_counter_flag:占位1bit,置1表示有此字段,0则无;

P-STD_buffer_flag:占位1bit,置1表示有P-STD_buffer字段,0则无此字段;

Reserved字段:3个bit;

PES_extension_flag_2:占位1bit,置1表示有扩展字段,0则无此字段;

Optional field :PES扩展字段的可选字段内容顺序为:

PES_private_data字段:私有数据内容,占位128bit,PES_private_data_flag
== 1时此字段存在;

Pack_header_field字段:Pack_header_field_flag
== 1时此字段存在;字段组成顺序如下:

Pack_field_length字段:(UI)指定后面的field的长度,占位8bit;

pack_header_field()长度为Pack_field_length指定;

Program_packet_sequence_counter字段:计数器字段,16个bit;当flag字段Program_packet_sequence_counter_flag
== 1时此字段存在;字节顺序依次为:

marker_bit:占位1bit;

packet_sequence_counter字段:(UI)占位7bit;

marker_bit占位1bit;

MPEG1_MPEG2_identifier占位1bit;置位1表示此PES包的负载来自MPEG1流,置位0表示此PES包的负载来自PS流;

original_stuff_length(UI)占位6bit;表示PES头部填充字节长度;

P-STD_buffer字段:表示P-STD_buffer内容,占位16bit;P-STD_buffer_flag
== ‘1‘时此字段存在;字节顺序依次为:

’01’字段:占位2bit;

P-STD_buffer_scale:占位1bit;表示用来解释后面P-STD_buffer_size字段的比例因子;如果之前的stream_id表示音频流,则此值应为0,若之前的stream_id表示视频流,则此值应为1,对于其他stream类型,此值可以0或1;

P-STD_buffer_size占位13bit;无符号整数;大于或等于所有P-STD输入缓冲区大小BSn的最大值;若P-STD_buffer_scale ==
0,则P-STD_buffer_size以128字节为单位;若P-STD_buffer_scale ==
1,则P-STD_buffer_size以1024字节为单位;

PES_extension2字段:扩展字段的扩展字段;占用N*8个bit,PES_extension_flag_2
== ‘1‘时此字段存在;字节顺序依次为:

marker_bit占位1bit;

PES_extension_field_length:占位7bit,表示扩展区域的长度;

Reserved字段:占位8*PES_extension_field_length个bit;

Stuffing bytes:填充字段,固定为0xFF;不能超过32个字节;

PES_packet_data_bytePES包负载中的数据,即ES原始流数据;

PES包是TS和PS包封装的基础,TS和PS其实就是对PES包的再一次封装,下篇将讲解一下TS流

.embody { padding: 10px 10px 10px; margin: 0 -20px; border-bottom: solid 1px #ededed }
.embody_b { margin: 0; padding: 10px 0 }
.embody .embody_t,.embody .embody_c { display: inline-block; margin-right: 10px }
.embody_t { font-size: 12px; color: #999 }
.embody_c { font-size: 12px }
.embody_c img,.embody_c em { display: inline-block; vertical-align: middle }
.embody_c img { width: 30px; height: 30px }
.embody_c em { margin: 0 20px 0 10px; color: #333; font-style: normal }

时间: 2024-08-04 20:48:06

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

海康视频录像文件打包格式解析

海康威视视频录像以PS格式打包,录像设置时如将音频设置为G.711 Alaw或者Ulaw,录制下来的文件使用vlc/ffplay等标准播放器播放不出音频,需要向海康申请专用的转换库来转换,当然,打包是按照标准PS格式来打,同学们也可以自己解析文件读取另存 解析的过程按照PS包-->system header--->program stream map--->音视频PES包一路下来,海康在包中自定义了一些id,可以不理会 我手头的文件海康在系统头中定义了四个streamid,分别是0xe0

rtp(h264,ts,ps)流的播放小技巧

使用ffmpeg以下指令,即可分析出sdp ffmpeg -re -i test.264 -f rtp rtp://127.0.0.1:20001>test.sdp ffmpeg -re -i test.ts -f rtp rtp://127.0.0.1:20002>test.sdp ffmpeg -re -i test.ps -f rtp rtp://127.0.0.1:20003>test.sdp 本地调试,利用ffmpeg 推送及播放udp rtp https://blog.csd

ES PES TS

1.流媒体系统结构 ES:elemental stream 基本数据流: PES:packet elemental stream分组的基本数据流: 然后把PES打包成PS ,TS流,PS:program stream;TS:transport stream; DTS(解码时间戳)和PTS(显示时间戳)分别是解码器进行解码和显示帧时相对于SCR(系统参考)的时间戳.SCR可以理解为解码器应该开始从磁盘读取数据时的时间. DTS 2. 在MPEG-2系统中,信息复合/分离的过程称为系统复接/分接,由

PS 流格式解析(转)

对于PS流,最近因为工作需要,所以MPEG2中的PS流格式和解包过程进行了学习. 首先我们需要知道PS包流格式是怎么样的: 针对H264 做如下PS 封装:每个IDR NALU 前一般都会包含SPS.PPS 等NALU,因此将SPS.PPS.IDR 的NALU 封装为一个PS 包,包括ps 头,然后加上PS system header,PS system map,PES header+h264 raw data.所以一个IDR NALU PS 包由外到内顺序是:PSheader| PS syst

ps流格式解析和总结(改了一下排版)

对于PS流,最近因为工作需要,所以MPEG2中的PS流格式和解包过程进行了学习. 首先我们需要知道PS包流格式是怎么样的: (来自http://blog.csdn.net/chen495810242/article/details/39207305) 针对H264 做如下PS 封装:每个IDR NALU 前一般都会包含SPS.PPS 等NALU,因此将SPS.PPS.IDR 的NALU 封装为一个PS 包,包括ps 头,然后加上PS system header,PS system map,PES

TS格式解析

1.TS格式介绍 TS:全称为MPEG2-TS.TS即"Transport Stream"的缩写.它是分包发送的,每一个包长为188字节(还有192和204个字节的包).包的结构为,包头为4个字节(第一个字节为0x47),负载为184个字节.在TS流里可以填入很多类型的数据,如视频.音频.自定义信息等.MPEG2-TS主要应用于实时传送的节目,比如实时广播的电视节目.MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的.简单地说,将DVD上的VOB文件的前面一截c

一、javaSE (二十二)登录注册IO版本案例、数据操作流、内存操作流、打印流、标准输入输出流、随机访问流、合并流、序列化流、Properties、NIO

1:登录注册Io版本案例(掌握) 要求,对着写一遍 cn.itcast.pojo User cn.itcast.dao UserDao cn.itcast.dao.impl UserDaoImp1(实现我不管) cn.itcast.game GuessNumber cn.itcast.test UserTest 2:数据操作流(操作基本类型数据的流)(理解) (1)可以操作基本类型的数据 (2)流对象名称 DataInputStream DataOutputStream 3:内存操作流(理解)

图论之随机配流01——基于LOGIT的STOCH配流法-经典dial算法

function dialsuanfa(T) %程序说明 clc disp('========================================================================================'); disp('                   <基于LOGIT的STOCH配流法--dial算法>'); disp('运行环境:MATLAB 8.3.0.532 '); disp('作者信息:兰州交通大学  刘志祥   QQ:531

什么是流,.NET中有哪些常见的流

分析问题 流是一种对于字节流的直接操作.例如在处理一个文件时,本质上需要通过操作系统提供的API来进行文件打开,读取文件中的字节流,再关闭文件等操作,而读取文件的过程就可以看作字节流的一个过程.常见的流类型有文件流.终端操作流.网络Socket等. 在.NET中,System.IO.Stream类型被设计为所有流类型的虚基类,所有常见的流类型都继承自System.IO.Stream类型,当程序员需要自定义一种流类型时,也应该直接或者间接继承自Stream类型..NET提供了丰富的内建的流类型,其