APP下载

解决OpenMAX组件资源冲突的一种方法*

2012-01-21贺静海华云松

光学仪器 2012年1期
关键词:调用音频组件

贺静海,华云松

(上海理工大学 光电信息与计算机工程学院,上海 200093)

引 言

目前常采用基于OpenMAX标准接口与多媒体协处理器的多媒体解决方案,来开发手机多媒体功能,上层应用通过OpenMAX组件在协处理器中运行相关Codec,处理数据。这种常用的解决方案的优点是:移植性高,设计周期短,成本低;缺点是:受协处理器内存限制,无法同时运行所有Codec,若多个组件同时申请资源时,就会产生资源冲突,影响系统运行,甚至发生死机。

针对上述目前常用方案的缺点,文中提出的解决方法基于OpenMAX流程规范,根据Codec类型将协处理器内存资源划分为音频解码、音频编码、视频解码、视频编码4种不同运行空间(数据和指令空间),并对其进行管理及维护,为OpenMAX组件进行资源获取、释放、抢占等操作行为提供接口。在多组件同时访问协处理器资源时,根据组件优先级对资源实施实时仲裁,实现资源被单一组件互斥使用,完成系统并发需求。

1 OpenMAX

OpenMAX[1]是由Khronos制定的多媒体应用程序标准接口,主要针对嵌入式设备或移动设备,在架构底层上为多媒体Codec和数据处理定义了一套统一的编程接口(OpenMAX IL API),对多媒体数据的处理功能进行系统级抽象,为用户屏蔽了底层的细节。图1是OpenMAX IL API软件全貌,OpenMAX IL API有个高层实体,称为IL客户端(IL client),该客户端通常是一个filter graph多媒体框架或者应用程序的一个功能片,IL client通过OpenMAX组件调用OpenMAX IL API可以以一种统一的方式来使用Codec和其他多媒体数据处理功能,无需担心其底层的硬件结构。

OpenMAX组件代表一个具体的功能模块,可以是文件解析组件,也可以是编解码组件等。OpenMAX组件有Loaded,Idle,Executin与WaitingForResource等6种状态。每个组件最开始处于Loaded状态,当组件开始执行任务时,先转到Idle状态,这时需要获取资源,如果获取资源失败,则转入WaitingForResource状态,之后从Idle状态转入Executing状态开始执行任务,当执行完任务时,组件释放资源并转入Loaded状态。一旦组件正在使用的资源遭抢占,组件释放资源再进入WaitForResource状态等待该资源可用。

2 系统架构

2.1 系统框架

图2是以OpenMAX部分组件为例的资源管理器框架示意图,图的右侧根据不同类型的Codec对协处理器资源进行划分,不同的Codec在运行时用到对应的资源。左侧罗列了常用的OpenMAX编解码组件,并根据组件种类分成4组,同一组内的组件在运行时会用到相同的资源。例如,FR编码和AMR编码均会用到音频编码的数据段和程序段,当这两个组件同时申请资源时就会发生资源冲突。

图1 OpenMAX IL API软件全貌Fig.1 OpenMAX IL API software landscape

图2 系统框架Fig.2 System framework

2.2 系统需求

资源管理器目前维护多个组件对一个互斥资源的访问,即在系统出现多个组件同时需要占用一个资源的情况下,根据组件的优先级进行资源的分配。每个组件由IL Client设置一个优先级值,当比较两个含有相同优先级值的组件时,新近注册等待该资源的组件的优先级高于较长时间前注册的组件。如下是资源管理器需在相应情形下应完成的相应功能:

(1)资源空闲时,组件发起资源请求:组件获得资源。

(2)低优先级的组件正占用资源时,高优先级组件发起资源请求:通知低优级组件资源将被抢占,等待低优先级组件释放资源,低优先级组件释放资源后可根据需要选择是否进入资源等待队列,高优先级组件获得资源。

(3)高优先级的组件正占用资源时,低优先级组件发起资源请求:通知低优先级组件资源不可用,上层将组件注册进入资源等待队列,在资源可用的时候得到通知。

(4)接受组件释放资源。

(5)当组件使用资源完毕时,资源等待队列为空:资源释放后不做其他操作。

(6)当组件使用资源完毕,资源等待队列不为空:资源释放后,找到资源等待队列中优先级最高的组件,知组件资源可用。

2.3 主要流程

图3是系统发生资源的获取、抢占与恢复的主要流程,其中当前组件为正在使用资源的组件。

组件调用AcquireResource接口申请资源,如果资源空闲,组件注册为资源使用者。如果资源正在被使用,组件与当前组件进行优先级的比较,组件优先级高则资源管理器调用内部接口ReleaseResourceRequest请求当前组件释放资源,等当前组件释放完资源,组件注册为资源使用者;不然组件则调用WaitForResourceReques申请等待该资源,资源管理器响应该请求并把组件添加到等待对列中。

组件处理完任务后调用接口ReleaseResource释放资源,资源管理器查看等待队列是否有等待该资源的组件,没有则进行反初始化,有则调用内部接口WaitForResourceResponse给优先级最高的组件,通知其资源可用,并把它注册为资源使用者。

图3 系统流程图Fig.3 System flow chart

3 资源管理器实现

3.1 内部数据定义

资源对象与资源管理器对象是资源管理器最主要的两个数据结构体。资源对象记录了资源名称,资源使用者指针等数据,资源管理器通过此结构体实现对资源的操作。资源管理器对象维护了一张可用资源链表。

3.1.1 资源对象

3.1.2 资源管理器

3.2 接口实现

组件到资源管理器的交互通过接口函数,资源管理器到组件通信通过消息传递。接口函数内部既可以用函数执行直接实现,也可通过消息机制实现,资源管理器主要基于直接执行模式。

3.2.1 资源管理器操作相关接口

资源管理器操作主要完成资源管理器和资源的创建删除以及信息查询等。在实现中,在资源管理器操作类接口的访问不做保护,这些保护主要涉及到rm_Deinit()和rm_DeleteResource(),即在进行资源销毁之前不对资源当前的状态做任何检查,同时对这两个函数与组件调用类接口之间也不做互斥访问保护。这样,就要求rm_Deinit()和rm_DeleteResource()的调用时机由调用者确认,即保证没有任何组件使用或注册资源的时候进行操作。主要包括以下函数;

rm_Init()创建一个资源管理器,初始化并返回句柄,需确保可重复调用。

rm_Deinit()释放资源管理器中的所有资源,并最终释放资源管理器。在释放资源时,会通知所有关联的组件释放该资源。

rm_AddResource()为资源管理器增加一个资源。

rm_DeleteResource()删除资源管理器中的一个资源。该函数对被释放资源不做任何检查,在调用该函数前需要确保资源已经被所有相关组件释放,否则该函数释放资源后相关组件会发生不可预知后果。

3.2.2 组件调用接口

所有组件调用函数都会对等待列表进行操作,检查等待者队列,如果等待者符合执行条件,就会被加为使用者。以下组件调用接口是在组件资源操作过程中频繁使用的接口,通过互斥量pRsrc->mtxOp,保证互斥访问。

rm_AcquireResource():请求一个资源,可设定抢占超时,抢占在规定时间内无法完成,则资源请求失败。函数工作流程:

rm_ReleaseResourceResponse():抢占请求时,被抢占组件释放指定的资源,在实现中,该接口的功能可以统一到rm_ReleaseResource(),但为了兼容性该接口仍保留,实质上调用这两接口没有区别。

3.2.3 组件回调函数

回调函数完成从资源管理器向组件的通信。由于回调函数在资源管理器的线程中执行,因此它必须是非阻塞的,所有需要延迟处理的工作一般需要在回调函数中通过向组件发送事件的方式完成。每个资源资源管理器维护一组组件回调函数指针和对应用户指针,组件回调包括以下两个:

ReleaseResourceRequest():它向OpenMAX组件发送释放资源消息[5],通知组件应当让出当前资源(给更高优先级组件使用),OpenMAX组件的消息线程根据消息调用rm_ReleaseResource()来释放资源。函数实现:

WaitForResourceResponse():penMAX发送事件通知处于等待资源状态的组件资源可以使用,组件消息线程根据事件初始化等待资源的组件,进行相关处理。

3.2.4 内部实现函数

内部实现函数主要供组件调用函数调用,主要函数如下:

InsertClient():用于在组件链表(RM_LIST类型)中添加一个组件。

RemoveClient():用于根据组件单元指针(RM_CLIENT*)类型组件链表中删除一个组件。

Serve()[6]:维护资源,被组件接口调用,执行组件pUser指针为空,则从等待链表中提取最高优先级的组件作为pUser;当执行组件pUser的优先级低于等待链表中最高优先级组件则进行抢占。函数工作

流程如下;

4 测试分析

通过测试用例对资源获取,抢占及恢复进行测试,测试其功能性,规范性及正确性。

4.1 测试环境[7]

在ADS环境下编译包含资源管理器和相关测试组件的测试工程,并通过TRACE将代码下载到EVB板上。硬件配置:EVB板,横河仿真器。软件配置:ADS1.2,TRACE32

4.2 测试用例

资源的获取,抢占等操作是在组件进行状态转换过程中,通过组件消息线程调用资源管理器接口进行,资源管理器一旦成功完成相关的操作,线程就会释放事件信号量,如果资源管理器操作失败系统就会死在线程里。测试用例的原理就是两个组件先后申请资源,通过在等待事件信号量后加LOG打印函数TEST_CRIT来反映系统运行情况,从而体现资源管理器的相关操作是否成功。测试用例代码如下:

4.3 测试结果

测试结果如图4所示。

4.4 结果分析

结果显示组件能顺利的进行状态的转换,表明资源管理器能成功进行资源的调配。但发现当组件正在处理帧数据时,发生资源被其他组件抢占,会导致当前帧的处理出现错误并丢弃。为了防止这种情况的出现,在系统中增加一个互斥量[8]将数据处理过程与抢占过程进行互斥。组件调用获取资源接口前,先申请该互斥量,完成后续工作之后再释放该互斥量,使用这种方法来可以保证抢占时数据处理的正确性。

图4 测试结果Fig.4 The result of test

5 结 论

目前,组件发生资源冲突时,通过该资源管理器OpenMAX用户可以接收到相应的消息事件,自动完成资源的调度,从而解决资源冲突问题。该方法思路简单清晰,易于实现。但当出现资源与资源、资源与组件之间关系比较复杂,不能表现出简单的互斥性时,例如,音频解码空间可能需要占用音频编码空间或者视频解码空间时,音频解码空间资源与音频编码空间资源就不能表现出简单的互斥性,这时将需要用到内存复用技术[9],对资源的管理也会有更高的要求。资源管理器的后续设计需要对这方面的扩展问题做充分考虑。

[1] The Khronos Group Inc.OpenMAXTMintegration layer application programming interface specification[M].New York:The Khronos Group Inc,2008.

[2] Packet Video Corporation.OMX core integration guide[M].New York:Packet Video Corporation,2009.

[3] The Khronos Group Inc.OpenMAXTMweb site[EB/OL].[2010-03-01].http:∥www.khronos.org/openmax

[4] The Khronos Group Inc.Embedded system[EB/OL].[2010-02-01].http:∥en.wikipedia.org/wiki/Embedded_system

[5] Packet Video Corporation.Guide to supplying decoder buffers from the MIO component[M].New York:Packet Video Corporation,2008.

[6] Packet Video Corporation.OMX core integration guide[M].New York:Packet Video Corporation,2009.

[7] Packet Video Corporation.OpenMax call sequences[M].New York:Packet Video Corporation,2009.

[8] ITRI.EMDMA controller user manual[M].New York:ITRI,2008.

[9] REEK K A.Pointers on C[M].New York:Pearson Education Press,1998.

猜你喜欢

调用音频组件
无人机智能巡检在光伏电站组件诊断中的应用
新型碎边剪刀盘组件
U盾外壳组件注塑模具设计
核电项目物项调用管理的应用研究
必须了解的音频基础知识 家庭影院入门攻略:音频认证与推荐标准篇
LabWindows/CVI下基于ActiveX技术的Excel调用
基于Daubechies(dbN)的飞行器音频特征提取
音频分析仪中低失真音频信号的发生方法
基于系统调用的恶意软件检测技术研究
Pro Tools音频剪辑及修正