H.264支持4:2:0的连续或隔行视频的编码和解码。
1、宏块
在视频编码中,一个编码图像通常划分成若干宏块组成,一个宏块由一个亮度像素块和附加的两个色度像素块组成。一般来说,亮度块为16x16大小的像素块,而两个色度图像像素块的大小依据其图像的采样格式而定,如:对于YUV420采样图像,色度块为8x8大小的像素块。每个图象中,若干宏块被排列成片的形式,视频编码算法以宏块为单位,逐个宏块进行编码,组织成连续的视频码流。
2、片(slice)
为了满足MTU大小的要求,在3G视频传输中对视频进行分片压显得尤其重要。经过分片压缩后的视频码流中通常每个RTP包中包含一个片(也可以对RTP进行分割或合并),一般每个片中包含一个或者几个宏块,以R11P包的大小满足MTU的要求为准。
对视频流进行分片处理,除了满足通信要求之外,另外一个功能是提高视频流的容错能力。H.264/AVC标准规定,帧内编码块只能在同一片中进行帧内预测。这样如果由于传输错误一个片中的数据被丢失,所能影响到只是同一片中的宏块解码,不会影响到同一帧图像中其他片中的宏块解码。将图像划分为多个片,当某一片不能正常解码时的空间视觉影响就会大大降低,而且片的头部还提供了重同步点。
REF:http://www.cnblogs.com/jiangjh/archive/2011/06/30/2094756.html
一个slice是由一系列按光栅扫描顺序排列的宏块组成。一般情况下每个宏块均包含一个16×16 的亮度阵列,当视频格式不是单色时,还包含和两个相应的色度阵列。如果没有使用宏块自适应帧/场解码,每个宏块代表图像中的一个空间矩形区域。例如,如图3.22所示,一幅图像被分为两个条带。
每个slice都是一个独立的编码单位,无论是帧间还是帧内编码都不能越界
REF: http://blog.csdn.net/yangzhongxuan/article/details/8011596
3、帧
视频压缩中,每帧代表一幅静止的图像。
frame的数据可以分为多个slice.每个slice中的数据,在帧内预测只用到自己slice的数据,与其他slice数据没有依赖关系。NAL 是用来将编码的数据进行大包的。比如,每一个slice 数据可以放在NAL 包中。
I frame 是自己独立编码,不依赖于其他frame 数据。I 帧通常是每个 GOP的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。
P frame 依赖 I frame 数据。P帧由在它前面的P帧或者I帧预测而来。解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像。
B frame 依赖 I frame, P frame 或其他 B frame 数据。
I帧 表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)。
P帧 表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)。
P帧: http://baike.baidu.com/link?url=HTNh1PTyKgaWi5NKBQPdEtlerNxvyt_we2s826sYshyDjK_NeIcv5HlNRqpg-xlOpMqgufKBfe8qNq1l2OtlBq
B帧 是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况),换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累~。
REF:http://blog.csdn.net/abcjennifer/article/details/6577934
I、B、P各帧是根据压缩算法的需要,是人为定义的,它们都是实实在在的物理帧,至于图像中的哪一帧是I帧,是随机的,一但确定了I帧,以后的各帧就严格按规定顺序排列。
当视频解码器逐个帧地对比特流进行解码以便重构视频时,必须始终从I帧开始解码。如果使用了P帧和B帧,则必须与参考帧一起解码。在H.264基准类中,仅使用I帧和P帧。由于基准类没有使用B帧,所以可以实现低延时,因此是网络摄像机和视频编码器的理想选择。
帧与IDR帧的区别
举个例子,在一段视频中,
存在以下帧:I P B P B P B B P(绿) I(红) P(蓝) B…
如果这段视频应用了多重参照帧,那么蓝色的P 帧在参照他前面的I 帧(红色)的同时,还可能会参 照I 帧之前的P 帧(绿色),由于I 帧前后的场景可能会有很大的反差甚至根本不同,所以此时P 帧参考I 帧之前的帧不但会没有意义,反而会造成很多问题。
所以一种新型的帧被引入,那就是IDR 帧。如果这段视频应用了多重参考帧的同时采用了IDR 帧,那 么帧的顺序就会变成这样:I P B P B P B B P IDR P B…
由于IDR 帧禁止后面的帧向自己前面的帧参照,所以这回那个蓝色的P 帧就不会参照绿色的P 帧了。
码流结构:
NALU:Coded H.264 data is stored or transmitted as a series of packets known as NetworkAbstraction LayerUnits. (NALU单元)
RBSP :A NALU contains a Raw Byte Sequence Payload, a sequence of bytes containingsyntax elements.(原始数据字节流)
SODB:String Of Data Bits (原始数据比特流, 长度不一定是8的倍数,故需要补齐)
逻辑关系:
SODB 数据比特串-->最原始的编码数据,即VCL数据;
SODB + RBSP trailing bits = RBSP
NAL header(1 byte) + RBSP = NALU
Start Code Prefix(3 bytes) + NALU + Start Code Prefix(3 bytes) + NALU + …+ = H.264BitsStream
REF: http://blog.csdn.net/stpeace/article/details/8221945
在H.264中,一个宏块包括16*16个像素,I宏块有三种形式:
1. 16个I4x4编码方式组成的宏块(为了方便,简称I4x4方式的宏块);
分块越细,就越准确,所以I4x4编码方式适合编码那些纹理比较复杂的宏块
2. I16x16宏块;
I16x16编码方式适合编码那些比较平滑的区域.
3. IPCM宏块(特殊)
不预测,没残差,不变换,无量化等操作,而是直接传像素值,直接将最原始的yuv数据写入到码流中,可见IPCM的信息不会有任何损失
对于一般的P宏块而言,像素残差和运动矢量残差都会写入码流,从编码端传到解码端,但是P-Skip宏块的特殊之处就在于,既不传送像素残差,也不传送运动矢量残差(在这种情况下,像素残差和运动矢量残差必定都为零,所以根本不需要传送).编码端除了传送一些标识该宏块是PSkip宏块的很少量的bit外,不在需要传送关于该宏块的其他信息,那么解码端如何恢复出像素呢?
我们知道,mvd = mv - mvp, 刚才说了,运动矢量残差mvd为零,而从解码端可以得到mvp, 所以,在解码端也就知道了mv。 在解码端有参考帧对应宏块的重建像素,根据这个重建像素和mv, 就可以恢复出本帧本宏块的像素值(如果mv是分数,则需要插值),这就是所谓的P-skip宏块原理,从字面理解就是跳过了这个宏块,相当于这个宏块没有编码,在解码端采取了近似替代的恢复办法。
为什么要引入P-skip宏块呢?如果本帧的一宏块和参考帧的一宏块像素(不要求两宏块在同一位置)几乎完全一致,很显然,当前帧的宏块压根就不用编码,在解码端,直接就可以用近似替代的办法恢复出本帧本宏块的像素值. 比如在第一帧中有个乒乓球,在第二帧中也有个乒乓球,那个第二帧中乒乓球这个宏块就很可能编成了PSkip宏块.
REF: http://blog.csdn.net/stpeace/article/details/8202880
1、帧间预测概念
利用 已编码视频帧/场 和 基于块的运动补偿 的预测模式。
运动估计:
将活动图像分成若干块或宏块,并设法搜索出每个块或宏块在邻近帧图像中的位置,并得出两者之间的空间位置的相对偏移量,得到的相对偏移量就是通常所指的运动矢量,得到运动矢量的过程被称为运动估计。
运动补偿:
根据运动矢量和帧间预测方法,求的当前帧的估计值(预测值)的过程。旨在说明当前图像的每一块像素是如何由参考图像的像素块得到的。
2、帧间预测过程
1. 当前帧在过去帧的窗口中寻找匹配部分,从中找到运动矢量;
2. 根据运动矢量,将过去帧位移,求得对当前帧的估计(预测);
3. 将这个估计和当前帧相减,求得估计的误差值(预测误差);
4. 将运动矢量和估计的误差值送到接收端去。
5. 解码端根据收到的运动矢量将过去帧(参考帧)作位移(也就是对当前帧的估计),再加上接收到的误差值,就是当前帧了。
6. 使用码流中解出的预测块信息,解码器从参考帧中(参考图像列表)得到预测宏块P,它和编码器形成的预测宏块P相同。P+D ->滤波->解码宏块,当前图像所以宏块解码完成后,就得到当前重建图像进行显示,而此图像将用于未来的解码的参考帧。
REF:http://blog.sina.cn/dpool/blog/s/blog_687611bf0101gtnn.html
REF: http://blog.csdn.net/a514223963/article/details/7894779
3、树状结构的运动补偿:
H.264利用已经编码块的运动矢量对当前未编码块的运动矢量进行预测。
编码和传输:实际运动矢量-预测值、每个块的运动矢量、分块方式
4、帧间色度块预测
色度块的MV是通过相应亮度块的MV水平和垂直分量减半而得。
5、帧间预测的特点
不同大小和形状的宏块分割
对每一个16×16像素宏块的运动补偿可以采用不同的大小和形状,H.264支持7种模式(16*16~4 *4)。小块模式的运动补偿为运动详细信息的处理提高了性能,减少了方块效应,提高了图像的质量。
高精度的亚像素运动补偿
在H.263中采用的是半像素精度的运动估计,而在H.264中可以采用1/4(亮度)或者1/8(色度)像素精度的运动估值。在要求相同精度的情况下,H.264使用1/4或者1/8像素精度的运动估计后的残差要比H.263采用半像素精度运动估计后的残差来得小。这样在相同精度下,H.264在帧间编码中所需的码率更小
多帧预测
多帧预测需要解码器和编码器在缓冲中存贮多帧图像作为参考帧。解码器则利用比特流中参数设置信息内存管理控制操作(memory management control operation)去复制编码器相同的多帧缓冲。同时对于每个运动补偿的16×16、16×8、8×16或8×8块及其子块需传送参考索引参数,用于确定该块或子块参考帧在缓存中的位置。
去块滤波器
6、参考图像列表
解码器每解码完一幅图像,都会判断该图像是否用于参考,并标记相应的参考图像,而且会在解码下一幅图像前,将参考图像列表初始化好;解码下一幅图像时,先根据图像的片头信息判断是否需要对参考列表重排序,如果需要,就根据片头的附加信息重新排序,之后开始对图像解码,解码完成后,重新进行参考图像的标记……如此循环。(IDR帧不需要参考帧,它解码完后标记产生第一个参考图像,供之后的图像解码时使用)
REF:http://blog.csdn.net/newthinker_wei/article/details/8784742
http://www.cnblogs.com/general001/archive/2013/04/26/3044833.html
1、一个frame是可以分割成多个Slice来编码的,而一个Slice编码之后被打包进一个NAL单元。
2、NALnal_unit_type中的1(非IDR图像的编码条带)、2(编码条带数据分割块A)、3(编码条带数据分割块B)、4(编码条带数据分割块C)、5(IDR图像的编码条带)种类型与Slice种的三种编码模式:I_slice、P_slice、B_slice
NAL nal_unit_type 里的五种类型,代表接下来数据是表示啥信息的和具体如何分块。
I_slice、P_slice、B_slice表示I类型的片、P类型的片,B类型的片.其中I_slice为帧内预测模式编码;P_slice为单向预测编码或帧内模式;B_slice中为双向预测或帧内模式。
关于H264,通用的6个进阶文档为
1 《H.264_MPEG-4 Part 10 White Paper》
2 《Video coding using the H.264 MPEG-4 AVC compression standard》
3 《H.264 and MPEG-4 video compression》
4 《Overview of the H.264_AVC Video Coding Standard》
5 《Overview and Introduction to the Fidelity Range Extensions》
6 《H.264_MPEG-4 AVC Reference Software Manual》