常见封装格式

啥是数据流封装格式?
将已经编码压缩好的音视频封装在数据包中,可以在网络上进行传输,对方在收到数据后根据封装格式,能够知道码流的类型,特性等,从而解析数据。

取流协议及封装格式有哪些?
RTSP取流 — RTP、PS封装、RTP+PS 
HLS取流 — TS封装,一个片段就是一个TS文件
RTMP取流 — FLV文件

播放器支持的封装格式
VLC:支持RTSP、HLS、RTMP取流。RTSP取流时只支持RTP封装格式的H264码流,其余情况会黑屏(高版本vlc支持RTP封装格式的H265码流 )。
VLC、VSPlayer等可以播放ps、ts封装的码流文件,无法解析RTP封装。
VLC无法播放H265的码流文件。

一、PS封装

PS封装,一段PS流可以视为多个PS GOP(图像组),每个GOP以I帧开始,然后包含了一些P帧,B帧等: 
(1) PS 是 Program Stream(程序流或节目流)的简称,可用于存储和传输;
(2) 一个PS流可以视为多个PS GOP,每个GOP是以I帧起始的多帧集合;
(3) 一个PS GOP由一个或多个PS包组成;
(4) 一个PS包内包含一个PSH(PS Header)和若干个PES包;
(5) 每个PS GOP的第一个PS包应当在包头PSH后立即跟随一个PSM包;
(6) PSM包是一种特殊的PES包,含有对其他PES负载数据类型的描述。

一个PS流或者文件可以视为多个PS GOP,每个GOP是以I帧起始的多帧集合,各GOP之间的信息没有相互依赖性,可以进行剪切拼接。一个PS GOP由一个或多个PS包组成,一个PS包内包含一个PSH(PS Header)和若干个PES包,每个PS GOP的第一个PS包应当在包头PSH后立即跟随一个PSM包。PSM包是一种特殊的PES包,含有对其他PES负载数据类型的描述。PS包内的其他PES的出现顺序和内容没有特殊约束,即一个PS包内可以包含交错出现的视频、音频和私有流等PES包,各PES包根据PSM的描述进行拆分。

I帧:表示关键帧,可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面); 
P帧:表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据);
B帧:是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况),换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累~

PS封装,以ps头开始,然后是ps系统标题,接着是节目映射流,最后是pes头和裸数据。 PS封装是没有固定的封装头长度的,针对H264 做如下PS 封装,一个IDR NALU PS 包(关键帧)的大致结构,如下图所示(ps system header非必须):

对于其它非关键帧的PS 包,则为:

注释:播放原理是根据psm中获取码流的类型等,然后利用PES中的PTS(播放时间戳)和DTS(解码时间戳)来进行解码播放。

举例

针对H264 做如下PS 封装,一个IDR NALU PS 包(关键帧)的大致结构如下图所示:

00 00 01 ba是ps头,然后这里就没有包含ps系统标题00 00 01 bb,接下去是节目映射流00 00 01 bc。bc后面是两个字节的长度,标明PSM的长度。跳过两个字节(版本号,填充位啥的),接下去就是音视频,还有私有数据的说明了。格式都是两个字节长度+内容。比如这里00 24是长度,40 0E开始这一串就是海康私有数据;然后00 2c是长度,用来说明音视频,其中24 E0是视频,00 10是长度,91 c0是音频,00 0c是长度。这里24代表了h265,91代表了g711u。 基本流标识字段:0x(C0~DF)指音频,0x(E0~EF)为视频。

更简单地看就是先找到00 00 01 bc,以及后面两字节的长度;然后在这个长度范围内直接找E0和C0,E0前面如果是1b就是264,24就是265。

二、TS封装

(1) TS是Transport Stream(传输流)的简称,用于存储和传输;
(2) TS流由一系列长度固定为188个字节的TS包组成;
(3) TS包以4个字节的前缀(TS header)开始, 包括位长13bit的PID;
(4) 通过PID和节目特殊信息表(PSI)可以识别TS包中负载的内容。

首先看ts封装,ts封装主要再hls取流时会用到,保存下来的文件可以直接用vsplayer播放。转包中利用http.request.method == GET条件过滤,保存码流文件,直接播放。TS封装比较简单,就是每一包数据固定为188个字节;然后最前面是4个字节的ts码流头,后面是184个字节的负载;4个字节头中第一个字节固定都是0x47。

举例:

TS Header中第一个字节固定为0x47,上图看到第一个TS Header地址为0xc9,然后加上ts包长度188,就是0x185,又是0x47 。所以,如果要确定文件是否是TS码流,可以看是不是每隔188个字节就有0x47。

三、FLV封装

(1) FLV是Flash Video的简称,文件存储格式,且可实现流式播放;文件开头会有’F’(0x46),’L’(0x4c),’V’(0x56)这三个字节;
(2) FLV由文件头、媒体头和多个Tag组成;
(3) FLV的Tag分为Video、Audio和Scrip,一个Tag只能包含一个媒体帧,每个Tag下面有一个4字节的长度,用于记录该Tag的大小,用于逆向读取处理;
(4) FLV暂只支持H264+AAC,不支持私有数据;
(5) RTMP格式的消息结构与FLV格式的Tag结构有部分相同的语法定义,只不过应用场景不同。

四、RTP封装

(1) RTP是Real-time Transport Protocol(实时传输流)的简称,用于传输;
(2) RTP码流由多个RTP包组成,每个RTP包包含RTP头标准字段(固定12字节)、RTP头扩展字段、RTP负载、填充字段;
(3) 私有数据存放在私有扩展字段,包括各种描述子及各种私有类型数据;
(4) RTP保存成文件是不能直接播放的,抓包下来的RTP码流中往往含有协议交互数据和冗余数据,所以分析RTP数据是很耗时的。

具体参考:https://blog.csdn.net/dusk0825/article/details/108240156

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值