您当前的位置:五五电子网电子知识单片机-工控设备嵌入式系统-技术基于ARM926EJ-S的MPEG-4软解码器的优化与实现 正文
基于ARM926EJ-S的MPEG-4软解码器的优化与实现

基于ARM926EJ-S的MPEG-4软解码器的优化与实现

点击数:7492 次   录入时间:03-04 11:58:09   整理:http://www.55dianzi.com   嵌入式系统-技术

1 引 言

MPEG-4视频压缩标准自问世以来受到人们的广泛关注。近几年,嵌入式应用中对MPEG-4播放器的实现已经成为众多厂家的研究热点。专用的MPEG-4播放芯片已经非常普遍,但是减少功耗和降低成本一直是商家追求的目标,因此,随着嵌入式的主流微处理器ARM的处理能力越来越强,用他来实现MPEG-4系统的软解码成为了众多嵌入式设计公司研究的重点内容。由于MPEG-4系统庞大且需要大量的数据处理,因此在ARM中实现MPEG-4软解码需要对其原算法进行充分的优化才能达到理想的性能。为此研究了一种基于ARM926EJ-S微处理器的MPEG-4解码算法的纯软件实现和优化的方法,通过对解码算法的软件优化,将QVGA格式MPEG-4码流在ARM9平台上的播放速度由原来的10 f/s提高到了37 f/s,完全达到了流畅播放的要求,具有很高的实用价值。

2开发平台及耗时分析

论文研究使用的是基于ARM926EJ-S微处理器的综合开发平台,采用Linux操作系统,外接320*240(QVGA格式)的LCD显示屏。ARM926EJ-S微处理器的时钟频率为190 MHz;采用5级整数流水线操作,支持32位ARM指令集和16位Thumb指令集以及扩充的DSP指令集;支持数据Cache和指令Cache,具有更高的指令和数据处理能力。软件编译环境为ADS1.2,使用Multi-ICE下载程序。

MPEG-4 SP级算法流程图如图1所示。优化的前期工作首先要将MPEG-4解码代码移植到开发平台上,然后对解码各个模块进行运算量和耗时分析,找出优化的重点内容。本文采用长度为376 934 B的AVI码流为测试序列,该码流共95帧,其中包括8个I帧,87个P帧。在未优化前测得的耗时分析结果如表1所示,整个测试序列解码播放完毕耗时10.05 s,解码播放速度只有9.5 f/s。



www.55dianzi.com

3.1.2 调整子块处理以增加Cache命中率

MPEG-4每个宏块由6个子块组成。在XVID源代码中,宏块解码中的6个子块的所有处理一起进行,被放在一个大的for循环中。ARM9采用哈佛结构,分别拥有I-cache和D-cache,所有处理同时进行,某一子块的值会一直在D-cache中不被替换,对于D-cache是非常有利的,但是对于I-cache来说却会造成代码的不断替换而影响Cache效率。对于I帧,由于其数据量比较大,数据替换的开销会远远大于代码替换,因此不对其做处理。而对于P帧,由于数据量小,零值较多,数据替换开销大大降低,因此将其6个子块的某一处理集中进行,保证这一处理过程的代码一直存在于I-cache中,以增加cache的命中率。具体的做法是:

这个过程使解码速度提高了将近4 f/s。

另外对于I帧,IDCT与VOP重建也是可以合并的,这个过程可以减少存储器的访问次数。但是这个合并过程不符合ARM的Cache工作特性,因此优化的效果并不明显,这也是优化过程中矛盾折衷的明显体现。

3.2 编写ARM汇编函数

ADS编译器对C程序有很强的编译能力,但对于一些运算量较大,涉及存储器访问较多的模块,仍然需要使用ARM汇编优化。这部分主要是针对耗时较多的IDCT,插值,VOP重建等模块。在书写汇编函数时,要充分把握ARM处理器的特性,尽量避开多周期指令,避免流水线阻塞,合理分配寄存器以尽量减少存储器操作。汇编函数的优化包括以下几点: 3.2.1避免多周期指令

在ARM汇编中,相对耗时的指令主要有存储器操作指令load/stor,程序跳转指令B,乘法指令MUL等。在编写汇编函数时,要尽量的考虑这些指令的替换方案。

对于存储器操作指令,可以采用多寄存器传送指令LDM/STM来替换。一次LDR指令需要5个指令周期,而N个寄存器传送的LDM指令只需要N+4个指令周期。IDCT、插值、VOP重建中的数据读取都是连续地址操作,可以一次读人4个甚至更多的数据到寄存器以减少程序的执行指令周期数。

其次,一条程序跳转指令B需要3个指令周期,利用手写汇编可以避免ADS编译C时经常出现的函数跳转指令,同样减少了执行周期数。

3.2.2避免流水线阻塞

ARM9采用五级流水线,执行效率很高,但是如果指令设置不当,很容易造成流水线阻塞而影响执行效率。Load装载指令和B跳转指令是造成流水线互锁①和刷新②的重要因素。解决流水线互锁的办法主要是预装载和循环展开。

预装载,即将接下来要用到的数据在不影响寄存器使用的情况下提前两个以上指令周期装载到寄存器中。这是由于load指令装载到寄存器的数据在接下来的2个周期中还不能被使用,会造成流水线的互锁。

循环展开,即将循环体内的主体多次循环将循环跳转次数减少。这样不仅可以减少B跳转指令带来的流水线刷新,同时可以在前一个循环中通过预装载下一个循环需要用的数据来避免流水线的互锁。

3.2.3尽量减少存储器操作

将经常使用的数据保持在寄存器中,避免每次用数据时都从存储器读取。尤其在IDCT中,尽量将一行或一列的数据一直保持在寄存器中,寄存器的执行效率是最高的,合理的分配寄存器和利用堆栈可以使程序更优。

一个高效的汇编程序可以使整个性能有较多的改善,通过ARM汇编函数的替换,测试序列解码播放完毕耗时3.1 s,解码速度提高了8 f/s。

3.3寻找快速算法和并行算法

ARM汇编的好处不仅在于执行效率高,还在于可以充分利用ARM处理32位数据的特性,寻找快速算法和并行算法。

对于插值函数,可以采用并行算法来一次处理多个象素。每个象素是一个8位数据,而ARM处理器是32位,因此可以改进算法一次处理4个象素。插值中的关键算法是:

rounding是码流中一个取0或1的参数。我们可以改进这个算法4个象素一起处理。通过分析知道,可以将式(1)改为A/2+B/2+C,C也应该是一个取0或者取1的值。分析的结果发现,当rounding为0时,C=(A∣B)&0X01;当rounding为1时,C=(A&B)&0X01。此时我们可以用4个象素组成两个32位的字W1,W2,利用公式:


W的结果等同于四个象素单独处理的结果。但是由于ARM处理器字读取时是字地址对齐的,因此要注意改进算法引起的字地址不对齐问题,利用这个算法时可以通过拼字的方法来解决字地址对齐的问题。

通过这一步骤的优化,测试序列解码播放完毕耗时2.56 s,解码速度提高了6 f/s,整体解码速度达到了37 f/s。

4结语

本文对MPEG-4软解码器在ARM平台上的实现及优化的整体思路和步骤进行了阐述,优化结果理想,软解码播放速度由最初移植完毕时的10 f/s提高到了37 f/s。本文给出的优化方案可以进一步推广到H.264或者其他视频软解码系统基于ARM的应用中。




本文关键字:解码器  嵌入式系统-技术单片机-工控设备 - 嵌入式系统-技术