i.MX51平台视频硬件解码的研究与应用*

2013-02-21 07:53周时伟谢维波郭利全
网络安全与数据管理 2013年10期
关键词:固件缓冲区寄存器

周时伟 ,谢维波 ,郭利全

(1.华侨大学 计算机科学与技术学院,福建 厦门361021)2.厦门软件园 华侨大学嵌入式技术开放实验室,福建 厦门 361008)

随着多媒体技术的迅速发展,数字视频的应用越来越广泛。人们对高清视频的狂热追逐给视频解码带来了巨大的压力[1]。传统的软件解码方法已经很难满足视觉要求。高清视频的分辨率远远高于一般格式视频,其码率也很高,再加上视频编码标准的压缩率高,使得解码运算量很大。因此,常规地直接用CPU解码会极大地消耗CPU的运算能力,于是转向硬件解码。硬件解码是通过显卡的视频加速功能对高清视频进行解码,能够将CPU从繁重的视频解码运算中释放出来,使计算机具备流畅播放高清视频的能力。本文通过研究主流Android开发板i.MX51上的VPU,给出了使用VPU实现视频硬件解码的主要流程和方法。

1 i.MX51 EVK平台硬件视频解码方案

1.1 i.MX51处理器的特性

i.MX51是飞思卡尔公司自主研发的ARM体系结构的中央处理器单元。i.MX51处理器采用了先进、高效率的ARM Cortex A8内核,处理器运行在800 MHz的高速下[2]。相比于ARM11产品,其性能被大大提高。它支持最高200 MHz的DDR2和移动DDR DRAM时钟速率,拥有32 KB的指令缓存和数据缓存以及256 KB的二级缓存[3];处理器内部集成了 DDR/DDR2内存控制器;同时集成了矢量运算、浮点运算以及ARM NEON SIMD媒体和信号处理器,为多媒体信息娱乐终端提供了强大的处理核心支持。

1.2 i.MX51 VPU

i.MX51 VPU(视频处理单元)是一个支持多标准编解码操作的高性能的视频编解器引擎。VPU编解码器支持MPEG-1/2、MJPEG、H.264、MPEG-4的编解码。 VPU 在i.MX51上支持的解码高达HD水平,编码为SD水平。VPU通过32 bit的APB总线和64 bit的AXI总线与系统联络,APB总线用于系统控制,AXI总线用于数据的传输。同进,利用片上存储器实现高性能。

VPU中的视频硬件模块被最佳化设计以用来在不同的视频标准中共享使用,并提供强大的性能和超低的功耗,如图1所示。

VPU提供一套主控接口寄存器,通过这些寄存器主处理器可以简单、高效地控制VPU。VPU拥有一个16 bit的DSP内核——位处理器,通过该位处理器可以控制内部硬件模块并实现视频编解码操作。

1.3 视频解码方案

i.MX51开发板具有支持多种操作系统的特性,例如Android等实时OS。为了能够获得较好的推广应用,采用比较流行的Android系统。

在Android中创建自己的解码函数库,通过JNI穿越系统的应用框架层直接访问库函数,才能实现Android系统下对硬件的直接调用和控制。首先,使用C语言对VPU的API组织调用,实现视频的解码;然后,生成相应的动态库,并提供给JNI相应的应用接口;最后,在Java类中使用C实现视频解码的本地方法。

2 VPU解码的内部逻辑

2.1 VPU的初始化

VPU中位处理器用于处理比特流数据,位处理器是一个高度优化的,它还可控制VPU与主处理器之间的通信[4]。位处理器固件被分为两部分来进行视频的解码:一部分是引导代码,这些代码是主处理器通过IP总线下载到位处理器内部存储器的,启动代码大小为1 KB,这些启动代码被写在外部存储器一块区域中,固件区域的基地址由VPU的API写入;另一部分是进行解码处理的固件包,在开始解码前,固件先被写进外部存储器启动代码之后的一块连续的区域中,运行过程中,位处理器自行下载固件,根据不同的解码标准下载到相应的内部存储器中,它是通过AXI总线进行加载的,VPU初始化过程如图2所示。

2.2 VPU与应用程序的交互

图3给出了位处理器和VPU视频处理核心模块,并且指明了VPU如何与应用软体进行交互。从根本上说,在框架水准之上,主处理器是通过API与主处理器进行通信的。

2.3 VPU的硬件抽象层

图4为VPU的硬件抽象层的详细内容。VPU的解码器的寄存器头文件vpu_reg.h中定义了内存映射地址;头文件vpu_io.h中定义了I/O操作的各种定义,声明了I/O操作的各种函数,并在vpu_io.c中实现了其头文件中的各个函数;vpu_lib.c是VPU的库函数,实现了VPU编解码的所有操作;vpu_lib.h中定义了VPU函数库中的数据类型、数据结构,并声明了各个函数;vpu_util.c中是与VPU中位处理器相关的各种操作。

3 VPU硬件解码流程分析

3.1 VPU进行视频解码的流程

通过VPU解码的基本流程包括以下步骤:

(1)调用函数Init()来初始化 VPU;

(2)使用函数DecOpen()打开一个解码器实例;

(3)为了能够提供合适数量的字节流,使用DecGet-BitstreamBuffer()获取字节流缓冲地址;

(4)在改变解码器的输入流之后,使用 DecUpdateBitstreamBuffer()通知传输到字节流缓冲区的字节数量;

(5)在进行一个图片的解码操作之前,使用DecGetInitialInfo()来为解码操作获取重要的参数,如图片大小、帧缓冲等;

(6)使用返回的帧缓冲大小配置帧缓冲区合适的大小,并且使用函数DecRegisterFrameBuffer()把这个数据传达给i.MX51 VPU。

(7)使用DecStartOneFrame()开始图片解码器操作,一张一张地进行图片解码;

(8)等待完成图片解码器操作的中断事件;

(9)使用DecGetOutputInfo()检查解码器操作的结果;

(10)播放第 n帧后,使用 DecClrDispFlag()清除播放缓冲标志;

(11)如果还有更多的比特需要解码,返回到步骤(7)继续执行,否则就执行下一步;

(12)使用DecClose()关闭实例,终止操作;

(13)调用UnInit()释放系统资源。

3.2 数据处理与控制

VPU拥有一个专用的路径进行主处理器与VPU之间的数据或信息的交流,即共享存储器。共享存储器通过ABMA主总线被访问,使用这个存储器进行比特流和数据帧的交换。通过使用VPU寄存器中的主控寄存器来实现主处理器与VPU之间专一的信息交流路径。所有在主处理器与VPU之间的命令和响应都是通过这些寄存器来交换的。数据转换与命令及响应相关的信息也是通过主控寄存器来交换的。从主处理器可以访问VPU主控接口的所有寄存器。一些主控寄存器用于交换实际的命令和响应,另一些寄存器则用来向主处理器提供VPU内部状态信息。

主应用程序通过API发送命令和相应的参数给VPU来控制VPU。从VPU接收到一个中断之后,发送要求的操作已经完成的信息。如图5所示为应用程序数据处理的过程。

每个API的定义包括请求命令和输入输出数据结构。从API给出的命令经常被写进一个专用的I/O寄存器,但是输入和输出数据结构是通过一套包括输入参数和输出结果的I/O命令寄存器传输的。

所有的像素数据或者数据流处理被主处理器执行或者通过在SDRAM中的共享内存被VPU执行。为了保证主处理器与VPU之间的安全性,所需信息被存放在主控寄存器中。这些事务一般都是单向的,VPU或主处理器写数据,其他设备在一个单数据缓冲区读取数据。

4 视频硬件解码在Android下的应用

4.1 MPEG-4在i.MX51上的硬件解码实现

本文以MPEG-4视频流为例实现其硬件解码。图6为MPEG4的解码流程。

(1)初始化 VPU

用BIT Code Download命令下载BITProcessor固件到存储器;设置初始化参数用于对BIT Processor进行一般性设置,设置工作缓冲区基址、BIT Code存储器地址、比特流缓冲区控制等;命令BIT Run Start运行BIT处理器初始化VPU。

(2)创建并初始化一个MPEG-4解码进程

设置SEQ_INIT参数,这一过程通过调用MPEG4_initial()进行解码初始化,包括打开文件、设置硬件参数(如codec)、解码参数初始化(如波特率设置)、申请地址空间(如配置基地址);运行 SEQ_INIT命令,开始一个MPEG-4解码进程。如果出现Wait BusyFlag=0,则等待BIT处理器完成SEQ_INIT命令的执行,以进行接下来的处理。

(3)运行MPEG-4解码进程

设置PICTURE_RUN参数配置帧源地址和目标地址;运行PICTURE_RUN命令,通过调用 MPEG4_continue()启动MPEG-4的解码进程。以帧为单位完成读输入、解码和写输出的工作。返回1代表解码正常,可对其本身进行再调用,实现下一帧的解码;返回0则代表文件结束或者出现异常。如果出现Wait BusyFlag=0,则等待BIT处理器完成PICTURE_RUN命令的执行。它也意味着结束了一帧数据的解码,将解码后的数据发送到图像处理单元进行后处理并播放。

(4)继续执行第(3)步,如果比特流缓冲区是空的,则在运行下一帧解码之前,主处理器应该下载新的比特流到比特流缓冲区。

(5)运行SEQ_END命令调用 MPEG4_stop(),编码完成终止解码进程。对硬件进行设置,并释放内存空间。

一般而言,不同编码标准的解码处理流程是相似的,尽管不同的编码标准对应的固件版本有小幅改进,但其具体的执行过程是由VPU驱动来完成的。

4.2 Android平台使用VPU硬件解码

之前的解码是用C语言编译通过的,而开发板i.MX51上运行的是Android系统,需要在Android系统上对解码实现,本文采用的是JNI技术。

首先,编写Mikefile文件并编译;接着,在终端中进入工程目录,运行ndk-build命令进行编译,编译通过后即可生成动态库文件libvpu.so;最后,在Java文件代码中对本地库进行调用。使用public native String stringFromJNI()申明本地方法;使用System.loadLibrary()来加C动态库。至此,对本地库的调用即完成。

本文深入地分析和研究了i.MX51开发板的功能特性,详细介绍了其硬件解码模块的内部结构和使用方法,并具体说明了其应用程序接口函数。在此基础之上,探讨了其一般使用流程,并用MPEG4的具体解码过程进行了说明,最后在Android系统下实现。实验结果表明其运行情况良好。

[1]李强申.Linux视频硬件解码技术与应用研究[D].北京:北京邮电大学,2009.

[2]王知航.基于i.MX51芯片和Android平台平板电脑电源管理的研究与应用[D].西安:西安电子科技大学,2011.

[3]i.MX51:应用处理器开发评估方案[J].世界电子元器件,2010(3 ):22-23.

[4]Freescale公司.i.MX51多媒体应用处理器参考手册[S].2010.

猜你喜欢
固件缓冲区寄存器
STM32和51单片机寄存器映射原理异同分析
Lite寄存器模型的设计与实现
移位寄存器及算术运算应用
基于网络聚类与自适应概率的数据库缓冲区替换*
基于SHA1的SCADA系统PLC固件完整性验证方法
基于UEFI固件的攻击验证技术研究*
基于固件的远程身份认证
一类装配支线缓冲区配置的两阶段求解方法研究
关键链技术缓冲区的确定方法研究
提取ROM固件中的APP