H.264编解码
H.264编解码(精选7篇)
H.264编解码 第1篇
关键词:图像采集,FPGA,中值滤波,图像预处理
近年来,随着多媒体技术的不断发展,视频图像的传输应用越来越广泛,在视频图像的采集和传输过程中,由于温度、光照、电信号等因素的影响,很容易在视频图像采集的过程中引入噪声,这对图像的显示和欣赏效果造成了一定影响。因此,在视频图像的采集和传输过程中,对图像进行一定的降噪处理是有必要的。 为了降低图像噪声,可对编解码系统中采集到的图像进行预处理,将滤波预处理之后的图像再存入编解码系统中。由于图像的实时性,对图像预处理的处理速度提出了较高的要求,普通软件处理速度达不到要求,而FPGA具有较快的处理速度,成为实时图像处理的首选[1]。
本文基于面向H. 264视频编解码系统,在充分考虑系统实时性的基础上,以FPGA为核心的处理部件,设计了具有较高处理能力的中值滤波器对视频图像进行预处理,有效消除了图像中的噪声,避免了噪声的逐级传递,达到了较高视频图像质量和较好视觉效果的目的。
1图像预处理算法
1.1BT656和YUV420格式转换
本文设计的视频图像预处理系统,主要是基于面向H. 264视频编解码系统上的。如图1所示,是编解码系统的部分架构,包括了视频图像采集、A/D转换和预处理,SAA7113芯片将摄像头采集到的模拟信号转化为BT656格式的数字信号。
BT656格式,即YCrCb422( YUV422) 格式,YUV422格式在每行像素中,亮度信号Y数据和色度信号U、V数据的比例都是2 ∶ 1[2,3,4,5,6],为了节省数据量,本文中采用YUV420的格式,因此需要将BT656格式和YUV420格式进行格式转换。YUV420格式的每行和每列,Y数据和U、 V数据的比例都是2∶ 1,即4个Y值共用一个U和V,这样就在垂直方向数据量比YUV422格式数据量减少了1/2。
本文采用的转换方法是丢弃偶数行像素点的色度信号Cr和色度信号Cb,从而使得每两行的4个像素点公用一个色度信号Cr和一个色度信号Cb,使得存储的视频图像数据能进一步减少[6],而不影响图像的质量。 假设Yxy表示亮度信号在( x,y) 位置处的值; Crxy、Cbxy表示了色度信号在( x,y) 位置处的值,则BT656格式和YUV420有如下的对应关系
1.2中值滤波原理
中值滤波器就是用该像素相邻像素的像素值的中值来代替原中心像素点的值
中值滤波器的应用较广,对于由随机信号引起的噪声如脉冲噪声等等,中值滤波不仅具有良好的去噪能力,且在相同尺寸下相比线性平滑滤波器能够更好地保护图像的细节部分。由于中值滤波器的这些特性,使其在图像滤波领域应用广泛。
针对YCrCb420格式的特点,需采用合适的中值滤波设计对视频图像的噪点进行处理。由于YCrCb420数据的存储是按照Y、Cr、Cb的顺序。因此,可通过流水的方式依次对存储在DDR II存储器中的Y、Cr、Cb数据进行处理。以亮度信号Y为例,本设计中,中值滤波的计算步骤如下: ( 1) 将窗口的中心与图像中的某个像素点的位置重合,然后让滤波窗口在图像中滚动, 每次只移动一个像素点。( 2) 读取窗口内包含像素点的亮度值。( 3) 将这些亮度值按照从小到大的顺序排列,确定排序位于中间值。( 4) 用中间值来代替滤波窗口中心的亮度值。( 5) 由于滤波窗口的中心不可能位于图像边缘,需要对图像的边界进行单独处理。
对于分辨率 为640 × 480的视频图 像而言, YCrCb420数据亮度信号的大小为640 × 480 × 8,而色度信号Cr和Cb分别为320 × 240 × 8。以亮度信号为例,中值滤波原理如图2所示。
2中值滤波器设计
在实际去噪的过程中,滤波窗口的大小对滤波效果的影响比较大,若窗口选取较小,虽可有效地保护图像的细节信息,但去噪的效果会相对较弱; 若窗口选取较大,去噪效果会加强,但会使滤波后的图像更加模糊,丢失了细节信息,且滤波窗口越大会相应的消耗更多的资源[7,8]。因此,从资源和效率方面综合考虑,本设计中,中值滤波的窗口采用3 × 3的方形滤波窗口。 根据上述中 值滤波原 理及窗口 选取,本系统中YCrCb420视频图像的中值滤波的设计如图3所示。
如图3所示,首先要从DDR II存储器中读取YCrCb420数据,对Y、Cr、Cb数据分别进行中值滤波来去除像素值中的噪点。将读取的数据送入3 × 3的窗口生成模块,然后将窗口中的9个数据送入中值比较模块得出中值。由于边缘数据无法位于3 × 3窗口的中心,即无法用求中值的方式来更新边缘数据。因此, 要通过边缘检测模块将边缘的数据单独进行处理。最终,将得到的中值和边缘数据重组,得出所需数据并送入DDR II存储器中[9,10,11]。
( 1) 视频图像数据读取模块。系统采用Altera公司的QYSY平台,总线协议为Avalon协议,设计中从DDR II存储器中读数据要满足Avalon总线的协议要求。为了提高数据的读取速度,图像数据的读取过程采用Avalon master read( 主端口读) 的模式。此外,为了加快数据的读取速度,实际的设计中还采用了带突发传输属性的模型进行数据读取[12,13]。
( 2) 3 × 3的窗口生成模块。3 × 3窗口通过使用3个FIFO来实现,每一个FIFO存储一行的数据,待准备好后,每个FIFO连续出3个数据,形成一个3 × 3数据的窗口,具体实现如图4所示。
由于采用3 × 3的窗口模式,所以要保证每次进入窗口中的数据是来自3个不同的像素行。因此在开始将数据送到3 × 3的窗口之前,要对两行像素数据进行存储,等到第三行数据到来时,才将数据一起送入3 × 3的滤波窗。设计采用同步FIFO进行数据存储,同时通过FIFO的usedw信号进行数据的填充记录。这里两个同步FIFO用于进行前两行数据的存储,第三行数据则是通过前面的异步FIFO的输出来提取。在两行数据都在FIFO中准备好时( 其中第一行数据存入line_ 3中,第二行数据存入line_2中) ,一旦line_3的FIFO读信号开始有效时,便将3行数据送入3 × 3中( 第3行数据由line_1的输出实时的送入)
( 3) 中值生成模块。对于3 × 3窗口中的9个待处理数据,中值滤波的基本思想是通过比较得出这9个数的中值。中值滤波的输出值由领域数据的中间值决定。具体的比较过程如图5所示。
为加快处理速度,设计采用流水线技术。由于前一个步骤的输出是下一个步骤的输入,可考虑采用流水线技术,以提高系统的工作频率。由于前后操作使用相同的比较操作,前后级处理的时间相等,均是一个时钟周期,可直接将前级的结果送入下一级。
通过7次比较,便能得出一个处理过的中值来代替原本窗口中间的值。由仿真波形可知,从数据准备好开始,到得出一个中值,只需4个周期的时间。数据连续输入,中值也可连续的输出,除了上述提到的在每3行的结尾处需要等待两个周期。这里比较器的作用是通过比较找出3个数据中最大值、最小值和中值。
( 4) 边缘数据检测及处理。如图3所示,在窗口移动过程中,只能处理窗口中间的数据,由于边缘的数据不可能作为窗口中间值,对于边缘的数据必须要进行单独处理。由于数据按行读出的,边缘数据包括第一列和最后一列的数据以及每一行的第一个数据和最后一个数据。边缘检测的实现如图6所示。
设计采用不对边缘数据进行处理的方式,仅将边缘数据保留原值。边缘数据通过line_2的FIFO的输出来检测,设置行和列计数器。必须保证第一个处理完的中值必须在第二行的第一个数据之后和第二行的最后一个数据之前到来。这种方式有利于数据的恢复。最后将经过中值滤波的数据和边缘数据进行重组后写回到DDR II存储器中,然后送入到H. 264视频编码器中用于视频编码。
3仿真验证
实验中,通过FIFO2来控制每行数据的边缘检测, 保证利用最短的周期重组数据,当遇到边缘数据时,经过5个寄存器进行暂存; 当遇到中值数据时,直接使用。 然后将边缘数据和中值数据重组并经过异步FIFO后, 生成一个32位数据,图7中data即为最终重组数据。
对于图像预处理的滤波效果,本文将带有椒盐噪声的图像数据输入到图像预处理系统中,对滤波效果进行比较,如图8所示,经过图像预处理后直观滤波效果良好,有效降低了噪声。
4结束语
H.264编解码 第2篇
关键词:无线信道,视频通信,H.264,编解码器,优化
0引言
随着多媒体应用在无线和移动网络环境中需求的日益增长,无线视频传输技术得到了越来越广泛的应用。但是,由于无线信道具有易错、时变和带限的特点[1],信道的误码率要比有线环境大得多。而且信道随着基站和终端位置、方向的改变而变化很大,还会导致严重的衰落和突发性错误。因此基于无线的视频传输是一个具有挑战性的课题。
无线视频传输面临以下问题:
(1) 无线信道环境恶劣,有效的带宽资源十分有限,使得无线移动网络难以提供可靠的服务质量,无线传输中经常会出现连续的、突发性的传输错误,信道的可用带宽、传输速率具有时变的特性,信道误码率很高。
(2) 实时性要求高。人眼对视频信号的基本要求是:延迟小,实时性好。相对普通数据通信而言,视频通信要求更好的实时性。
(3) 无线视频的QoS保障。在移动通信中、用户的移动造成无线视频服务的QoS保障十分复杂。
为了能在时变、带宽有限、误码率较高的无线信道上传输视频数据,视频编码算法必须满足以下要求[2]:
(1) 高效的视频压缩比;
(2) 较高的传输实时性:更短的传输时延,更快的编码速度;
(3) 较强视频传输鲁棒性:更好地适应传输信道的误比特干扰。
H.264是由ISO/IEC与ITU-T组成的联合视频组(JVT)制定的新一代视频压缩编码标准。H.264有实用性、移动性和IP网络的适应性三个方面的技术特点,并在混合编码的基本框架下,其关键模块做了重大改进,如多模式运动估计、帧内预测、多参考帧预测、基于内容的变长编码、2维44整数变换、1/4Pixel精度预测、去块滤波等[3,4]。总之,H.264高效编码是以较高的运算复杂性和对硬件的高要求为代价的,如果编码器包含H.264所有功能,那么编码的计算复杂度至少是MPEG4或H.263的10倍以上,而解码复杂度则大约相当于H.263的2倍。同时,H.264标准提供了移动环境中包丢失和误码的恢复工具,标准中的视频编码层和网络适配层的分层结构提高了网络的友好性。由此可以看出,H.264视频流适合在误码、丢包的无线环境中传输,H.264标准是无线传输系统的首选的视频压缩标准。
1H.264编解码器的软件优化
本文主要是将H.264编码算法应用在嵌入式系统无线环境中,实现视频编解码,并且提高效率、增强抗干扰性。嵌入式系统硬件资源(内存和CPU资源等)有限,给无线实时视频编解码带来困难。因此,需要采用多种方法解决硬件资源有限的困难和操作系统的局限性,以满足无线实时视频通信的要求。由于H.264编码算法的计算复杂度很高,不能对采集到的视频进行实时编码,所以需要对编码软件进行相应的优化。
1.1H.264编解码器的优化设计
在嵌入式系统无线环境中实现基于H.264的视频编解码器,主要难点有:如何在内存资源非常有限的情况下完成视频通信;如何在嵌入式操作系统下有效实现视频采集、显示、视频编解码、分组传输等多线程调度的管理;如何在有限CPU资源下,完成H.264实时编解码。下面将针对这几个问题进行详细研究。
1.1.1 内存管理优化设计
嵌入式系统资源包括存储能力受限,也就无法将数据交换到硬盘来创建虚拟RAM,因此都是在内存非常有限的环境下运行和存储程序的。
本系统定制一个支持包括IP网络和多媒体功能的Windows CE操作系统,占用空间30MB以上,而系统运行时则需要占用更大的内存空间(MEMOS )。在Windows CE下RAM分为程序内存(MEMprogram )和对象存储库(MEMobject)两部分。因此运行应用程序时,应用程序实际可用内存仅为:
MEMavailable≤MEMprogram=MEMtotal-MEMos-MEMobject
另外,视频通信系统需要的内存空间包括以下几类:
1) 视频图像数据采集和显示模块需要的缓冲区;
2) 视频处理模块中,编解码需要的内存空间主要用于:当前帧图像缓冲、恢复图像缓冲、插值图像缓冲、差值缓冲、变换系数缓冲、量化系数缓冲、输出队列缓冲、用于变长编码(VLC)、变长解码(VLD)和计算使用的表,静态/动态数据,结构体等等;
3) 各个模块间接口用于视频数据传递的缓冲区等等。
因此,实现基于H.264算法的视频通信需要大量的内存空间。针对这种情况,必须优化并减少视频通信系统占用的内存,否则当空闲内存低到一个门限值时,Windows CE会自动终止程序,造成整个视频通信系统的瘫痪。
为了减少内存使用,本文采用下列多种算法:
1) 在解码端不分配插值图像缓冲,在运动矢量有x或y方向上的半像素分量时,采用实时插值方法。这样,当运动矢量x或y方向的分量是整数时,既可以节省内存,又可以省去不必要的插值运算。
2) 视频采集模块和H.264视频处理模块之间有适当大小的互斥共享内存,本文确定有3帧图像大小的互斥共享内存。为节省共享内存大小,我们将采集获得的RGB图像数据(R:G:B为8:8:8,24bits/pixel)直接转换为YUV4:2:0格式(平均12bits/pixel)后再存入共享内存,则共享内存的大小节省了二分之一。
3) 尽量减少算法中不必要的内存拷贝。例如,将解码恢复图像直接输出到显存用于显示。这样,节省内存的同时,还减少了内存拷贝操作,从而节省了运算时间。
4) 避免频繁地重新分配缓冲区。由于Windows CE操作系统下,在堆中只支持固定块大小的内存分配。因此频繁分配缓冲区极易引起内存碎片,累积起来会出现即使堆较空,但也需要大量虚拟页面的情况,这时操作系统会自动终止程序。
5) 避免分配过大的动态缓冲区。因为在Windows CE操作系统中,每个线程使用的堆栈大小是受限的,如果动态缓冲区占用过大,低内存下会产生堆栈分配失败,造成线程被自动挂起甚至产生异常,退出进程。
1.1.2 多线程调度优化设计
本文实现的基于H.264的视频通信系统主要包括四个线程:采集线程(Tsa)、编码线程(Tco)、解码线程(Tde)以及显示线程(Tdp)。如何合理安排视频通信中各个线程的优先级和同步机制,也是保证整个程序有效、快速运行的关键。
如果把Tsa线程优先级设为和其它三个线程一样(Normal级),则采集会被频繁中断,整个采集过程不能有效的进行,即使是QCIF(176144像素)格式,采集帧率也小于10帧/秒。同时,采集处理线程由于受多媒体定时器控制,内核属于中断服务线程,应该有较高的优先级。因此,本文将Tsa线程的优先级提到较高的Above-Normal级,保证系统的有效正常运行。但是必须合理安排高优先级的Tsa线程,如果它不释放时间片,其他线程将永远被阻塞,不能运行。因此,Tsa线程在受多媒体定时器控制的同时也要和Tco线程保持同步,这样才能保证视频编码和采集同步。同时,Tde线程和Tdp线程间也必须保持同步,才不致出现裂屏的现象。
1.2H.264编解码器的代码优化
嵌入式系统处理器支持SIMD指令集(MMX或SSE),可用于视频数据的并行处理和优化。本文对H.264编解码器采用多种方法进行优化:
1) SIMD指令集,在汇编级进行大量优化;
2) 解开循环,减少判断语句;
3) 函数调用变函数内联等。
视频编码的位移估值判决准则是最小绝对差值和(SAD),是较为耗时的运算;为了提高位移估值精度,还采用了半像素插值等,也是耗时的运算。下面以这两种运算为例讨论优化方法。
1.2.1 SAD运算优化
位移估值在搜索过程中采用的匹配函数是SAD:
式中MB是当前宏块,SA是参考区域,以MB左上角为(0,0)坐标,(Δx,Δy)是SA对MB的位移值式中MB是当前宏块,SA是参考区域,以MB左上角为(0,0)坐标,(Δx,Δy)是SA对MB的位移值,每次都针对字节型数据进行运算。由式(1)可以看出,SAD的计算包括求差值、求绝对值、求和三个步骤。优化算法首先适当解开循环,然后使用SIMD指令优化。本文利用MMX指令中的PSUBUSB(无符号紧缩字节带饱和减,它对8个连续的字节实现并行减法操作,并把每个字节的值箝位到0~255之间)来实现,则可用式(2)计算SAD:
式中:
1.2.2 半像素插值和箝位运算优化
半像素插值是对恢复图像像素值插值,它是帧差DCT系数的反变换值与其帧间预测值的和Sdiff。为防止越界,要对Sdiff进行箝位。由于只有一次箝位操作,因此可以将它与半像素插值合并到一个函数中去(函数内联)。这样,可以节省一个中间缓冲区和函数调用带来的开销。
另外,SIMD指令也是非常适合半像素插值优化,半像素插值中求平均计算:
avg(a,b)=(a+b+1)/2 (3)
本文利用MMX中的指令PADDUSW(无符号紧缩字带饱和加,对4个word型数据进行并行加法操作)、PSRLW(紧缩字的逻辑右移,对4个word型数据进行并行逻辑右移操作)来实现,将式(3)修改为:
avg(a,b)=PSRLW(PADDUSW(PADDUSW(a,b),packed1),1) (4)
式中a、b是紧缩型64位数据,即一次运算可获得连续4个16bits的像素值。packed1是4个值为1的16bits的数据紧缩而成的紧缩型64位数据0x0001000100010001。
2实验结果
实验环境为自主开发的VIA C3处理器(主频1GHz)硬件平台,配置有64MB 的SDRAM,操作系统为Windows CE 4.2,视频通信速率为256Kbps。下面实验中测出的时间均以此开发平台上的时间为准。由于特殊用途无线接入设备仅提供48kbps/96kbps的低网络带宽,要求将不同地点的现场视频信息通过无线通信手段实时传送到监控中心,支持采用H.264、MPEG-1/2/4等格式的数字视频流稳定可靠地进行传输,为了能够保证视频流的稳定持续传输,远距离传输,并且不受复杂地形限制。本文使用CIF(352288像素)和SIF(320240像素)格式的标准图像序列Susan,以及实时采集的图像序列(SIF或QSIF(160120像素)格式)进行测试。
H.264移植到嵌入式平台后,1.1节的内存管理方法使用与否,对视频编码性能产生严重影响:使用之前完全不能运行,使用之后才能工作。
再者,使用多线程调度方法调整线程优先级和线程间的同步,可以充分利用CPU和显著提高系统运行效率,保证无线视频通信系统有效运行。表1给出了使用多线程调度方法前后的性能比较。
在系统正常运行下,对视频编解码算法进一步优化,实验结果如表2所示。
可以看出,使用本文提出的优化算法后,在降低CPU占用率4%~10%的情况下,编码速度仍提高了19~25%,且恢复图像的主客观质量没有下降,满足无线实时视频通信的需要。
3结语
本文结合无线网络环境自身特点,通过对嵌入式系统和H.264编码算法的分析,探讨了H.264编解码器的软件设计优化,以满足无线实时视频通信的要求。研究成果已应用于军用视频通信产品中。
参考文献
[1]王丽丰,牛建伟,肖晨,等.基于H.264无线视频传输系统的研究[J].计算机应用与软件,2005,22(10):139.
[2]李建,别红霞.H.263无线视频传输的关键技术改进[J].计算机工程与应用,2006(03):152.
[3]Thomas Wiegand,Gary J Sullivan,et al.Overview of the H.264/AVC video coding standard[J].IEEE Trans.on circuits and systems for vid-eo technology,2003,7(13):560-576.
H.264编解码 第3篇
随着因特网和电子技术的迅猛发展,视讯业务对视频的传输速度和播放质量的要求也在不断提升,在已有视频编码标准中,新一代视频编码标准H.264/AVC因其具有优异的解压缩功能和良好的网络亲和性而受到欢迎。但H.264的优越性能是以算法复杂度为代价换取的,据统计,H.264解码复杂度相当于H.263的2.5倍,大约是MPEG-2的2~3倍。这种情况下,处理器的计算能力和解码速度成为了视频编解码应用的瓶颈。
目前已有的文献多致力于H.264解码算法的软件优化和研究。文献[1]给出了一种新型基于DSP的H.264解码器的软件优化,文献[2]基于影响H.264解码速度的因素,提出了基于Trimedia DSP平台的优化方案,文献[3]研究了H.264在DSP多核平台的上的并行性。而基于FPGA的H.264解码核整体实现方案的研究尚不多见。局限于C语言的串行执行特性,用DSP等纯软件方案实时完成H.264解码的运算比较困难,特别是对于高清视频很难达到理想解码效果,而拥有高速度及并行处理能力的FPGA能很好满足实时性需求。基于此,本文研究了基于FPGA的H.264解码核的实现问题,并给出了一个具体的实现方案。同时提供了相应的验证结果。实验数据显示本文提出的方法是正确的和有效的。
2 H.264解码算法
2.1 H.264解码原理
H.264/AVC并没有明确规定编解码器如何实现,仅规定了一个编码后视频比特流的句法及解码方法。H.264编码通常采用预测和变换的混合压缩法,该编码流程以宏块为单位进行帧内或帧间预测处理,然后把预测值PRED与当前块相减,产生残差数据块,之后进行块变换和块量化,最后将熵编码后的数据与解码所需头信息组成一个压缩码流。H.264解码是编码流程的逆过程,原理如图1所示。H.264解码流由残差数据和预测数据两条路径并行处理。残差数据路径主要由熵解码CAVLC和反量化反变换IQIT产生残差数据;预测数据路径由基于参考像素的帧内预测(帧间预测本文暂未考虑)产生预测宏块。两条路径结果输出相加构成重建图像,并以该图像作为下一帧解码图像的参考像素进行帧内预测。
2.2 H.264反量化和逆DCT算法原理
为避免传统浮点型离散余弦变换因解码端的运算精度不足经常引起的失配问题[4],H.264采用整数变换技术,该变换把解码和量化过程中的乘法合二为一,既减少了解码的运算量,又提高了图像解压缩的实时性。
根据整数变换与反量化过程,H.264在解码中将逆DCT运算中的部分系数放到反量化中一起处理。与正变换对应的44块像素的逆DCT变换公式为:
undefined
式中:Ci为逆变换矩阵;Ei为变换尺度调整矩阵;a=1/2,undefined;Z为逆量化后的结果,将“Z⨂Ei”结合到逆量化的过程中去,根据当前块类型的不同,H.264的反量化公式可分为3种情况:
1) 若当前块是帧内1616预测模式的亮度块时,交流系数由反量化公式(4)计算,直流系数反量化公式为
undefined
式中:i,j=0,1,2,3
2) 若当前块是色度块时,交流系数由反量化公式(4)计算,直流系数反量化公式为
undefined
式中:i,j=0,1,2,3
3)若当前块是非帧内1616预测模式的亮度块时,不需要考虑直流系数时的反量化由公式为
Wr(i,j)=(ZijVij)<<(QP/6),i,j=0,1,2,3 (4)
式中:QPy和QPc分别为亮度块和色度块的量化参数;WD(i,j)为直流系数的逆Hadamard变换结果;Vij是融合在反量化过程中的逆DCT的比例变换系数;Zij为j交流残差系数矩阵。相对应于直流系数的逆Hadamard变换公式为见式(5),其中ZD为直流残差系数矩阵
undefined
3 H.264解码核实现方案
为了提高系统性能和处理速度,本方案在解码实现结构上用流水线和模块并行处理。考虑到CAVLC指令周期占解码时间较长[5],将算法从图2中的虚线处分开用并行处理完成,每当虚线右部分的CAVLC完一个宏块解码后,便启动虚线左部IQIT的运算,同时启动CAVLC对下一宏块的熵解码运算。各模块间采用流水线处理,使用握手信号end_xxx来表征一个运算结束,使用启动信号trigger_xxx开始一个运算,因此本方案有增加模块间处理灵活性的优点。
3.1 句法解析模块
编码比特流由一个个句法元素为单位依次衔接组成,比特流句法表详细的介绍了H.264的句法,指明了在码流中依次出现的句法元素及它们出现的条件、表示的物理意义、提取描述子等。
句法解析模块分析和解码每一个句法元素,为后续模块提供参数信息,如为IQIT解码模块提供当前宏块类型mb_type和量化参数偏移值mb_qp_delta等。句法解析模块根据码流的分层结构,引入有限状态机FSM的处理方法,采用层次分解结合sub FSM的形式来对比特流句法进行解析。由图3可见句法解析模块分6个层级,且包括13个sub-FSM。对于每一个sub-FSM都是单一的输入控制,避免了sub-FSM之间的相互转化,减少结构复杂度。并且可以在每个sub-FSM内部根据需要自如地改变状态,而无需考虑句法解析模块的整体结构,因此增加了实现结构的灵活性和可扩张性。
3.2 CAVLC熵解码的实现
根据CAVLC解码原理[6],本文给出一种新型CAVLC解码实现方案,其结构如图4所示,主要包括NC查表模块、Trailing_sign模块、非零系数幅值Levels模块、TotalZeros模块、Run_Before模块,Data_reorder模块。由图4可见,如果当前宏块类型为P_skip,则整个宏块不包括任何残差信息,若当前44块的CodedBlockPatter为0,则对应子块的所有的残差不被传送,再者若进行NC值查表后,得到非零系数数目值TotalCoeffs为0,则没有必要再进一步进行CAVLC解码,以上3种情况可以直接将残差数据设置为0,其他情况则依次进行Trailing_sign,Levels,TotalZeros,Run_Before解码。
CAVLC的组成模块都是基于变长表格来进行查表的[7],以NC查表获取非零系数数目TotalCoeffs和拖尾系数数目TrailingOnes为例,共有4个变长表格和1个定长表格可供选择。对于变长码流的查表,已提出的有分组码表法、二叉树法、全码查表法等,基于查表效率和硬件资源消耗的综合考虑,本文采用改进的分组二叉树法来解析ToalCoeffs和TrailingOnes。
仔细观察4个变长表格和1个定长表格可发现大部分码流都是由若干个前缀零和由1引导的后缀组成,类似于哥伦布码流结构。表1给出了NC取值的码表规律性,在知道码流前缀零的个数count后,使能相应的分组信号temp++,然后使用状态机state++状态转换实现二叉树遍历,解析出非零系数个数和拖尾系数个数。对于后面非零系数幅值Levels、最后一个非零系数前零的数目TotalZeros、每个非零系数前零的个数Run_Before[i]的解析都采用该改进的分组二叉树法。
3.3 IQIT解码块的实现
根据残差数据被编码的类型,IQIT解码可分为2个数据路径:对路径1,如果残差数据为Intra16x16_Luma块或者Chroma块,则直流系数需在反量化前做逆Hadamard变换,量化后结果放到相应块的(0,0)位置上与15个交流系数组成1个44块,之后再做逆DCT变换;对于路径2,如果残差数据非Intra16x16_Luma块和Chroma块,则需对所有系数反量化,然后再进行逆DCT变换。
反量化算法主要基于乘法运算和移位操作完成,实现结构见图5。具体实现过程为:首先由MUX选择当前块量化参数QP(0≤QP≤51);再由Mod6 LUT模块对QP取余,其结果与iq_address、res_dc和res_ac信号共同用于选择比例变换系数Vij(0≤i,j≤3);然后Vij和残差系数Wij经乘法器lpm_mult算出Yij;此外,还把QP送入模块Div6 LUT取商,经shift_len模块算出移位长度len;最后把Yij和len送入移位模块Shift LUT算出量化结果IQ_output。其中Mod6 LUT和Div6 LUT采用查表方式完成运算。该模块每次处理一列数据加快了处理速度,为后续的逆DCT解码提供了便利。
由2.2节逆DCT算法原理知,逆Hadamard算法和逆DCT算法在结构上相似,它们的每一维运算中都包括4个输入和8次数学运算,不同点仅在系数上相差1/2,因此可通过引入1个系数选择器来共用相同硬件结构;对于22的色度块,可将二维逆DCT变换合成为一维的44块逆DCT变换来共用同一硬件结构。故本文对逆DCT变换用信号IS_Hadamard来确定运算结构,如果IS_Hadamard=1,则选择逆Hadamard算法;否则若IS_Hadamard=0,则选择逆DCT算法;其次通过设置1D_counter和2D_counter信号值来选择相应的块,若1D_counter=4且2D_counter=4,则选择亮度44块;若1D_counter=1且2D_counter=0,则选择22的色度块。在上述运算过程中,我们还引入了双向加法器lpm_add_sub,从而获得了降低算法复杂度的效果。
3.4 帧内预测解码块的实现
帧内预测利用宏块之间的相关性,根据邻近子块的存在性和在当前图像中的位置,获取参考像素值A~M,然后由预测公式[8]来计算像素样点值。其中1616亮度块和88色度块的预测方式由句法解析模块的解码比特流Intra16x16_predmode和Intra_chroma_predmode直接给出,44亮度块的预测方式由其相邻上方块及左方块的预测方式ModeA和ModeB共同计算得出[10]。
预测方式共有17种,其中44亮度块有9种[9],1616亮度块和88色度块各有4种,若针对每一种预测方式都设计一种实现结构,势必会增加硬件资源消耗和系统复杂度。由于17种预测方式的运算结构基本一样,都是先求和再进行移位运算,唯一不同之处是,1616亮度块和88色度块的Plane预测方式,需在预测之前,先算出H,V,a,b,c这5个变量[10],最后的像素值再根据下式计算
predL[x,y]=max(0,min(255,
{[a+b(x-7)+c(y-7)+16]≥16} (6)
图6为帧内预测解码结构图,加法运算由Parallel_add硬件加法器来完成,Is_clip模块用于完成Plane预测方式。每个周期处理1列像素点,4个周期可完成1个44像素点的预测,这有助于加快硬件处理速度。
4 H.264解码核功能验证
为验证本文提出算法的正确性,在QuartusⅡ7.2版的环境中,对用VHDL设计的各个功能模块及整个H.264解码核执行了功能仿真,使用的FPGA为Stratix Ⅱ系列的EP2S60F672C5ES。因文章篇幅有限,下面仅给出CAVLC熵解码器和反量化器的仿真曲线图及H.264解码核编译报告。
图7为1个44块CAVLC解码仿真图,输入为00001000 11100101 11101101的1帧图像数据中5个句法元素的编码比特流,解析得到的参数为ToalCoeffs为5,TrailingOnes为3,Levels为1和3,Total_zeros为3,Run_before[i]为1,0,0,1,0,解码数据排序为0,3,0,1,-1,-1,0,1,0,0,0,0,0,0,0,0。
图8为反量化器波形仿真图,其中trigger_quant为反量化模块使能信号,高电平有效,res_ac和res_dc为交直流复位信号,高电平有效,qp为量化参数,qp_ref为qp取商结果,qp_rem为qp取余结构,data0~data3是前面CAVLC解码器输出的44残差数矩阵,m0~m3为相对应的比例变换系数Vij,dataout0~dataout3为反量化器的量化输出。
H.264解码核编译报告由表2所示。本文提出的H.264硬件解码核采用改进的分组二叉树法进行变长码表的查找,最大程度简化了反量化、逆DCT和帧内预测解码实现结构,因模块之间采取了流水线和并行处理方式,在硬件资源消耗和处理速度上与传统未改进的硬件实现方法相比都有很大的改进,结果也表明了该H.264解码核设计的正确性和实用性。
5 结束语
针对H.264解码复杂度高的问题,从提高解码速度和节省硬件资源两方面来权衡考虑,给出了基于FPGA的H.264解码核,并详细介绍了其设计和实现方法,最后给出了基于FPGA的功能验证和与传统法的性能对比。实验结果表明了设计的正确性,同时也显示其在性能和解码效率上与传统法相比有较大幅度的提高。
参考文献
[1]任李悦,唐宁,滕舟.基于H.264解码器的软件优化[J].电子设计工程,2009,17(12):104-108.
[2]林冰,冯艳,李学明.基于Trimedia DSP的H.264解码算法优化[J].计算机工程与应用,2005,31:41-45.
[3]奚杰,陈杰,刘建,等.H.264在多核平台上的并行性分析[J].哈尔滨工程大学学报,2010,31(6):736-742.
[4]曹伟,洪琪,侯慧,等.一种用于H.264编解码的新型高效可重构多变换VLSI结构[J].电子学报,2009,37(4):675-674.
[5]郭倩,陈耀武.基于功能模块的H.264并行解码算法[J].计算机工程,2010,36(23):231-233.
[6]CHEN Guanghua,HU Dengji,ZHANG Jinyi.Efficient VLSI architectureof CAVLC decoder with power optimized[J].上海大学学报:英文版,2009,13(6):462-465.
[7]GUO Hui,FU Yongqing.An improved CAVLC entropy encoder ofH.264/AVC and FPGA implementation[J].Key Engineering Materials,2011,5:241-246.
[8]毕厚杰,王健.新一代视频压缩编码标准——H.264/AVC[M].2版.北京:人民邮电出版社,2009.
[9]冯杰,陈耀武.基于H.264I帧编码的块边缘模式特征提取算法[J].华南理工大学学报:自然科学版,2010,38(2):126-129.
H.264软件解码器的结构与优化 第4篇
关键词:H.264,熵编码解码,反离散余弦,帧内预测,环路滤波
H.264是由联合视频专家组(JVT)制定的新一代视频编码标准。由于H.264使用了帧内预测、整数变换、多种块大小的运动估计补偿、多帧参考、1/4像素精度预测、环路滤波等新技术,使得它在编码效率、抗干扰能力以及信道利用率方面都优于现存的编码标准,具有高压缩比的同时还拥有高质量流畅的图像。但是H.264性能的改进是以增加复杂性为代价而获得的,H.264解码复杂度是H.263的2~3倍,而实际应用中对解码器的实时性要求相当高,标准组织的参考模型远不能满足实时的要求,所以要实现H.264格式视频序列的实时解码,必须对解码器作很大的优化。
1. H264软件解码器结构与性能分析
1.1 H.264解码流程
如图1所示H.264解码流程如下:NAL数据(媒体文件原始数据)经过熵编码得到量化后的一组变换系数,再经反量化、反变换得到残差数据。利用解码出的头信息进行帧内预测或者进行运动补偿、帧间预测,得到预测数据。预测数据加上残差数据经过滤波后得到解码输出图像。
1.2 解码器各模块的说明与耗时分析
H.264解码器各模块耗时百分比情况如下:熵编码解码占9.7%,反量化与反离散余弦变换占12.6%,帧内预测占18.8%,运动补偿占32.4%,环路滤波占16.2%,其它处理占10.3%。以下我们对各个模块处理流程及耗时进行分析。
1.2.1 熵编码解码
H.264通常采用基于上下文的自适应二进制算术熵编码(CABAC)。算术编码是使用区间递进的方法来为输入流寻找码字的,它从第一个符号确定的初始区间(0,1)开始,逐个字符地读入输入流,在每一个新的字符出现后根据各字符的概率递归地划分当前区间,处理完最后一个字符后得到最终区间,在最终区间中任意挑选一个数作为输出。解码则是根据给出的一个输出数据反复地查找区间,得到字符,更新区间,最终得到完整的输入流。
为了加快编解码速度,避免乘法、浮点运算,H.264提供上下文模型区间表、量化的概率更新表和乘法查找表优化编解码速度,所以熵编码的过程就是不断查找各个表的过程,执行时间主要消耗在查表操作上。
1.2.2 反量化与反离散余弦变换
为了进一步节省图像传输码率,去除图像信号中的相关性及减小图像编码的动态范围,H.264对预测残差数据采用了44整数离散余弦变换技术(DCT),并对变换后的数据进行量化,减少码流。
二维NN图像块的DCT可以表示为:
Xij是图像块中第i行第j列的数据,Ymn是变换结果。可以用矩阵表示:
其中,AT为A的转置矩阵,变换矩阵A中的系数:
H.264对44图像块进行操作,则相应的44DCT变换矩阵A为:
设,则:
由于a、b和c是实数,直接运算会降低效率,解码时由于精度问题会导致数据漂移。为此,可以对矩阵A进行改造,采用整数DCT技术,可有效地减少计算量,同时不损失图像的准确度。设d=c/b(≈0.414),取d=0.5,变换过程可以表示为:
运算茚表示左边矩阵的每个元素乘以右边矩阵对应位置上的值。⊗右边的矩阵被归纳到量化过程中。简化DCT过程为:
设Zij是对Yij量化后结果,Qstep为量化步长,round=为取整函数,则有:
Qstep作为量化参数进行查表可以得到Eij/Qstep的值。
反量化与反离散余弦变换则是离散余弦变换(IDCT)的逆过程,反量化只需根据Qstep查表,IDCT公式为:
其中IZ为反量化运算后的矩阵,所以IDCT变换执行时间主要消耗在矩阵乘法上。
1.2.3 帧内预测
由于视频图像具有空间相关性,即当前宏块数据与相邻的像素数据变化不大,可以由左边宏块和上边宏块预测出当前宏块的像素值。预测出的值肯定与真实值存在差异,差异以残差数据进行保存。由于图像的空间相关性,经过准确的预测后,与真实值之间的差异(残差数据)会在很小的范围内,对变化很小的一组数据进行熵编码可以节省码流。
44亮度帧内预测有9种模式,88和1616预测有4种模式。帧内预测计算本身不复杂,主要操作是将左边或上边的像素值经过简单运算后保存到当前宏块的相应位置上,之所以耗时是因为要进行频繁的内存数据存取操作,而且被调用的次数相当多。
1.2.4 帧间预测
帧间预测是利用已解码视频帧进行运动补偿的预测模式。为减少传输比特数,可利用邻近分割块较强的相关性,运动矢量(MV)由邻近分割块的MV进行预测后加上运动矢量差异(MVD)得到,MV由x方向和y方向的运动偏移组成。亮度运动偏移单位为1/4像素,色度运动偏移单位为1/8像素。
像素插值图2所示。其中灰色矩形为参考图像的整像素点,白色矩形为1/2与1/4像素插值点。
帧间预测时,首先生成参考图像半像素位置的像素值。半像素点(如b、h、m)通过对相应整像素点进行6抽头滤波得出,权重为(1/32,-5/32,5/8,5/8,-5/32,1/32),如1/2像素点b计算如下:
类似地,h由A、C、G、M、R、T滤波得出,而j则必须等cc、dd、h、m、ee、ff计算完毕后才能开始计算。
半像素点计算出来以后,1/4像素点就可通过线性内插得出,如a=round((G+b)/2)。1/4像素点不参与插值,如p=round((h+s)/2),不能由n和q插值得到。
相应地,色度像素需要1/8精度的MV,通过整像素点二次线性插值得出,如图3所示。
通过上面的分析,可以看到,帧间预测的主要执行时间消耗在像素插值上。
1.2.5 环路滤波
由于H.264编码对每个宏块采用了DCT变换和量化,因此解码后的宏块与原始数据存在一定的误差,另一方面由于运动补偿块的匹配不可能是绝对准确的,所以相邻宏块之间会产生数据不连续的现象,在图像上则表示为方块效应。
环路滤波器可以消除宏块之间的方块效应,但复杂度非常高。主要原因是它具有高度的自适应性,它需要对方块边界及样点量化值进行条件判断和处理,这样,在算法的主要内部循环中不可避免地出现条件分支,这个过程是很耗时的,而且无法优化。另一个高度复杂的原因是H.264的编码算法中残差编码的尺寸,对于44的方块大小及平均在每个方向上对2个点滤波,这样几乎图像中每个点都要被调入到内存中,要么被修正,要么用来判断边界点是否要被修正。
滤波器首先要区分方块是图像的真实边界还是由DCT变换系数量化而造成的假边界,这个过程主要是根据参数查表,通过简单的计算来判断。然后按照规定的顺序计算边界上的点的修正值,再查表对修正值限幅,最后根据修正值对像素点进行修正。
环路滤波计算过程不复杂,主要执行时间消耗在条件判断和分支,以及过多的调用次数上。
2 H.264的解码优化
根据对H.264各个模块处理情况及耗时分析,以下提出各模块的优化方法。
2.1 熵编码解码优化
熵编码解码的执行时间主要消耗在查表操作上,可以采取的优化措施是提高cache命中率。由于H.264采用的是基于上下文的自适应二进制算术编码,相邻参数的上下文区间具有连贯性,在表格中的位置也是相邻的,因此在解码时可以连续解出多个相邻上下文区间的参数后,再对解出的参数进行处理。如果解码一个参数就进行处理会导致cache中的表格数据得不到利用,下次又要从内存中读取,降低查表速度。
2.2 反离散余弦变换优化
IDCT的主要操作为:
如果按照普通矩阵乘法来进行计算,会耗费大量的时间。考虑到前后两个矩阵互为转置矩阵,可以将两个矩阵的运算改为两次同一矩阵的运算,即先对IZ的每行进行一维IDCT运算,然后对经行变换的块的每列再应用一维IDCT运算,即:
而每次一维IDCT运算可以采用蝶形快速算法,以节省计算时间,如图4所示。
其中。
这样经过两次蝶形快速算法,就可以得到反离散余弦变换后的数据。
2.3 帧内预测优化
帧内预测主要时间消耗在频繁的内存数据存取操作上,可以通过减少内存数据的读取次数来进行优化。
对于44的预测块,以垂直预测为例,像素预测值由上方44块的底边决定,即:
对该块进行预测需要读取四次内存,即p[0,-1]、p[2,-1]和p[3,-1]。每个值的大小都为8位,设CPU是32位,因此CPU可以一次读取四个值,保存到unsigned long类型的变量中,再通过移位和&操作就能得到每个字节的值。
该方法可以大大节省访存时间,从而达到优化的目的。
2.4 帧间预测优化
帧间预测主要时间消耗在像素插值上,如b=round((E-5F+20G+20H-5I+J)/32),系数相同的项进行合并可得:b=((E+J)-(F+I*5+(G+H)*20)>>5。由于乘法操作比较费时,可以考虑采用查找表法代替乘法。
整像素点的值在0~255之间,因此可以建立两张表,每张表有511个元素,一张用于成系数20,另一张用于乘系数5。插值时只需将两个整像素点的和作为数组的索引,找到表格中的值,就能避免乘法运算。
b=((E+J)-table_mul5[F+I]+table_mul20[G+H])>>5。
通过查找表进行插值,虽然消除了乘法运算,但增加了内存读取操作。不过图像中的像素具有空间相关性,查表操作能有效利用cache。由于帧间预测占用了整个解码调用过程的3/5左右,最理想的做法是将这两个表锁入CPU的RAM,这样可以显著提高计算速度。
2.5 环路滤波优化
环路滤波主要执行时间消耗在条件判断和分支,以及调用次数较多上,计算过程几乎没有优化的空间。考虑到环路滤波只是消除宏块间的方块效应,而方块效应最主要是由于量化和DCT变换产生的误差而导致。量化步长越大,码率越小,但误差越大,量化步长越小,码率越大,误差越小。
在环路滤波中要检查量化参数,如果小于16是不需要滤波的。但以16为是否进行滤波的界限在N2070中不是很合适,因为量化参数为24以下的320240视频,即使不进行滤波,解码计算也非常吃力。经过多次测试,设定量化参数在26以上才进行滤波,可以在解码速度与画面清晰度之间取得平衡,不管量化参数为多少,画面都不会出现明显的方块,而且可以保证画面的流畅度。
3 结束语
本文从实际应用角度,指出H.264编解码的计算复杂度过大,不适用实时性高的应用要求,必须对其进行优化。通过对H.264解码器各个模块处理流程以及耗时分析,提出优化方法。实践证明,经过以上各模块的优化处理,H.264解码器的实时性能提升了13.2%。
参考文献
[1]喻鑫.基于H.264视频编码的快速算法研究及实现[D].四川大学,2004.
[2]刘冠群.3G环境下手机智能视频监控的设计与实现[D].电子科技大学,2010.
[3]何俊,田应洪,洪志良.基于H.264的熵编码结构[J].计算机工程,2008,(06).
[4]朱琪,朱灿.基于H.264整数变换和量化的研究与软件优化[J].武汉理工大学学报:信息与管理工程版,2006(01).
[5]魏利风.AVC/H.264整数离散余弦变换及反变换的结构设计[J].现代电子技术,2008(04).
[6]杨意仲,张申科,秦肖,等.H.264及AVS视频解码器中IQ/IDCT的设计与实现[J].电子技术应用,2007(03).
[7]张晓燕,谢珺堂.H.264的整数DCT变换编码与量化过程[J].军民两用技术与产品,2005,(05).
[8]张江鑫,冯明.H.264快速帧内预测模式选择算法[J].中国图象图形学报,2008(10).
[9]沈方,支琤.H.264标准的帧间模式选择快速算法[J].微计算机信息,2006(16).
H.264编解码 第5篇
关键词:H.264,帧内预测,预测模式,存储开销
1 帧内预测
一直以来, 视频信息以其直观性、高效性等优点而受到人们的青睐。但是视频信息包含的信息量太大, 若要广泛应用, 必须解决压缩与编码的问题。为此, 国际标准化组织和视频图像专家组等组织制定了一系列的视频编解码和压缩的标准, 其中由ITU-T (国际电信联盟组织) 和ISO (国际标准化组织) 联合推出的H.264视频编解码压缩标准具有突出的压缩效率[1], 得到了广泛的认可和应用。
H.264采用了帧内预测、1/4像素插值、多参考帧预测、环路滤波等多种新技术, 获得了优越的压缩性能[2]。但是, 这些新技术在提高编码压缩效率的同时, 提高了计算复杂度, 对硬件平台提出了更高的要求。因此, 针对H.264标准在硬件资源相对紧张的嵌入式设备上的应用, 业界提出了多种有效的优化方法。如基于VLSI硬件设计加速H.264解码计算过程[3];用特定平台提供的SIMD指令进行数据的向量处理[4];或者针对H.264解码流程中一个或多个模块进行结构或者算法上的优化, 提高执行效率[5,6,7]。
以上几种方法中, 硬件加速的方法性能比较高, 但是开发周期长, 成本高, 且不灵活, 不利于升级;用SIMD指令虽然可以加速计算过程, 但是和平台相关性很大, 可移植性比较差。相对于前两种优化方法, 后一种方案比较灵活, 没有平台的限制, 是一种通用的优化方法。
本文提出的优化方法属于最后一种, 是对帧内预测模块提出的一种通用的优化方法。通过对H.264解码过程中帧内预测原理进行深入的分析, 针对此模块中处理器与片外存储空间 (SDRAM) 数据交互频繁、44亮度块的预测模式计算复杂度较高的特点, 对帧内预测模块采取了两方面的优化措施。其一是通过结合环路滤波的结构, 去除了目前常用结构中片上存储空间 (SRAM) 的冗余存储, 节省了解码所需的片上存储空间;第二个优化措施是通过预先在片上空间 (SRAM) 存储相邻44亮度块的帧内预测模式, 简化44亮度块帧内预测模式的获取过程。通过以上两种优化措施, 节省了解码过程片上存储空间需求、简化了44亮度块帧内预测模式的获取过程, 并且减少了处理器与片外存储空间 (SDRAM) 的数据交互次数, 大大提高了解码器的执行效率和解码性能。
2 帧内预测模块优化方案
帧内预测是H.264采用的一项新技术, 利用一帧图像的空间相关性, 由邻近块的信息来预测当前块的信息, 进一步提高了压缩效率。这种预测来自以下两个方面:像素的预测和44亮度块预测模式的预测。本文的两个优化措施分别针对这两个方面。
2.1 片上冗余存储的优化
片上空间冗余存储的优化是针对像素的预测过程进行的优化。H.264帧内预测模式下, 当前块的像素预测值是由邻近块的像素根据不同的预测模式预测得到。
H.264支持9种44块、4种1616块的亮度预测模式和4种88块的色度预测模式[7], 如图1所示。其中88色度块的预测模式和1616的亮度块预测模式类似, 因此图1并未重复给出。
从图1中可以看出, 当前块的像素预测可能会用到左方宏块最右一列、上方宏块最下边一行的像素值作为参考像素, 且参考像素值必须为环路滤波前的像素值。目前普遍采用的处理方法是:重建宏块滤波前, 最右一列和最下面一行的数据被分别保存于两个片上buffer中, 如图2所示。后续邻近宏块为帧内预测类型时, 直接读取两个片上buffer中的参考像素值进行帧内预测。
这种结构虽然可以在一定程度上减少处理器到片外空间读取参考像素的次数, 但事实上这两个buffer中的数据是片上的冗余信息。本文结合环路滤波的结构, 取消了这两个片上buffer, 直接在环路滤波的缓存buffer中读取数据, 去除了这部分冗余数据的存储。这里有必要先简单介绍一下环路滤波的结构。
常用的以宏块为单位的环路滤波结构中[8], 也存在两个类似的片上buffer来暂存相邻块的数据, 不同的是这两个buffer存储的数据是环路滤波后的像素值。如图3所示, 当一个宏块滤波结束后, 把最右边四列和最下边四行像素值分别存储到片上LINE_BUF和LEFT_BUF两个buffer中, 以便右边宏块和下方宏块滤波使用。
从图3可以看出, 这两个buffer同样包含了一个宏块最右边一列和最下面一行的像素值。通常认为这两个buffer中的像素值为滤波后的像素, 因此不能被帧内预测模块利用。事实上, 深入分析环路滤波过程可知, 这两个buffer中帧内预测所用到的部分像素值在滤波前后并不会改变。图4a中实线是一个宏块中需要滤波的边界, 图4b给出了在最强滤波强度下, 一条边界两边可能改变的像素值 (图中深色的像素) 。从图4可以看出, 一个宏块中最右一列和最下边一行的像素值在滤波前后是不改变的。因此完全可以将帧内预测模块中的两个buffer去掉, 当需要左方和上方块的像素值作参考像素时, 直接到环路滤波这两个buffer中读取相应的数据即可。这一优化措施不但去掉了片上的冗余存储, 释放的空间可以将片外更有意义、使用频繁的数据存储到片上空间, 而且减少了帧内预测模块中未滤波像素保存这一步骤, 进一步提高解码性能。
2.2 预测模式获取过程的优化
帧内预测的另一个重要步骤是每个44亮度块本身预测模式的获取。为了提高压缩效率, 宏块头信息只给出1616亮度块和色度块的预测模式, 44亮度块的预测模式需要解码器根据邻近块的相关性计算得出。如图5所示, 当前块E与左方块A和上方块B的预测模式有很大的相关性。
44块预测模式的预测过程如图6所示, 当前块E的预测模式由最可能预测模式和参数prev_intra44_pred_mode (以下简称参数1) 及参数rem_intra44_pred_mode (以下简称参数2) 来共同决定。最可能的预测模式为左方块A和上方块B的预测模式的最小值。若块A或块B为非帧内44预测模式, 则相应的预测模式置为2 (DC预测模式) 。如图6所示, 根据参数1和参数2的值对最可能模式进行修正, 就得到当前块E的预测模式。
由以上分析可知, 每个44亮度块预测模式的获取, 处理器需要频繁地在片外存储空间读取邻近块的信息并进行判断等步骤。当图像带有大量的细节, 随着44块数目的增多, 这部分的开销会陡增, 降低解码性能。可见对这一部分的优化是十分必要的。
本文采取了在预测当前块模式之前就预先判断并存储相邻块的信息的优化措施。首先新增两个片上buffer:top_model_buf和left_model_buf。top_model_buf用来存储当前块上方整个44块行中每个44块的预测模式, left_model_buf用来存储左方44块的预测模式。
如图7所示, 当前块E的上一行子块在解码过程中, 同时把此子块预测模式的值存入top_model_buf中, 若此块不是帧内44模式, 则在top_model_buf的对应位置存入2 (DC预测模式) 。left_model_buf存储最近解码子块的预测模式, 同样, 若这个子块为非44帧内预测模式, 则在buffer存储2。如此一来, top_model_buf类似一个循环存储结构, 解码一个宏块行才全部更新一次, 保存着当前解码行上一44子块行全部的预测模式。当前块E只需要到buffer的对应位置上读取相邻块的信息求最小值即可得到最可能预测模式。
下面来分析新增的两个buffer所需要的空间开销。因为每个44子块有9种预测模式, 因此只需要4 bit便可以存储一个子块的预测模式。1个宏块中只需要存储最下面的4个44子块, 因此1个宏块需要的比特数为44=16 bit。如果存储1个宏块最下边一行的像素, 则需要168=128 bit。因此, 相对于未优化前存储最下边一行像素的top_buf, 这个buffer的大小仅为原来的1/8。可见本文的优化方法尽管将更多的信息存储到了片上存储空间, 不但没有增加片上存储需求, 反而释放了一定大小的片上存储空间, 这对硬件资源相对宝贵的嵌入式系统来说是十分有意义的。
优化后的44块预测模式的获取流程如图8所示, 相比于优化前的流程图6, 复杂度大大降低。
3 实验结果
本文将优化前后的解码程序分别在IME-Diamond仿真平台上做了验证, 对比结果如表1所示。IME-Diamond仿真平台是32位定点处理器IME-Diamond的仿真软件, 片上存储空间为128 kbyte, 该软件可以精确统计每个模块消耗的周期数。测试所用的码流是由JM编码器产生的标准码流, 用了4组300帧CIF格式的测试码流。表1分别给出优化前后帧内预测模块消耗的周期数, 并给出了对比结果。
从表1可以看出, 采取本文提出的优化措施对程序进行优化后, 帧内预测模块消耗的平均周期数大大减少, 相对于优化前平均提高了13%左右。
4 结论
本文对H.264帧内预测模块做了两方面的优化, 一是结合环路滤波的结构, 却除了片上冗余信息的存储, 在降低片上空间需求的同时简化了参考像素的存储流程;二是对44亮度块的预测模式获取过程的优化, 在解码相邻信息块的同时对这些块的预测模式进行判断和存储, 降低预测模式的获取的复杂度。通过这两种优化方法, 在降低片上存储空间的前提下简化了帧内预测模式的处理流程, 减少了处理器和片外数据的交互次数, 提高了解码性能, 尤其对于包含大量细节的图像, 优化效果更加明显。
参考文献
[1]Joint Video Team.ITU-T Rec.H.264 and ISO/IEC 14496-10 AVC, Draft ITU-T recommendation and final draft international standard of joint video specification[S].2003.
[2]WIEGAND T, SULLIVAN G, BGONTEDAARD G, et al.Overview of the H.264/AVC video coding standard[J].IEEE Trans.Circuits and Systems for Video Technology, 2007, 13 (7) :560-576.
[3]ZHANG N, LI M, WU W.High performance and efficient bandwidth motion compensation vlsi design for H.264/AVC decoder[C]//Proc.ICSICT 2006.[S.l.]:IEEE Press, 2006:1896–1898.
[4]陈梅芳.基于TMS320DM642的H.264解码器优化[J].现代电子技术, 2006 (3) :112-115.
[5]袁晓雷, 魏江, 张鹏.嵌入式平台H.264软件解码器的优化[J].电视技术, 2010, 34 (5) :36-39.
[6]任李悦, 唐宁, 滕舟.基于H.264解码器的软件优化[J].电子设计工程, 2009, 17 (12) :104-108.
[7]姜峰.基于DSP的H.264解码器运动补偿模块的优化[J].微电子学与计算机, 2012, 29 (10) :86-88.
[8]毕厚杰.新一代视频压缩编码标准—H.264/AVC[M].北京:人民邮电出版社, 2005:83-89.
H.264编解码 第6篇
H.264是继MPEG4之后的新一代数字视频压缩格式,它既保留了以往压缩技术的优点和精华,又具有其他压缩技术无法比拟的优点。H.264最具价值的部分是更高的数据压缩比。在同等的图像质量条件下,H.264的数据压缩比能比当前DVD系统中使用的MPEG-2高2~3倍,比MPEG-4高1.5~2倍。正因为如此,经过H.264压缩的视频数据,在网络传输过程中所需要的带宽更少,也更加经济。所以本系统选择采用H.264格式视频。
Direct X软件开发包是微软公司提供的一套在Win dows操作平台上开发高性能图形、声音、输入、输出和网络游戏的编程接口。可以用来开发游戏以及作为其他各类多媒体应用程序的底层API函数集。它是一种基于COM的系统,既不属于驱动程序层,也不属于应用程序层。作为Direct X的一个COM组成元素,Directshow应用程序编程接口是一个Windows平台上的流媒体架构,提供各种格式的高品质多媒体流的捕获、处理、传送和回放。Directshow集成了Direct X其他组件中的先进技术,能做到自动检测、使用视频和音频硬件加速设备。它不仅支持基于WDM驱动程序的硬件设备,也向上兼容Video for Windows驱动程序的硬件设备。Directshow采用多线程多任务的方式,还支持宽松的格式变化。Directshow为播放视频监控中涉及到的各种类型的音频、视频数据提供了非常有效的途径。因此本系统采用Directshow来实现视频监控系统中H.264视频的解码。
1 Directshow体系结构
Directshow基于模块化结构,每个功能模块都采取COM组件方式,称为Filter。Filter负责执行一些多媒体流的处理过程,采用Filter Graph模型来管理整个数据流的处理过程。Directshow的体系结构图如图1所示。它通过提供各种功能的Filter完成总体应用框架的工作,从而使多媒体应用程序设计变得简单。每个Filter都分别具有一个不同的应用功能,Filter之间通过Pin相互连接。每个过滤器都拥有属于自己的针脚。针脚分为输入针脚和输出针脚,输入针脚把过滤器外部的数据接收到过滤器中进行处理,输出针脚把过滤器中处理后的数据传送到下一个过滤器。经过输入输出针脚的传递,数据从一个过滤器传送到了下一个过滤器中。当两个pin连接的时候,必须有一个pin提供一个allocator。Directshow定义了一系列函数调用来确定由哪个pin提供allocator,以及buffer的数量和大小。在数据流开始之前,allocator会创建一个内存池pool of buffer,在开始发送数据流以后,源Filter就会将数据填充到内存池中一个空闲的buffer中,然后传递给下一个的Filter。
1.1 Filter的原理
Directshow技术的最核心就是作为过滤器的可插入标准组件,它是具有特殊功能的COM对象。过滤器又可分为:源过滤器(Source Filter)、变换过滤器(Trans-form Filter)、提交过滤器(Renderer Filter)等。源过滤器引入数据到过滤器图表中,数据来源可以是文件、网络、照相机等。不同的源过滤器处理不同类型的数据源,然后将数据往下传输;变换过滤器的工作是获取输入流,处理数据,并生成输出流,其对数据的处理包括编解码、格式转换、压缩解压缩等;提交过滤器主要负责数据的最终去向,接收数据并把数据提交给外设。Directshow使Filter Graph Manager中的Filter按一定的顺序连接成一条“流水线”协同工作,Filter Graph的结构如图2所示。过滤器通过文件读写、修改数据和显示数据输出设备来操作流媒体。为了完成整个任务,必须将所有的过滤器Filter连接起来。应用程序只需要通过COM接口访问过滤器图表、控制流媒体或者接收过滤器事件来完成视频的播放。
1.2 COM组件
Directshow是基于COM系统的开发包。而COM组件对象模型是一种软件架构,它定义了不同的对象使用一致同意的协议进行通信的一套机制。所有的COM对象都支持相同的接口规范,这使得COM对象可以不依赖于具体的语言和系统平台。每个COM都至少有一个接口,这里所说的接口是指一套函数和它们参数的定义。每个COM有它自己的GUID-CLSID,每个接口也有它自己的GUID-IID。GUID是一串128 bit数字,由专门的程序产生,可以保证每个GUID的全球唯一性。当知道了一个COM的CLSID和它的接口IID,就可以用Co CreateInstance函数来实例化该COM对象的其他接口,可用该接口的IID作参数,调用Query Interface查询接口函数来完成[1]。得到COM的接口后,就可以用它访问该接口的一些函数。
2 Directshow的应用
本系统采用VC++6.0开发多媒体应用程序,开发应用程序之前先要配置开发和编译环境,在写应用程序时要包含头文件Dshow.h并连接到库文件strmbased.lib;在VC++的Library和Include中要加入Direct X SDK中的Lib和Include文件,并且放在标准的VC目录之前[2]。利用Directshow开发应用程序的步骤:(1)创建Source Filter、Trans-form Filter、Renderer Filter;(2)创建Filter Graph管理各个Filter,并且负责和应用程序交互实现播放控制等。
由于Directshow使用COM技术实现,首先要调用Co Initialize函数进行初始化。接着创建用于组建过滤器的过滤器组件管理器和Capture-Graph Builder组件,定义接口指针并获取接口[3]。
2.1 COM对象的创建
COM对象的创建要经过以下步骤:
(1)Co Create Instance调用Co Get Class Object函数;
(2)COM库找到DLL程序并进入进程;
(3)调用DLLGet Class Object函数;
(4)DLLGet Class Object函数创建类工厂;
(5)DLLGet Class Object把类工厂接口指针返回给CoGet Class Ojbect函数;
(6)Co Get Class Object把类工厂接口指针返回给CoGet Class Object函数;
(7)Co Create Instance得到类工厂后,调用类工厂的对象创建函数;
(8)类工厂创建COM对象;
(9)类工厂把COM对象返回给Co Create Instance函数,Co Create Instance函数返回;
(10)客户直接调用COM对象。
2.2 开发Direct Show一般过程
(1)创建一个Filter Graph Manager
IGraph Builder*p Graph=NULL
HRESULThr=Co Create Instance(CLSJD_Filter Graph,NULL,CLSCTX_INPROC_SERVER,IDD_IGraph Builder,(void**)&p Graph)
(2)根据实际应用,创建一条完整的Filter链路。
(3)调用Filter Graph Manager上各个接口的方法进行控制,并且完成Filter Graph Manager与应用程序的事件交互。调用Imedia Control接口的方法控制Filter Graph的状态转换:
IMediacontol*p Control=NULL
hr=p Graph->Query Interface(IID_IMedia Control,(void**)&p Control)
hr=p Control->Run()
2.3 媒体类型的检测
当两个Filter连接的时候,它们会采用某一种媒体类型达成一致的协议。媒体类型定义了处于源头的Filter将要给下一个与其相连接的Filter发送什么样的数据,以及数据的physical layout。两个Filter必须支持同一种类型的媒体格式[4]。
3 解码器设计
在Directshow环境中播放一个H.264格式的文件,需要一个能够对H.264格式的压缩视频进行解码的解码器。由于Directshow没有提供H.264的解码Filter,所以H.264视频解码器需要自行开发。
3.1 Filter的设计
为了实现H.264视频解码器,可设计一个名为H264Decoder的Transform Filter,包含一个出pin、一个输入pin,用于接收H.264的视频流输入,解码后输出YUV格式的图像帧序列。
Filter的注册名:“H.264 Decoder”
Filter类型:Transform Filter
CLSID:CLSID_Filter H.264
Merit值:MERIT_DO_NOT_USE
此Filter的功能是接收视频流的输入,解码后输出YUV格式的图像帧序列。而输入输出视频流是通过不同功能的Filter连接完成的。Filter的连接实际上是Filter上pin的连接,连接的方向一般是从上一级Filter的输出pin指向下一级Filter的输入pin。只有两个Filter都在Graph里,连接才能成功。应用程序可以通过IFilterGraph::Add Filter将Filter添加Graph中,当一个Filter被添加到graph中时,Filter图标管理器通过Ibase Filter::Join Filter Graph来通知Filter。pin连接的过程为:
(1)Filter Graph Manager表管理器首先调用输出pin上的IPin::Connect;
(2)如果输出pin接受连接,就调用输入pin上的IPin::Receive Connection;
(3)如果输入pin也接受连接,则双方连接成功。
从Directshow的基类继承得到Filter以实现一个独立的线程,专门用于H.264的解码输出。在输入pin上实现媒体类型检查(Check Media Type)。
3.2 基类的选择
可以选择的基类有:CTransform Fitler、CTrans In PlaceFilter、CVideo Transform Filter、CBase Filter。当Filter的输入pin接收数据后,经过一定的处理由输出pin再输出数据,一般选择CTransform Filter或者CTrans In Place Filter。由于在Filter上的两个pin要求的媒体类型互不相同,而CTrans In Place Filter的输入和输出pin上一般使用相同的媒体类型进行连接,并且使用相同的Sample管理器,所以这个Filter不适合用CTrans In Place Filter。而CBase Fitler是个一最基本的类,需要做比其他的基类更多的工作。此视频解码Filter最后选择了CTransform Filter类。
CTransform Filter类是从CBase Filter继承而来,其最大特征是将pin上必须实现的函数委托到了Filter上。一般不需要重新写输入和输出pin类,只需要在Filter上实现相应的函数即可。CTransform Filter类使用时需要重载函数:
CTransform Filter::Check Input Type
CTransform Filter::Check Transform
CTransform Filter::Decide Buffer Size
CTransform Filter::Get Media Type
CTransform Filter::Transform
由于微软公司推出的Directshow没有提供H.264的视频解码器。因此本文还需要使用ffmpeg中提取出的、经过优化的H.264视频解码组件。
本系统采用Directshow设计了H.264视频的解码器,并且利用ffmpeg提取出了H.264解码代码,实现了H.264视频的解码播放,如图3所示。
摘要:为实现视频监控系统中视频的解码,提出了一个H.264视频解码器在Directshow中的实现方案。Directshow应用程序编程接口是一个基于Windows平台的优秀流媒体架构,它为在Windows平台上处理各种格式的媒体文件回放、音视频采集等高性能要求的多媒体应用提供了完整的解决方案。
关键词:H.264,Directshow,解码器
参考文献
[1]潘爱民.COM原理与应用[M].北京:清华大学出版社,1999.
[2]陆其明.Directshow开发指南[M].北京:清华大学出版社,2003.
[3]陆其明.Directshow实务精选[M].北京:科学出版社,2004.
H.264编解码 第7篇
当今社会已经步入信息时代,传统的信息载体和通信方式已经无法满足人们对信息的需求。而实验表明:相比较语音和抽象数据,人类接受的信息更多是以图片和视频方式为载体的。其中视频信息具有直观、具体和高效的特点,这也就决定了视频通信技术将成为信息时代的重要技术之一[1]。
由于视频的数据量巨大,而存储视频的资源通常是非常有限的,因而对视频进行压缩编码,以减少存储资源的消耗,非常必要。然而,通常情况下,使用的压缩算法的复杂度越高,压缩比率越高,视频播放时的解码速度就会越低。因而在提高编码压缩率的同时,也需要对解码器进行相应的优化,以提高视频解码器在目标平台上的性能。本文就实现了ffmpeg解码器在龙芯3B上的移植与向量化,提高了该解码器在龙芯3B上的性能。
1 视频编/解码与龙芯3B
1.1 视频编/解码
目前,成熟的压缩编/解码方法有很多。其中H.261、MPEG-1、MPEG-3和H.263采用了第一代压缩编码方法,如预测编码、变换编码、熵编码以及运动补偿;而MPEG-4和H.264[2]采用了第二代的压缩编码方法,如分段编码和基于模型或对象的编码等。
视频压缩编码的主要目的是减少存储视频所占用的资源,而解码技术的目标则是提高解码的速度,从而提高视频播放的流畅性。常见的基于H.264编码方法的软解码器包括Core AVC、ffmpeg和JM等。其中JM是H.264官方网站提供的编/解码器,集合了各种编/解码算法,而且代码的结构清晰,很适合应用于对视频编/解码技术的研究。而Core AVC解码器则主要用于商用,其解码速率比ffmpeg快50%以上。ffmpeg是开源的解码器,而且性能相对较好,很多开源项目都直接或间接地使用了ffmpeg,如mplayer播放器等。通过对性能以及开源特性的综合考虑,本文选择ffmpeg作为移植和向量化对象。
1.2 龙芯3B体系结构
龙芯3B处理器在兼容了MIPS64指令集的同时,实现了针对多媒体应用的向量扩展指令,这对视频编/解码应用性能的提升有很大的帮助。
龙芯3B提供了256位的向量寄存器并实现包括256位向量访存在内的向量扩展指令。使用向量指令可以一次完成32个字节宽度数据的操作。而这样的结构和指令集设计,使得龙芯3B非常适合于实现大规模相同类型数据的相同运算,比如矩阵乘法运算和FFT运算,以及视频编/解码运算等。
不过由于ffmpeg并未实现对龙芯3B平台的支持,因而需要完成ffmpeg到龙芯3B的移植工作。本文之前也有一些ffmpeg到其他平台的移植工作[3]和针对龙芯平台的移植与优化工作[4],都取得了不错效果。
2 基于龙芯3B的ffmpeg移植
2.1 ffmpeg的移植
ffmpeg解码器提供了对不同目标平台的支持,而与这些平台相关的文件都保存在以该目标平台命名的目录下。例如,ffmpeg解码器实现了对arm和sparc平台,以及x86平台的支持。
对于实现ffmpeg解码器对龙芯3B的支持,主要完成以下5个步骤:
(1)修改configure配置文件,增加与龙芯体系结构相关的配置选项;
(2)新建龙芯专用文件夹godson,将龙芯体系结构相关的文件都存放于该文件夹中;
(3)将godson文件夹下新增的需要编译的文件添加到Makefile中;
(4)增加与dsputil_init类似的新的初始化函数dsputil_init_godson;
(5)在头文件中添加新增函数的声明。
针对龙芯3B的ffmpeg移植工作相对比较简单,因而本文重点介绍针对龙芯3B的向量化工作。
2.2 移植后的ffmpeg的性能比较
本节对移植后的ffmpeg解码器进行了性能测试,对使用龙芯3B向量扩展指令和不使用龙芯3B扩展指令两种情况下的性能进行了比较。测试时使用支持龙芯3B扩展指令集的GCC编译器进行编译,并且开启-ftree-vectorize和-march=godson3b编译选项来支持龙芯3B扩展指令。使用的测试用例为视频"walk_vag_640x480_qp26.264",测试结果如表1所示。
从表1的测试结果中可以看出,使用龙芯3B的向量扩展指令可以提高ffmpeg解码器在龙芯3B上的性能,用来测试的视频的解码时间减少了约466s。尽管如此,由于GCC编译器本身自动向量化能力的限制,ffmpeg解码器的性能提升还是比较有限的,因而针对龙芯3B的指令集对移植后的ffmpeg解码器进行向量化,就成为了进一步提高性能的重要工作。
3 ffmpeg的向量化
3.1 ffmpeg的oprofile测试
使用oprofile对ffmpeg解码视频"问道武当002.mkv"的过程进行测试,测试结果如表2所示。表2列出了各个函数的调用过程以及运行时间所占的比重。而针对ffmpeg解码器进行的向量化工作,则主要是针对oprofile测试结果中执行时间较长、运行比重较大的几个函数的向量化。
上述函数的执行时间几乎占据了ffmpeg解码器执行时间的60%,因而针对上述几个函数进行向量化,就完全可以达到提升ffmpeg整体解码速度的目的。
3.2 针对龙芯3B的ffmpeg向量化
3.2.1 向量化方法
实现ffmpeg解码器在龙芯3B上的向量化主要是使用龙芯3B扩展的向量指令来改进3.1节中oprofile测试结果中执行时间比重较大的几个函数。而且在向量化的同时,同样可以使用一些优化策略,来提高向量化后的函数的性能。主要使用到的优化方法包括:
(1)循环展开。循环展开[5]是一种循环变换技术,将循环体中的指令复制多份,增加循环体中的代码量,减少循环的重复次数。需要说明的是,循环展开本身并不能直接提升程序的性能。
使用循环展开的主要目的是充分挖掘指令或者数据间的并行性。其中向量扩展指令的使用就是利用了展开后的循环体内数据的并行性;而在展开后的循环内使用指令调度和软件流水技术则是为了充分利用指令间的并行性。
(2)指令调度。循环展开后的循环体内的指令数目增多,因而可以进行指令调度,将不存在操作数相关性和不存在运算部件相关性的指令调度到一起,这样可以充分发挥龙芯3B的流水线性能,从而提高代码在龙芯3B上的执行速度。
除了使用龙芯3B的向量扩展指令和使用上述两种优化方法以外,同样还可以根据具体函数的特点,使用其他一些优化方法进行优化,比如使用逻辑运算和移位运算来代替乘法运算等。针对每个函数的向量化优化在3.2.2小节中介绍。
3.2.2 针对具体函数的向量化
3.2.1小节概述了向量化时用到的一些优化方法,本节则针对oprofile测试中比重较大的几个函数进行有针对性的优化。
对于表2中的函数,我们可以根据函数名将其分类,函数命名类似的函数基本上都可以使用类似的优化方法。
(1)简单向量化。对于1号和2号函数的优化,本文都采用了使用移位运算来代替乘法运算的策略,并且针对循环内部运算的有界特性,使用饱和向量运算来改进。不过对于2号函数的访存操作,由于存在着数据非对齐的情况,因而使用额外的向量指令对数据进行打包和回写。而3号函数则是1号和2号函数的混合,因而对1号和2号函数的优化间接提升了3号函数的性能。
而对于4号、5号和6号函数,本文仅对其内层循环使用了循环展开和指令调度策略,就能够取得不错的运算效果。
同样,对于11和12号函数也可以比较直观的进行向量化,在此就不做详述了。
(2)间接向量化。而对于比较难于向量化的7号和8号函数,本文分别采用了使用掩码和使用矩阵转置运算的策略来间接实现向量化。
其中针对函数h264_v_loop_filter_luma的C语言实现中有很多判断语句的问题,本文使用构建掩码的方式来消除这些判断语句。
以图1(a)中的循环为例介绍掩码的构建。而图1(b)所示为代替该循环的向量指令。具体的运算结果如图1(c)所示:将p向量(数组)和q向量做饱和减法(结果为负的都置为0),得到的结果向量如Vsub所示。使用Vsub与零向量进行比较来设置掩码:结果为真,掩码值为0x FF;反之,结果为假,掩码为0。最后将掩码值与p向量进行与操作,就可以得到该循环的运算结果。
使用构建掩码的方法来消除判断语句,不但减少了由判断引起的时间开销,而且重要的是间接将循环进行了向量化,提高了函数性能。而对于9号和10号函数,可以使用同样的方法来改进。
而对于8号函数,由于运算处理的是连续的数据,因而无法进行向量化。使用矩阵转置的方式,将数据重新打包后,就可以进行相应的向量运算。
对于图2(a)中的运算,原始计算是p向量内部的运算,因而无法向量化,我们用向量指令将p向量转置为q,其中q0存放p中标号为1的数据,q1存放p中标号为2的数据,依此类推。转置得到的q向量就可以用图2(b)中的向量指令运算,得到的运算结果与原来的运算相同。
对于13~15号函数的优化,同样使用到了上面的转置方法。而4.1节的测试结果则说明了各个函数的优化效果。
4 实验结果
4.1 ffmpeg各函数加速比
本文分别对向量化后的各个函数进行了测试,并且与未向量化之前的函数进行了比较,各个函数向量化优化后的加速比如图3所示。其中图中横坐标所示函数序号与表2中的各个函数一一对应。
图3中的函数的加速比所跨越的范围较大,比如6号函数的加速比约有23.9左右,而最后一个函数的加速比只有1.2左右。之所以会出现上述情况,除了与改进后的函数所使用的向量指令的数量和修改代码的比重有关以外,也与运算所使用的操作数的类型有关。对于6号函数,其循环内的运算所使用的操作数的类型为字节类型,因而仅仅使用向量指令进行优化,理论加速比就可以达到32,不过本文仅仅对该函数的内层循环进行了向量化,而向量化后的内层循环一次仅仅处理了16个字节类型的数据,即并未充分使用256位的向量寄存器。因而理论的加速比应该为16,但是由于结合了循环展开和指令调度等其他优化策略,因而实际的加速比可以达到23.9左右。同样,对4号、5号和6号这三个同类型的函数进行分析,我们也可以发现:后一个函数的加速比均约为前一个函数加速比的两倍。这是因为对于4号函数,内层循环向量化后一次可以同时计算4个字节类型的数据,而5号函数可以同时计算8个字节类型的数据,因而理论上的加速比也应该是两倍的等比数列形式,而实际结果与理论分析是一致的。
对于3.3.2小节中重点介绍的7号函数和8号函数,其原函数无法进行简单向量化,而本文使用了掩码以及矩阵转置等优化方法,使其能够使用龙芯3B的向量扩展指令,因而尽管性能提升不大,但是加速比也分别有3.2和5.5。
4.2 不同平台上的向量化比较
本文同样将ffmpeg解码器分别在不同的平台上进行了测试,使用的两个测试视频分别为是"问道武当002.mkv"(视频A)和"walk_vag_640x480_qp26.264"(视频B)。其中视频A是问道武当视频(720p)中截取的片段,而后者是通过x264对walk_vag.yuv(480p)编码生成的,编码时选用的qp值为26。而测试平台则分别选择了AMD和Intel处理器平台。
从表3的测试结果可以看出对于视频A,在龙芯3B上的性能提升比其他两个平台上都高很多;而对于视频B,在龙芯3B上的性能提升也与其它两个平台接近。实验结果表明:在龙芯3B上实现ffmpeg解码器的向量化,对性能提升有很大帮助,而且解码某些视频时,性能的提升甚至高于性能优越的商用处理器。而通过与表1中使用GCC向量化编译的结果进行比较,也可以看出:手工对ffmpeg解码器进行向量化比使用GCC进行向量化,性能有更大的提升。
5 总结和展望
本文实现了ffmpeg解码器到龙芯3B的移植,并针对龙芯3B实现了对向量扩展指令支持的特点,对ffmpeg解码器进行了手工向量化。实验结果表明:手工向量化后的ffmpeg解码器的性能比使用GCC向量化编译后的ffmpeg解码器性能要好很多,而且性能的提升也比Intel和AMD平台更多。
本文仅仅从代码级实现了针对龙芯3B的ffmpeg解码器的向量化移植,为了进一步提高性能,还需要从整个算法层面上进行优化。另外,由于龙芯3B的多核特性,还可以考虑使用多核进行解码。
参考文献
[1]姚庆栋,毕厚杰.图像编码基础[M].北京:清华大学出版社,2006.
[2]黄健,张琳.H.264视频编码技术研究[J].计算机数字工程,2006,34(7):83-87.
[3]Major A,Ying Yi,Nousias I,et al.H.264decoder implementation on a dynamically reconfigurable instruction cell based archi-tecture[C]//Proceedings of the2006System On Chip Conference,Sept.24th-27th2006:49-52.
[4]王明,彭成磊,都思丹.面向龙芯平台的快速DCT算法及其实现[J].计算机工程,2009,35(17):223-225.
H.264编解码
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。