我们选取ITU-T公布的JM6.1e参考软件作为我们的优化对象,目标是实现一个base-line profile的实时编解码算法。但是JM6.1e代码复杂,冗余度很大,需要在PC机端对其进行较大调整,涉及工作有:去除冗余代码、规范程序结构、全局和局部变量的调整和重新定义、结构体的调整等。
1. 代码移植
代码移植,就是将在PC端跑通的程序,移植到DSP端,使其能够初步运行。需要考虑的问题主要是一些内存分配,语法规则等问题。
2. DSP端代码的优化
通过把PC机H.264代码DSP化,可以在DSP上实现H.264的编解码算法,但是,这样实现的算法运行效率很低,因为所有的代码都是由C语言编写,并没有完全利用DSP的各种性能。所以必须结合DSP本身的特点,对其进一步优化,才能实现H.264视频解码器算法对视频图像的实时处理。
代码的优化分为三个层次:项目级优化,算法级优化,指令级优化。
*项目级优化
是对项目的整体优化,主要手段有以下几点:
首先是利用CCS编译器提供的优化功能,对优化选项进行选择和配置,如打开O-3选项等。
其次对程序结构进行调整,对不适合DSP执行的语句进行改写,以提高代码的并行性。
最后是对内存进行合理分配,因为DSP资源有限,我们把一些常用数据,如全局变量,程序等数据分配到访问速度高的片内内存,把占用空间较大的数据分配在片外,如帧存等。
* 算法级优化
是利用H.264的自身特点,提出快速高效算法,从算法上挖掘潜力,提高运行速度,达到优化目的。这部分工作主要集中在编码器优化方面。
视频编码中,运动估计部分是运算量最大的一块,研究显示,对于H.264,单帧参考,运动估计占总运算量的70%,5帧参考,这个比例能达到90%,因此,提出有效快速的运动估计算法非常有必要,我们通过研究提出了基于预测和早停止技术的运动估计算法,主要方法是利用周边邻块对当前块运动矢量进行预测,并设定自适应阈值,使搜索提前停止。
我们提出的算法,在搜索窗32时,每块平均搜索点数3-4个左右,和全搜索算法的4225余个点相比,提高速度1000多倍。和一些经典快速算法相比,优势也很明显, H.264算法中,亚象素运动估计采用全搜索,1/4精度下,需要搜索16个点。我们提出了自己的亚象素快速搜索算法,平均搜索点数7个,节省运算量60%以上。我们提出的新算法提高编码速度很明显,而且质量也较好,PSNR损失不到0.06dB,码率增大2%左右。这对于运动估计算法基本可以忽略不计。
此外,我们针对帧间编码7中块大小匹配模式,以及帧内预测13中模式太过复杂,运算量太大的问题,提出了我们自适应模式选择算法,不需要将所有模式全部计算,就能找到一种相对最优的模式。这些算法,都大大提高了代码的运行速度,在速度与质量上达到较好的折中。
*指令级优化
如果上述优化方法无法达到实时要求,就需要进行指令级优化了,主要手段有。
·循环拆解:将C语言中的for循环打开,排流水线,提高并行性
·调用系统提供的丰富的内联函数
·调整数据结构:将需要大规模访问的数据,在内存中将它们放置在一起,方便DMA机制的访问,或并行指令的处理,如插值函数模块。
·将耗时函数抽取出来
用线性汇编改写,充分利用丰富的媒体处理指令[5],最大限度的利用DSP的并行性。例如,运动估计中频繁调用的SAD计算,是对相应象素点做差,并对残差场求绝对值和的计算。原始算法是对每一对象素点分别求差,再对其绝对值累加。
我们对其进行了线性汇编的改写,使用了SUBABS4(一次对两对4字节数据做差并求绝对值),DOTPU4(一次对两对4字节数据做内积),LDW/LDNW(一次读取4字节数据)等指令,使代码并行性有了很大提高。对16×16的块来说,优化前需要指令1000余条,优化后,200条就足够了。 我们充分利用系统并行性,对耗时函数进行汇编语言改写,涉及函数有DCT变换,反DCT变换,整象素运动估计,亚象素搜索,帧内编码函数,插值函数等,效果明显。
算法性能的评测及前景展望
在NVDK C6416环境下,测试了编解码器算法,对QCIF测试序列,编码器40_50帧/秒的编码码速度,解码器达到50_60帧/秒的解码速度,远远达到了实时性解码的目的。
因为代码的兼容性和可移植性,我们可以把在C6416上实现的编解码算法移植到TI公司推出的媒体处理专用芯片TMS320DM642上,利用其丰富的媒体处理接口和协处理器,实现更好的性能。