How tough life is, how strong you should be!
分类: LINUX
2013-02-23 11:11:42
对于有着巨大信息量的视频处理来说,需要研究出更高压缩比、更低码率、更清晰画质的编解码算法。到目前为止,视频编解码的国际标准有MPEG-1,MPEG-2.MPEG-4,H.261,H.263,H.264等。
本课题选择的解码对象是MPEG-4标准码流。之所以选择MPEG-4码流而非H.264码流的原因是:虽然H.264作为新一代的视频编解码标准,在追求更高的编码效率和简洁的表达形式的同时,也提供了非常好的视频质量,是当前最高效的视频压缩方法,但是由于H.264中引入了多种新的编码技术,使得编解码器的计算量急剧增加,对基于手持设备和无线设备的编解码系统来说并不是一种理想的选择,相比之下,基于简单架构的(Simple Profile,SP)的MPEG-4 SP标准则非常适合此类系统。
MPEG-4:MPEG-4标准的突出特点是对音视频数据采用基于内容(Content-based)的操作、存取及传输。MPEG-4标准是一个开放、灵活、可扩展的结构形式,可随时加入新的、有效的算法模板,并可根据不同的应用要求现场配置解码器。
MPEG-4与MPEG-1、MPEG-2以及H.264相比,更注重多媒体系统的交互性和灵活性。最显著的差别在于它采用基于对象的编码理念;即在编码时将一幅景物分成若干个在时间和空间上相互联系的视频音频对象,分别编码后经过复用传输到接收端,在接收端再对不同对象分别解码。最后合成所需的视频和音频。这样便于对不同对象进行不同的编码和操作,也有利于不同数据类型间的融合。
它不但支持码率低于64kbps的多媒体通信,也能支持广播电视级的视频应用。MPEG-4将广泛地应用于数字电视、动态图像、实时多媒体监控、基于内容存储和检索的多媒体系统、可视游戏、基于面部模型的视频会议、交互式多媒体应用、演播电视等,它将推动电信、计算机、广播电视三大网络的最终融合,从而成为今后一段时间压缩标准的主流。
MPEG-4针对不同应用可以使用不同的编解码工具,并同时提出了类(profile)的概念。一个类是可以实现某个MPEG-4功能的一套工具子集。Profile使得用户完全可以根据自己的需要来选择使用相应的MPEG-4工具,并且在构建解码器时也不需要为所有MPEG-4中使用的编码算法准备好相应的解码算法。
MPEG-4标准中定义了很多视频工具(visual tools),每个视频工具都完成一项编码的工作。每个类都有自己支持的视频工具集,以适应各种环境下的使用。Simpile profile主要使用如下的视频工具:
i.I帧编码(I-VOP),内部VOP:只用自己的信息编码。MPEG-4标准将8*8的象素区成为块(block),将16*16的像素区称为宏块(macroblock)。I帧中只有intra块,intra(帧内)块只进行帧内压缩。I帧是作为预测基准的独立帧,具有较小的压缩比。
ii.P帧编码(P-VOP),单向预测VOP: 根据它前面的VOP利用运动补偿技术来编码。P帧包含intra块和inter块,P帧中的inter(帧间)块以本帧之前的图像为参考值做运动预测。由于使用了单向的远动预测,P帧可以得到中等的压缩比。MPEG-4视频中还有一种B帧(双向预测VOP,B-VOP),使用以前和将来的两幅图像做双向的运动预测,可以得到较高的压缩比,但其计算量也是三种类型的帧中最大的。Simple profile不支持B帧。
四类VOP(Video Object Plane视频对象平面):内部VOP(I-VOP)、单向预测VOP(P-VOP)、双向预测VOP(B-VOP)、全景VOP(S-VOP)。
iii.AC/DC预测(AC/DC Prediction)。AC/DC预测是以块为单位进行的。由于图像数据具有空间相关性,在intra块编码中,DCT变换后图像左上方块的直流/交流分量值(AC/DC)可以用来预测右下方的块的直流/交流分量值。
iv.数据分割(Data Partition)。在视频数据编码时,可以将编码后的数据分为纹理,运动矢量和控制字三部分。在接收端,控制字出错对解码的影响最大,运动矢量次之,纹理影响最小。由于对信道编码来说,抗噪性好就意味着码流中引入更多冗余。所以,如果视频数据信源编码时将这三部分分开,分别使用不通的信道编码方式,就可以做到在低带宽传输中尽可能的提高抗噪性。
v. 反向VLC(Reversible VLC)。对于普通的VLC编码,如果码流中有一个bit出现错误,之后的数据都无法解码。反向VLC的码表经过特别设计,从反向也可以完成解码工作。所以,如果反相VLC编码的数据在传输中出现了一个错误,可以从VLC码流的结尾向前解码,一直解到出错的bit,从而成功恢复出更多的码流。反相VLC提高了编码的抗噪性,但也付出了比普通VLC编码效率更低的代价。
vi. 短头(short header)。MPEG-4在编码过程中同加入很多的控制字作为码流的码头。如果使用短头,许多控制字将被省略,解码器会按照协议中固定的配置去解码。短头牺牲了一些编码的灵活性,来换取编码效率和编码速度。
MPEG-4解码就是根据码流中控制信息,调用相应工具,对码流操作的过程。
H.264:MPEG(运动图像专家组)和VCEG(视频编码专家组)联合开发了一个比早期研发的MPEG和H.263性能更好的视频压缩编码标准,这就是被命名为AVC(增强视频编码)。通常被简称为H.264/AVC。视频的各种应用必须通过网络传送,这要求一个好的视频方案能处理各种应用和网络接口H.264/AVC为了解决这个问题,提供了很多灵活性和客户化特性。H.264/AVC的设计方案包含两个层次,视频编码层(VCL,Video Coding Layer)和网络抽象层(NAL,Network Abstraction Layer)。视频编码层主要致力于有效地表示视频内容,网络抽象层格式化VCL视频表示,提供头部信息,适合多种传输和存储媒体。H.264着重于解决压缩的高效率和传输的高可靠性,其支持三个不同不同档次的应用,应用场合相当广泛。其中基本档次主要用于视频会话,如会议电视,可视电话,远程医疗,远程教学;扩展档次主要用于网络的视频流,如视频点播;主要档次主要用于消费电子应用,如数字电视广播、数字视频存储等。但是要实现上述多种强大功能也导致了H.264的算法复杂度较高,不利于在手机终端等能力受限设备上的使用。
数字视频基础:
自然界是由多个有各自特征形状、深度、纹理和亮度的物体所组成。一个与视频处理有关的典型自然视频场景包括空间特性(物体的形状、数目、纹理、颜色等)和时间特征(物体的运动、视点的变换等)。而自然视频场景在空间和时间上都是连续的,因此只要对自然场景的空间特征和时间特征进行采样,我们就可以用数字的方式来表示一个视频的场景。数字视频就是在数字的形式下的一个视频场景的采样的表示。每一个时-空采样(像素)可用一个数或者是一组数来表示采样点的亮度和色度。
摄像头用于把一个视频的场景投影到传感器上,比如一组电荷耦合装置(CCD)。在带色的视频采集中,每一个颜色成员都被过滤并投影到一组CCD中。
空间采样:在空间采样中,一组CCD的输出就是一个模拟的视频信号,一组可以表示视频图像的电信号。在一个时间点上的采样就形成了一个有定值的采样点图像帧。最常用的采样方法是把采样点置于一个正方形或长方形格中进行操作。然后对于水平方向和垂直方向的点二维采样,重建过程就以采样值对应到像素上进行显示。重建图像时,视觉效果取决于采样点的数晕。相同大小的图像,采样点的间隔较大就会得到一个低分辨率的采样图像,而增加采样点的数量就会增加采样图像的分辨率。
时间采样: 在时间采样中,一个运动的视频图像是通过对图像信号在周期性的时间间隔上进行采样得到的。重放这一系列的帧会得到一个运动的效果。一个高的时间采样率(帧率)会产生更加平滑的运动,但是它就要求有更多的采样要被捕捉并被保存。
在10帧/秒之下的帧率一般被用于一些很低码率的视频通信中,因为被传输的数据量非常的小。但是运动却看起来很笨拙而且不自然。在10-20帧每秒是比较经典的低码率视频。在25-30帧每秒进行采样是标准电视信号图象的采样帧率,如果配合隔行扫描采样来达到更好的运动效果。50-60帧每秒就可以形成平滑的运动,这样的代价就是帧率太过高,传输和存储的压力大。
颜色空间: 大多数字视频程序都依赖于彩色视频的显示,因此需要一个来捕捉并表示颜色空间的方法。一个单色的图像只需要一个在空间内表示一个像素点的亮度的值就可以了。但对于彩色图像来说,对于一个像素点至少需要三个数来把颜色信息准确地表示出来。颜色空间主要有RGB和YCbCr两种表示方法。
RGB颜色空间:在RGB颜色空间中,一个带颜色的图像采样是用三个值来表示一个像素点的相对的红、绿和蓝色比例。任何颜色都可以通过把红、绿和蓝来通过不同的比例相混得到。RGB颜色空间更加适合于捕捉并显示彩色图像,但是由于人类的视觉系统对亮度的敏感度大于颜色,而在RGB颜色空间中,三种颜色是被平等看待的,并用相同的分辨率存放起来。基于RGB颜色空间的相对缺点而提出的YCbCr颜色空间是通过把亮度和颜色信息分离,并对亮度值取更高分辨率可以更有效的表示一幅彩色图像。
YCbCr颜色空间和它的变换(通常写为YUV)是一种流行而高效的图像表示方法,两者之间转换方程如下:
Y=krR+kgG+kbB
Cb=B-Y
Cr=R-Y
Cg=G-Y
其中Y是亮度值,可由R,G和B的加权平均得到。在YCbCr颜色空间中,一个图像的完整描述可由给定Y和三个色差:Cb,Cr和Cg来表示。
在YCbCr空间中,Cb+Cr+Cg是一个常数。只有Y和Cb,Cr值被传输和存储。而人类视觉系统对于亮度更加敏感,为了减少图像表示的数据量,所以Cb和Cr的分辨率可以比Y低。因为人类的视觉系统相对于色度来说对亮度更加敏感,这就减少了表示图像的数据量。,低分辨率色差并不会对图像的质量产生影响,RGB和YCbCr表示的图像看上去没有什么不同。因此对于色度采样比亮度低的分辨率进行采样是一种最简单的压缩方法。
图像格式的几种常见的转换算法。。。
视频压缩(视频编码)是把数字视频流用更少的数据位进行存放的方法。未经压缩的视频数据量非常大,所以压缩对于数字视频的存储和传输来说都是必须的。图像压缩包括一对互补系统,一个编码器(encoder)和一个解码器(decoder)。编码器利用图像数据之间的相关性。在保证图像质晕的情况下使用较少的数据以传播或存储该图像;而解码器则把压缩后的图像还原出原始的视频数据。
图像数据中的冗余信息主要包括空间冗余,时间冗余,信息熵冗余,结构冗余,比例冗余,视觉冗余等。利用图像数据不同类型的冗余,科研工作者制定了不同的压缩算法,有些复杂的压缩算法则利用了几种不同类型的冗余。压缩算法的分类较多,一般来说可以分为无失真压缩和有失真压缩两大类。
无失真编码,又叫作熵保存编码,也称为熵编码,这种编码结果经解码后可无失真的恢复出原图像。一般来说压缩率不是很高。无失真编码的算法主要有:霍夫曼(Huffman)编码,算术编码,行程编码(Run Length Code)。
考虑到人眼对失真不易察觉的生理特征时,有些图像编码不严格要求熵保存,信息可允许部分损失以换取高的数据压缩比,这种编码是有失真数据压缩,通常运动图像的数据,通常运动图像的数据压缩都使用有失真编码,香农(Shannon)率失真理论对此有比较深入的解释,在此就不再赘述了。有失真编码的算法主要有:预测编码,变换编码,运动补偿和估计,小波变换(wave.1et)编码,分形编码等。
图像数据的压缩主要是对各种图像数据冗余度及视觉冗余度的压缩,包括如下一些方法:
一、统计冗余度的压缩:对于一串由许多数值构成的数据来说,如果其中某些值经常出现,而另外一些值很少出现,则取值上的统计不均匀性就构成了统计冗余度。利用该统计不均匀性可对视频数据进行压缩:经常出现的值用短码表示,对不经常出现的值用长码表示,因而.相对于定长表示法,用这种方法表示一串数据可以节省码位。这就是霍夫曼编码的思想。霍夫曼编码是无损压缩,目前在图像压缩编码中被广泛采用。
视频图像在每一点的取值上具有任意性。对于运动图像而言,每一点在一段时间内能取任意值,在取值上具有统计均匀性,难以直接运用霍夫曼编码的方法,但可以通过适当的变换编码的方法,如DCT变换,使原图像变成由一串统计不均匀的数据所表示,然后利用霍夫曼编码进行压缩。
二、空间冗余度的压缩:一幅视频图像相邻各点的取值往往相近或相同,具有空间相关性,这就是空间冗余度。图像的空间相关性说明相邻象素点的值变化缓慢。从频域的观点看,这意味着图像信号的能量主要集中在低频附近,高频信号的能量随频率的增加而迅速衰减。通过频域变换,可以将原图像信号用直流分量及少数低频交流分量表示,这就是变换编码中的离散余弦变换DCT的原理。DCT变换是MPEG-4压缩编码的基础,它可以对图像的空间冗余度进行有效的压缩。
变换编码不直接对空域图像信号进行编码,而是将空域图像信号变换到另一个正交矢量空间(变换域、频域)进行处理,在空域上具有强相关性的信号在变换到频域上之后相关性将大大降低,对频域信号进行量化之后就能达到压缩的目的。在视频变换中,应用最广泛的是DCT。
视频图像中经常出现一连串连续的象素点具有相同值的情况,典型的如彩条,彩场信号等。只传送起始像素点的值及随后取相同值的象素点的个数,也能有效地压缩码流,这就是游程编码(Run Length Coding)。由于DCT变换后高频部分0数据较为集中,如果把数据按照由低频剑高频的方式连接起来,将使游程编码得到更高的压缩率,这就是zigzag扫描。目前在图像压缩编码中,行游程编码并不直接对图像数据进行编码,主要用于对zigzag扫描后的DCT系数进行编码。 (原始图像->DCT变换->zigzag扫描DCT系数->游程编码)
三、时间冗余度的压缩:时间冗余度表现在视频画面中相继各帧对应像素点的值往往相近或相同,具有时间相关性。在知道了一个像素点的值后,利用此像素点的值以及其与后一像素点的差值就可求出后一像素点的值。因此,不传送像素点本身的值而传送其与前一帧对应像素点的差值,也能有效地压缩码率,这就是差分编码。在实际的压缩编码中.差分编码主要用于各图像块在DCT变换后的直流系数。相对于交流系数而言,DCT直流系数的值很大。而且相继各帧对应子块的DCT直流系数的值一般比较接近,在图像未发生跳变的情况下,其差值同直流系数本身的值相比是很小的。
由差分编码进一步发展起来的是运动预测编码,其过程为:对于当前帧中的一块图像,在一个参考帧中搜索与本块图像数据最接近的块,计算出两个块位置差值,即运动矢量,然后将这两个块的图像数据差值与运动矢量传送给接收端。接收端根据运动矢量及差值恢复出原图像。由于运动矢量及差值的数据量低于原图像的数据量,因而运动预测编码也能达到压缩图像数据的目的。
预测编码方法分线性预测和非线性预测编码方法,其中线性预测编码方法也称为差值脉冲编码调制法,简称DPCM(Differention Pulse Code Modulation),这是比较常用的一种编码方法。对于压缩率要求不高的系统应优先考虑预测编码,因为它比较简单,容易实现。另外还有运动补偿预测,这是利用时间冗余的预测编码技术,对于帧间图像常常使用这种预测编码技术。
四、视觉冗余度的压缩:视觉冗余度是相对于人眼的视觉特性而言的。人眼对于图像的视觉特性包括:对亮度信号比对色度信号敏感,对低频信号比对高频信号敏感,对静止图像比对运动图像敏感,以及对图像水平线条和垂直线条比对斜线敏感等。因此,包含在色度信号,图像高频信号和运动图像中的一些数据并不能对增加视觉清晰度作山贡献,而被认为是多余的,这就是视觉冗余度。
压缩视觉冗余度的核心思想是去掉那些人眼看不到的或相对于人类视觉可有可无的幽像数据。对视觉冗余度的压缩通常已反映在各种具体的压缩编码过程中。如对于DCT系数的直流与低频部分采取细量化,而对高频部分采取粗量化,使得DCT变换能借此压缩码率。在帧间预测编码中,大码率压缩的预测帧及双向预测帧的采用,也是利用了人眼对运动图像细节不敏感的特性。
图像压缩编码的具体方法虽然还有多种,但大都是建立在上述基本思想之上的。相关国际组织制定的各种视频编码标准也主要由DCT变换,游程编码,帧间预测编码及霍夫曼编码等编码方法构成。
小波变换(Wavelet Transform)简称WT,也称为子波变换,是一种具有很好局域化(在时域和频域)的时一频(在图像处理中也称为空-频)分析的综合方法。针对不同类型的图像特点中的不同区域采用不同的空-频分辨率,有可能得到比其他变换方法更高的压缩比。而且与其他变换相比,基于DWT(离散小波变换)的多分辨率分析具有与人类视觉系统相匹配的特性。
小波变换编码器可以分别处理信号的高频部分和低频部分,这与目前应用较广的DCT不同,DCT的方法是从数据流中去除了绝大多数的高频信息。由于高频成分大多是由于边缘引起的,而边缘对于图像的识别相当重要,因此小波变换的应用对于图像边缘的识别有非常重要的意义。另外,小波变换中的图像是作为一个整体被传送的,而基于DCT的编码方法是把图像分成像素块来传输的,因此基于小波变换的编码不会出现块效应。
基于DWT的编码算法可以获得比基于DCT编码算法更高的编码效率,但是小波变换的运算量很高,因此DCT编码算法现在依然应用广泛,而小波算法则在对图像要求较高的地方被应用。
视频编解码器模型
视频编码器将图像或者视频流编码成某种格式的压缩文件,解码器对压缩后的文件进行解码产生与原始相同或者相近的视频流,视频编码器如下图所示。视频编码器主要分为3个功能单元:时域模型、空域模型和熵解码器。
时域模型的输入是未压缩的原始视频流,通常原始视频流的相邻帧之间有较大相似性,根据这个特点,通过建立时域模型来建立预测帧从而降低时域冗余。时域模型中,当前帧减去预测帧得到残差图像,预测帧越准确,得到的残差图像能量越小。残差图像经过编码后传输到解码器,解码器通过与残差图像相加来恢复当前帧图像以重建相应的预测帧。预测帧的重建可以参考一帧或多帧、之后或之前的图像(即参考帧),精度可通过参考帧和当前帧直接的运动补偿来提高。
视频编码器框图
空域模型的输入是残差图像,它利用相邻像素点之间的相似性,消除残差图像的频域冗余。MPEG-4和H.264标准中,编码器对残差图像进行频域变换,量化得到相应的系数。变换系数经过量化后保留的残差系数作为空域模型最后的输出。
MPEG-4视频信号是由一系列单独的帧组成的。每一帧可以单独地进行压缩解压缩,如下图就是对图像的编解码过程。这种称为帧内编码(Intra-frame Coding),每一帧在"内部"进行编码,没有参考其他帧。
图像编码器
但是,消除视频序列中的时间冗余信息,可以达到更好的压缩效果。具体通过给图像编解码器增加一个"前后帧"来实现,主要有两个功能:
l、预测:基于一个或多个先前传输的帧来建立对当前帧的预测;
2、补偿:从当前帧中减去预测帧来产生一个残差帧。
以后就用"图像编解码器"来处理残差帧。其中关键是预测功能,如果预测准确,残差帧将包括较少的数据,这样就可以用图像编解码器进行有效的压缩。为了解码帧,解码器必须"逆反"补偿过程,把预测加到解码的残差帧中去重建,这个过程就是帧间预测(Inter-frame Coding),示意图如下图。
带预测的视频编解码器
MPEG-4视频编解码器:
MPEG-4分层描述语法结构:
MPEG-4引入了视频对象VO(Video Object)的概念,支持基于内容的交互功能和分级扩展(空域分级、时域分级)。一个视频对象可以是视频场景中的任意的一块区域,它的存在时间可以任意长。视频对象平面VOP(Video Object Plane)是每一具体时刻的视频对象。这样就将图像序列中的每一帧中的场景,看成是由不同视频对象平面的VOP所组成的,同一对象连续的VOP称为VO。视频对象可以是视频序列中的人或具体的景物,如电视新闻中的播音员,或者电视尉中的一部运动的汽车;也可以是在计算机技术合成的二维或者三维图形。
MPEG-4编码、解码过程是在VOP上进行的。因此输入视频序列通过分析可将其分割为多个视频对象,对同一VO编码后形成V0P。下面2幅图分别显示了矩形图像帧VOP和任意形状的VOP。VOP的编码采用了和以前的MPEG标准类似的编码原理:DCT和运动估计等算法。由于V0P可具有任意的形状,所以要求编码系统可处理形状(shape)信息,这和只能处理矩形帧序列的传统视频编码标准相比有很多不同之处。在MPEG-4中,矩形帧被认为是V0P的一种特例,这时编码系统不用处理形状信息,退化成了类似的MPEG.2m.263的传统视频编码。
矩形VOP和VO
任意形状VOP和VO
下图,MPEG-4的视频码流提供了对视频场景的分层描述。层次结构中的每一层都可以通过被称为起始码的特殊码字,从视频流中识别出来。用来描述场景的分层级为:
MPEG-4码流层次化结构图
(1)视频序列VS(video Session):完整的MPEG-4场景,可以包括任何二维和三维自然或合成对象以及它们的增强层。
(2)视频对象VO(Video 0bject):一个视频对象对应着场景中的一个特定2D对象。在大多数简单场景中视频对象都是一个矩形帧,当然也可以是任意形状的对象或是场景中的背景。
(3)视频对象层V0L(Video Object Layer):根据应用的具体要求,每一个视频对象都可以用分级或不分级的方式进行编码,用视频对象层来表征。视频层提供了对分级编码的支持,一个视频对象可利用空间或时间可伸缩性进行编码,使分辨率从粗糙到精确。
(4) 视频对象平面VOP(Video 0bject Plane):一个VOP是对一个视频对象的时间采样,包括视频对象的运动参数、形状信息和纹理数据。VOP可以是相互独立编码,也可以是通过运动补偿依靠其它VOP编码。对VOP编码就是针对某一时刻该帧画面VO的形状、运动、纹理等信息进行编码。
鉴于以上所述的这种编解码的思想,下图是符合MPEG-4标准的简单档次的编码器的原理框图。
MPEG-4编码器原理框图
MPEG-4视频部分致力于通过基于工具箱的视频信息编码方法来满足各种视频通信的应用需求。MPEG-4没有明确定义编解码器,着重定义了编码视频的码流语法及对此码流解码的方法。兼容的MPEG-4编码器包括功能模块如上图,除滤波器外,大部分基本功能(预测、变换、量化、熵编码)和其他视频标准(MPEG-1、MPEG-2、H.26l、H.263、H.264)一样采用相同原理。
编码部分…
MPEG-4视频解码技术:
MPEG-4压缩视频的码流结构: 通过MPEG-4码流的分析有助于更好的理解MPEG-4解码流程,MPEG-4标准定义了一个标准MPEG-4码流中的每一位的具体含义。MPEG-4码流的组织形式是按分层的形式组织起来的。如下图所示(其实对很多标准的码流都是这样的)。
码流的分层组织
首先,码流头是一个在码流中其它地方不会如现的一个比较长的特殊序列,又叫起始码字;然后是具体的头信息,它定义了整个码流的一些特征,这些特征将会对如何对这个码流进行解码产生影响,例如,帧的长度和宽度,该码流使用投术等。帧头,首先是帧起始码字;然后是具体的帧头信息,它定义了当前帧的一些特征,例如当前帧使用的量化值等,这些信息决定了该如何解码当前帧。从宏块头开始就是具体的数据了,宏块头并没有一个宏块起始码字,它紧跟在帧头信息后面。
按照上文的分析,只要给出一个符合MPEG-4标准的码流,就能按照标准定义的码流形式对这个码流解析并进行解码。首先,搜索码流起始码字,由于起始码字唯一,只要码流正确,肯定能搜索到,找到起始码字后,就可以对码流头信息进行解析,并把对后面的解码有影响的码字保存下来;接着,寻找帧头起始码字,找到后,对帧头信息进行解析,并存储对解码过程有影响的码字;最后,从码流中读出宏块数据,并进行解码,恢复为原来的图像。
这个过程有助于理解视频解码器的解码流程,此部分介绍码流的定义为解码流程分析打下了基础,从而更好的实现最终解码器算法的优化与实现。
MPEG-4视频解码的基本流程:
VOP是MPEG-4的基本编码单元,它包含视频对象边框的足寸。下图可以看出一个VOP的解码过程,MPEG-4视频解码主要由三部分组成:形状解码、运动解码和纹理解码,重建的VOP是通过合并解码的形状、运动和纹理信息得到的。
MPEG-4解码流程
解码器的实现
解码器流程图:在解码器的初始化部分定义了解码器所需要的各种数据结构,设置相应的各种默认参数。当初始化完成之后,根据视频流的头数据得出该编码视频流的帧大小,然后以帧为单位循环处理。
解码器流程图
在循环过程中,根据视频流语法格式依次读出对应的视频帧的头信息数据进行分析,得出与该帧的编码相关的各个参数,为解码器的相关参数赋值。根据读出的编码类型判断当前处理的视频压缩帧应该以何种方式进行解码。如果当前压缩帧为I-VOP编码,则对该帧进行相应的I-VOP解码;否则,为实现的简便性考虑,我们在编码器的实现中仅处理I-VOP和P-VOP两种情况,所以如果不是I-VOP的编码那么当前帧就为P-VOP的编码方式,则我们采取相应的P-VOP的解码方式进行解码。不论是I-VOP还是P-VOP方式的编码帧,只要进行解码之后,都将解码后恢复的视频数据存入固定的缓冲区中,在每一个循环过程的最后,需要将缓冲区中的数据写入待生成的图像数据文件中。一个编码帧解码结束之后,判断压缩视频流中的数据是否结束,如果结束,则解码过程结束,否则返回循环过程的开始继续解码下一压缩视频帧。
头信息的解码
解码的过程与编码过程成对应关系。首先看VO、VOL、VOP头信息的编码和解码过程。编码时,若编码第一帧,则首先调用函数PutVoVolHeader对VO、VOP的头信息进行编码,在以后对每一帧编码时,即编码VOP时,首先调用函数BitstreamPutvopHeader对每个VOP的头信息进行编码。与此相对应,在解码时,首先调用函数getvolhdr解码V0、VOL的头信息,然后在解码每一帧时,调用函数getvophdr获取V0P的头信息。在实现代码中可以看到这些头信息的编码和解码具有严格的对应关系。
函数PutvovolHeader和函数getvolhdr对应,对如下信息进行编码和解码:
函数BitstreamPutVopHeader和函数getvophdr对应,对如下信息进行编码
在这个过程中解码出来的编码模式prediction_type(inter或intra) 决定后面的解码模式(inter或intra);解码出来的量化参数信息quantizer决定解码器逆量化部分的量化参数。
VOP的解码
完成前面的头信息解码之后,解码器开始针对每个V0P进行解码,调用函数get-mp4picture来完成这个过程。该函数的实现过程为:
(1)初始化宏块的循环控制变量;
(2)循环调用宏块解码函数macroblock对VOP中的每一个宏块进行解码;
(3)调用函数make_edge对上一步获得的解码帧frame—ref(亦作为参考帧)进行边缘填充;
(4)调用函数PictureDisplay将frame_ref图像转换为bmp图像;
(5)将当前帧与参考帧交换。
宏块的解码
上面说明的是VOP解码的整体过程,下面着重说明其中的关键函数macroblock的实现。VOP的编码过程是基于宏块的,所以VOP解码过程同样是基于宏块的,因此此函数是解码的核心函数,它一方面通过VLD(可变长解码)、RLD(行程解码)、IQ(逆量化)、IDCT(逆DCT变换)解码出原始图像值(I_VOP)或误差值(P-VOP);一方面解码出运动矢量Motion Vector,并进行MC(运动补偿)。宏块解码的过程如下:
1)宏块头信息解码
解码出宏块的头信息,这些信息由编码器调用函数Bits_CountMB_combined编码,它们包括COD(1 bit):解码为变量not_coded,决定是否coded macroblock(该宏块是否被编码)。
MCBPC:编码时调用函数PutMCBPC_Intra或PutMCBPC-Inter完成编码(使用VLC),解码时调用函数getMCBPC完成解码,用以决定编码的宏块类型derived_mb_type(INTRA,INTRA_Q,INTER,INTER_Q,INTER4V)。
Ac_pred_flag(1 bit):当宏块类型为INTRA或INTRA_Q时解码。
CBPY:编码时调用函数PutCBPY完成编码,解码时调用函数getCBPY完成解码,结果用以得到cbp值。
Dquant(2 bits):如果宏块类型为INTER_Q或INTRA_Q,则要解码dquant值,用以修正量化参数quantizer。
2)运动矢量解码
接下来,如果宏块类型为INTER、INTE_Q或INTER4V时,对运动矢量进行解码,调用函数setMV。该解码部分对应的编码部分,即运动矢量的编码由编码器调用函数Bits_countMB_Motion来完成。
函数setMV的调用形式为setMv(int block_num),由参数blocke_num控制不同类型宏块的运动矢量解码方法。当宏块类型为INTER或INTER_Q时,将block_num设为-1,调用形式为setMV(-1);当宏块类型为INTER4V时,调用形式为
for(j=O; j<4; j++) { setMV(j) };
setMv函数分别对X方向和Y方向运动矢量进行解码,他们的解码方法一样,这里只看x方向矢量的解码。首先调用函数getMVdata,hor_mv_data=getMVdata(),使用VLD(可变长解码)获得编码的运动矢量,如果scale_fac=l,即度量因子为l,或hor_my_data=0,则mvd_x=hor_mv_data,即得到的就是motion vector difference;否则,先用FLD(固定长解码)解码出my residual,再进行逆Scale操作,得到mvd_x。
按下来调用函数find_pmv,计算运动矢量的预测值:compute motion vector prediction.此过程对用于编码函数find_pmvs。该函数的调用形式为int find_pmv(int block,int comp)。由参数block决定对INTER类型的宏块还是对INTER4V类型的宏块解码。对应的代码如下:
if(block_num=-1){//it is for INTER macroblock
pmv_x=find_pmv(0, 0);
pmv_y=find_pmv(O, 1);
}
else{//it is for INTER4V macroblock
pmv_x=find_pmv(block_num, 0);
pmv_y=find_pmv(block_num, 1);
最终解码出的运动矢量由mvd_x部分和pmv_x部分相加得到:
mv_x = pmv_x + mvd_x;
if(mv_x < low)
mv_x -= range;
if(mv_x > high)
mv_x -= range;
然后将结果保存起来,供后续的运动补偿MC使用。
运动补偿及块解码
如果宏块类型为INTER,INTER_Q或INTER4V,则先进行运动补偿,然后解码出误差值,将补偿值和误差值相加得到原始宏块的解码结果。如果宏块类型是内部宏块(INTRA, INTRA_Q),则直接进行宏块的纹理解码。
块解码函数blockInter和blockIntra是解码的核心函数,它们执行编码块信息的VLD,IQ和IDCT。BlockInter函数的实现过程是:首先循环调用函数vld_inter_dct,VLD得出VLC编码得到的误差值块信息,直到解码完整个块,与此同时进行逆量化得出DCT变换编码得到的变换系数。然后调用函数IDCT,进行逆DCT变换。BlockIntra函数比B1ockInter更复杂一些,它首先FLD(固定长解码)得出DC系数,然后重构DC系数,接着循环调用函数vld_inter_dct,VLD得出AC系数,然后重构AC系数,解码得出DC和AC系数之后,再调用函数iquant对它们进行逆量化IQ,最后调用函数IDCT进行逆DCT变换。这部分的解码与编码器中函数CodeMB和函数MB_CodeCoeff相对应,它们在对每一个宏块的编码过程中被调用。
块解码完成之后,就调用函数addblockInter和函数addblockIntra,将解码结果加入到解码帧上。
未编码宏块的处理
如果宏块没有被编码(not_coded=1),则将解码的矢量设为0,宏块模式设为NOT_CODED,并执行重构操作。