H264编码 封装成MP4格式 视频流 RTP封包

H264编码 封装成MP4格式 视频流 RTP封包

        分类:             多媒体编程              2013-02-20 21:31     3067人阅读     评论(0)     收藏     举报    

转自:http://www.cnblogs.com/ghw-NO1/archive/2012/08/28/2660848.html

http://blog.csdn.net/crazyman2010/article/details/8596229

一、概述

本文讲述的是对H264编码且封装成MP4格式的视频流进行RTP打包过程时需要了解的一些基本知识。

二、H264的基础知识

1.H264的编码格式

H.263 定义的码流结构是分级结构,共四层。自上而下分别为:图像层(picturelayer)、块组层(GOB layer)、宏块层(macroblock layer)和块层(block layer)。而与H.263 相比,H.264的码流结构和H.263 的有很大的区别,它采用的不再是严格的分级结构。H.264 支持4:2:0 的连续或隔行视频的编码和解码。H.264 压缩与H.263、MPEG-4 相比,视频压缩比提高了一倍。

H.264 的功能分为两层:视频编码层(VCL, Video Coding Layer)和网络提取层(NAL,Network Abstraction Layer)。VCL 数据即编码处理的输出,它表示被压缩编码后的视频数据序列。在VCL 数据传输或存储之前,这些编码的VCL 数据,先被映射或封装进NAL 单元中。每个NAL 单元包括一个原始字节序列负荷(RBSP, Raw Byte Sequence Payload)、一组对应于视频编码的NAL 头信息。RBSP 的基本结构是:在原始编码数据的后面填加了结尾比特。一个bit“1”若干比特“0”,以便字节对齐。 H264编码 封装成MP4格式 视频流 RTP封包

2.H264的传输

H.264 的编码视频序列包括一系列的NAL 单元,每个NAL 单元包含一个RBSP,见表1。编码片(包括数据分割片IDR 片)和序列RBSP 结束符被定义为VCL NAL 单元,其余 为NAL 单元。典型的RBSP 单元序列如图2 所示。每个单元都按独立的NAL 单元传送。单元的信息头(一个字节)定义了RBSP 单元的类型,NAL 单元的其余部分为RBSP 数据。

H264编码 封装成MP4格式 视频流 RTP封包

H264编码 封装成MP4格式 视频流 RTP封包

H264编码 封装成MP4格式 视频流 RTP封包

3.H264的码流结构

H264编码 封装成MP4格式 视频流 RTP封包

起始码:如果NALU 对应的Slice 为一帧的开始,则用4 字节表示,即0x00000001;否则用3 字节表示,0x000001。

一个frame是可以分割成多个Slice来编码的,而一个Slice编码之后被打包进一个NAL单元,不过NAL单元除了容纳Slice编码的码流外,还可以容纳其他数据,比如序列参数集SPS。

三、MP4封装的H264数据

MP4文件中所有数据都封装在box中,它是由若干个子box组成,每个box还可以包含另外的子box,且每个box都有长度和类型。“ftyp”(66 74 79 70)box:作为MP4格式的标志并包含关于文件的一些信息,有且仅有一个;“moov”(6D 6F 6F 76)box:包含了媒体的metadata信息(特别是avcC中的sps和pps),有且仅有一个;“mdat”(6D 64 61 74)box:包含了MP4的媒体数据,可以有多个,也可以没有。但是媒体数据的结构由metadata进行描述。MP4中box存储方式为大端模式。一般,标准的box开头会有四个字节的box size。

在MP4格式文件中,H264 slice并不是以00 00 00 01来作分割,而是存储在mdat box中。H264基本码流由一些列的NALU组成。原始的NALU单元组成:[start code] + [NALU header] + [NALU payload].

MP4数据格式:|"ftyp"box|"moov"box(及其子box)|"mdat"box|....|。

"mdat"box的格式:|box的length(4字节)|box类型(4字节)mdat-6D 64 61 74|NALU的length(4字节)|NALU的header(1字节)|payload|;

MP4封装结构图:

box结构图:

H264编码 封装成MP4格式 视频流 RTP封包

用MP4info分析的实例分析图:

H264编码 封装成MP4格式 视频流 RTP封包

四、H264视频流的RTP封包

1.RTP打包原则

RTP的包长度必须要小于MTU(最大传输单元),IP协议中MTU的最大长度为1500字节。除去IP报头(20字节)、UDP报头(8字节)、RTP头(12字节),所有RTP有效载荷(即NALU内容)的长度不得超过1460字节。

H264编码 封装成MP4格式 视频流 RTP封包

2.RTP协议的报文结构

H264编码 封装成MP4格式 视频流 RTP封包

开始12个八进制出现在每个RTP包中,而CSRC标识列表仅出现在混合器插入时。各段含义如下: ①版本(V)version (V): 2 bits   2位,标识RTP版本,协议初始版本为0,RFC3550中规定的版本号为2。。 ②填充标识(P)padding (P): 1 bit   1位,如设置填充位,在包末尾包含了额外的附加信息,它不属于有效载荷。附加信息的最后一个字节表示额外附加信息的长度(包含该字节本身)。该字段之所以存在是因为某些加密算法需要固定大小的填充字,或为在底层协议数据单元中携带几个RTP包。 ③扩展(X)extension (X): 1 bit           1位,如果该位被设置,则在固定的头部后存在一个扩展头部,格式定义在RFC3550 5.3.1节。 ④CSRC计数(CC) CSRC count (CC): 4 bits    4位,CSRC计数包括紧接在固定头后标识CSRC个数。 ⑤标记(M) marker (M): 1 bit    1位,标记解释由设置定义,目的在于允许重要事件在包流中标记出来。设置可定义其他标示位,或通过改变位数量来指定没有标记位,该位的功能依赖于profile的定义。profile可以改变该位的长度,但是要保持marker和payload type总长度不变(一共是8 bit)。。

或M:标示位,1 位。如果当前 NALU为一个接入单元最后的那个NALU,那么将M位置 1;或者当前RTP 数据包为一个NALU 的最后的那个分片时(NALU 的分片在后面讲述),M位置 1。其余情况下M 位保持为 0。 ⑥载荷类型(PT)payload type (PT): 7 bits   7位,记录后面资料使用哪种 Codec , receiver 端找出相应的 decoder 解碼出來,该位标记着RTP packet所携带信息的类型,标准类型列出在RFC3551中。如果接收方不能识别该类型,必须忽略该packet。 ⑦系列号 sequence number:16 bits  16位,系列号随每个RTP数据包发送后而增加1,接收方可以根据该序列号重新排列数据包顺序,或者探测包损失。系列号初值是随机的,使对加密的文本攻击更加困难。 ⑧时间戳timestamp: 32 bits    32位,时标反映RTP数据包中第一个八进制数的采样时刻,采样时刻必须从单调、线性增加的时钟导出,以允许同步与抖动计算。时标可以让receiver端知道在正确的时间将资料播放出来。实际中当采用”分片封包模式“打包RTP时,当一个NALU打包完毕时,时间戳更一次。

H264编码 封装成MP4格式 视频流 RTP封包

由上图可知,如果只有系列号,并不能完整按照顺序的将data播放出来,因为如果data中间有一段是没有资料的,只有系列号的话会造成错误,需搭配上让它知道在哪个时间将data正确播放出来,如此我们才能播放出正确无误的信息。 ⑨SSRC SSRC: 32 bits                     32位,SSRC段标识同步源。此标识不是随机选择的,目的在于使同一RTP包连接中没有两个同步源有相同的SSRC标识,也就是在一个RTP Session其间每个数据流都应该有一个不同的SSRC。尽管多个源选择同一个标识的概率很低,所有RTP实现都必须探测并解决冲突。如源改变源传输地址,也必须选择一个新SSRC标识以避免插入成环行源。 ⑩CSRC列表CSRC list: 0 to 15 items     bits0到15项,每项32位。CSRC列表表示包内的对载荷起作用的源。标识数量由CC段给出。如超出15个作用源,也仅标识15个。CSRC标识由混合器插入,采用作用源的SSRC标识。只有存在Mixer的时候才有效。如一个将多声道的语音流合并成一个单声道的语音流,在这里就列出原来每个声道的SSRC。

3.NALU header结构图

NALU header由一个字节组成, 它的语法如下:

H264编码 封装成MP4格式 视频流 RTP封包

F: 1 个比特.forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0.

NRI: 2 个比特.nal_ref_idc. 取 00 ~ 11, 似乎指示这个 NALU 的重要性, 如00的NALU解码器可以丢弃它而不影响图像的回放. 不过一般情况下不太关心这个属性.

Type: 5 个比特.nal_unit_type. 这个 NALU 单元的类型. 但是在h264中只有 1~23 是有效的值.而其他的24~29在RTP封包采用”组合封包模式“和”分片封包模式“时所用的type类型,而非“单一NAL单元模式”时。

简述如下:

0     没有定义   1-23  NAL单元  单个 NAL 单元包.   24    STAP-A   单一时间的组合包   25    STAP-B   单一时间的组合包   26    MTAP16   多个时间的组合包   27    MTAP24   多个时间的组合包   28    FU-A     分片的单元   29    FU-B     分片的单元   30-31 没有定义

4.RTP打包模式

主要分为三种模式:单一NALU模式、分片模式、组合模式,实际中前两种用的比较多。

(1)单一NALU模式

一个RTP包仅由一个完整的NALU组成。这种情况下RTP NAL头类型字段和原始的H.264的NALU头类型字段是一样的。适合条件是当NALU的长度小于RTP包长减去12时。

H264编码 封装成MP4格式 视频流 RTP封包

特别NALU type 值为 7 和 8 的NALU分别为序列参数集(sps)和图像参数集(pps)。

(2)组合封包模式

即可能是由多个 NAL 单元组成一个 RTP 包. 分别有4种组合方式: STAP-A, STAP-B, MTAP16, MTAP24.那么这里的类型值分别是 24, 25, 26 以及 27.适合条件当 NALU 的长度特别小时, 可以把几个 NALU 单元封在一个 RTP 包中.

H264编码 封装成MP4格式 视频流 RTP封包

(3)分片封包模式Fragmentation Units (FUs)

用于把一个 NALU 单元封装成多个 RTP 包. 存在两种类型 FU-A 和 FU-B. 类型值分别是 28 和 29。适合条件当 NALU 的长度超过 MTU 时, 就必须对 NALU 单元进行分片封包.

H264编码 封装成MP4格式 视频流 RTP封包

H264编码 封装成MP4格式 视频流 RTP封包

FU indicator 结构

H264编码 封装成MP4格式 视频流 RTP封包 F:当网络识别此单元存在比特错误时,可将其设为 1,以便接收方丢掉该单元。 NRI:必须根据分片NAL单元的NRI域的值设置,用来指示该NALU的重要性等级。值越大,表示当前NALU越重要。 TYPE:28表示FU-A和29表示FU-B

FU Header 结构:

H264编码 封装成MP4格式 视频流 RTP封包

S:当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。                 E:当设置成1,结束位指示分片NAL单元的结束。即荷载的最后字节是分片NAL单元的最后一个字节。当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0。 R:保留位必须设置为0,接收者必须忽略该位。

Type:与NALU的header中的Type类型一致。

【流媒體】H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流

SkySeraph Apr 1st 2012 

Email:skyseraph00@163.com


一、MP4格式基本概念

MP4格式对应标准MPEG-4标准(ISO/IEC14496)


二、MP4封装格式核心概念

1  MP4封装格式对应标准为 ISO/IEC 14496-12(信息技术 视听对象编码的第12部分: ISO 基本媒体文件格式/Information technology Coding of audio-visual objects Part 12: ISO base media file format)

 附-- 标准免费下载: Freely Available Standards    http://standards.iso.org/ittf/PubliclyAvailableStandards/index.html

2  MP4封装格式是基于QuickTime容器格式定义,媒体描述与媒体数据分开,目前被广泛应用于封装h.264视频和ACC音频,是高清视频/HDV的代表。

MP4文件中所有数据都封装在box中(对应QuickTime中的atom),即MP4文件是由若干个box组成,每个box有长度和类型,每个box中还可以包含另外的子box(称container box)。

 一个MP4文件首先会有且只有一个“ftyp”类型的box,作为MP4格式的标志并包含关于文件的一些信息;之后会有且只有一个“moov”类型的box(Movie Box),它是一种container box,子box包含了媒体的metadata信息;MP4文件的媒体数据包含在“mdat”类型的box(Midia Data Box)中,该类型的box也是container box,可以有多个,也可以没有(当媒体数据全部引用其他文件时),媒体数据的结构由metadata进行描述。

MP4中box存储方式为大端模式。一般,标准的box开头会有四个字节的box size。

5 几个名词

track

表示一些sample的集合,对于媒体数据来说,track表示一个视频或音频序列。

hint track

特殊的track,并不包含媒体数据,包含的是一些将其他数据track打包成流媒体的指示信息。

sample

对于非hint   track来说,video sample即为一帧视频,或一组连续视频帧,audio sample即为一段连续的压缩音频,它们统称sample。

对于hint   track,sample定义一个或多个流媒体包的格式。

sample table

指明sampe时序和物理布局的表。

chunk

一个track的几个sample组成的单元。


三、MP4封装格式结构图

1 实例样本

来源于Android MediaRecoder视频录制,平台为华为T8300和TCL968,mp4info查看如下

H264编码 封装成MP4格式 视频流 RTP封包

EsEYE查看如下:

H264编码 封装成MP4格式 视频流 RTP封包

winhex分析如下:

H264编码 封装成MP4格式 视频流 RTP封包

2 box结构图

H264编码 封装成MP4格式 视频流 RTP封包

接下来对h264编码中有用的几个进行阐述,其它不再描述。

3 ftyp(file type box)

如下图所示,开始的四字节00 00 00 00 18表示该box的size为24字节(含头),然后66 74 79 70是ftyp的BOX TYPE,其它是一些格式兼容等相关信息。

H264编码 封装成MP4格式 视频流 RTP封包

4  mdat

如下图所示,BOX YPE为6D 64 61 74 ,紧接着的00 00 09 39表示sliece长度

H264编码 封装成MP4格式 视频流 RTP封包

5 avcC

如下图所示,红色为BOX TYPE

H264编码 封装成MP4格式 视频流 RTP封包


四、MP4文件中h264的 SPS、PPS获取

1  【参考依据】ISO/IEC 14496-15 (下载

2  【综述】在H264中,SPS和PPS存在于NALU header中,而在MP4文件中,SPS和PPS存在于AVCDecoderConfigurationRecord, 首先要定位avcC.

3  【定义】

①参数集:一组很少改变的,为大量VCL NALU 提供解码信息的数据。

序列参数集SPS作用于一系列连续的编码图像,而图像参数集PPS作用于编码视频序列中一个或多个独立的图像。

如果解码器没能正确接收到这两个参数集,那么其他NALU 也是无法解码的。因此它们一般在发送其它 NALU 之前发送,并且使用不同的信道或者更加可靠的传输协议(如TCP)进行传输,也可以重复传输。

②关于AVCDecoderConfigurationRecord结构定义为  

H264编码 封装成MP4格式 视频流 RTP封包

4  【实例分析】 数据如上avcC图所示,现在对数据进行详细分析

H264编码 封装成MP4格式 视频流 RTP封包

所以,提取的SPS和PPS分别为67 42 00 1E A6 81 41 F9和68 CE 38 80


五、MP4文件中的H264 data /NALU slice

1  【参考】H264官方文档(下载) + 毕书—新一代视频压缩编码标准(下载

2  【综述】

① 在MP4格式文件中,H264 slice并不是以00 00 00 01来作分割,而是存储在mdat box中。

②  H264基本码流由一些列的NALU组成。原始的NALU单元组成:[start code] + [NALU header] + [NALU payload]

start   code

1字节

00 00 01 或 00 00 00 01

需要添加的

NALU header

1字节

如下3

通过mdat定位

③  H264基本码流结构分两层:视频编码层VCL和网络适配层NAL,这样使信号处理和网路传输分离

VCL

负责高效视频内容表示

NAL

以网络所要求的恰当方式对数据进行打包和发送

3  【定义】 NALU header

+---------------+

|0|1|2|3|4|5|6|7|

+-+-+-+-+-+-+-+-+

|F|NRI| Type |

+---------------+

H264编码 封装成MP4格式 视频流 RTP封包

特别的,当值为7和8分别为SPS和PPS。

毕书(下载)(P191)上的定义为:

H264编码 封装成MP4格式 视频流 RTP封包

4  【实例分析】数据分析,数据如上图mdat所示

6D 64 61 74

mdat   BOX TYPE

00 00   09 39

silce长度,2361

接下来的65就是NALU header,可以由65&0x1F来求的后五个bit,从而得知此slice为I frame

注意,mdat与silce之间有可能存在若干占位符,我在TCL手机测试时就出现了连续的00的占位符,这样后面用H264硬编码时会比较麻烦一点。


Ref/Related

1 相关资料和工具在文中链接下载

2 http://www.52rd.com/Blog/wqyuwss/559/4/

3 http://blog.csdn.net/szu030606/article/details/5943279

4 http://blog.csdn.net/k1988/article/details/5654631

5 http://www.cppblog.com/czanyou/archive/2008/11/26/67940.html

6 http://krdai.info/blog/sps-pps-in-mp4-format.html

7 http://www.cnitblog.com/zouzheng/archive/2007/04/04/25155.html

8 http://bbs.chinavideo.org/viewthread.php?tid=10273

上一篇:HTML5 Web Form 新增属性和表单验证


下一篇:Motor Vocabuary