賀靜海,華云松
(上海理工大學(xué) 光電信息與計(jì)算機(jī)工程學(xué)院,上海 200093)
目前常采用基于OpenMAX標(biāo)準(zhǔn)接口與多媒體協(xié)處理器的多媒體解決方案,來(lái)開(kāi)發(fā)手機(jī)多媒體功能,上層應(yīng)用通過(guò)OpenMAX組件在協(xié)處理器中運(yùn)行相關(guān)Codec,處理數(shù)據(jù)。這種常用的解決方案的優(yōu)點(diǎn)是:移植性高,設(shè)計(jì)周期短,成本低;缺點(diǎn)是:受協(xié)處理器內(nèi)存限制,無(wú)法同時(shí)運(yùn)行所有Codec,若多個(gè)組件同時(shí)申請(qǐng)資源時(shí),就會(huì)產(chǎn)生資源沖突,影響系統(tǒng)運(yùn)行,甚至發(fā)生死機(jī)。
針對(duì)上述目前常用方案的缺點(diǎn),文中提出的解決方法基于OpenMAX流程規(guī)范,根據(jù)Codec類(lèi)型將協(xié)處理器內(nèi)存資源劃分為音頻解碼、音頻編碼、視頻解碼、視頻編碼4種不同運(yùn)行空間(數(shù)據(jù)和指令空間),并對(duì)其進(jìn)行管理及維護(hù),為OpenMAX組件進(jìn)行資源獲取、釋放、搶占等操作行為提供接口。在多組件同時(shí)訪(fǎng)問(wèn)協(xié)處理器資源時(shí),根據(jù)組件優(yōu)先級(jí)對(duì)資源實(shí)施實(shí)時(shí)仲裁,實(shí)現(xiàn)資源被單一組件互斥使用,完成系統(tǒng)并發(fā)需求。
OpenMAX[1]是由Khronos制定的多媒體應(yīng)用程序標(biāo)準(zhǔn)接口,主要針對(duì)嵌入式設(shè)備或移動(dòng)設(shè)備,在架構(gòu)底層上為多媒體Codec和數(shù)據(jù)處理定義了一套統(tǒng)一的編程接口(OpenMAX IL API),對(duì)多媒體數(shù)據(jù)的處理功能進(jìn)行系統(tǒng)級(jí)抽象,為用戶(hù)屏蔽了底層的細(xì)節(jié)。圖1是OpenMAX IL API軟件全貌,OpenMAX IL API有個(gè)高層實(shí)體,稱(chēng)為IL客戶(hù)端(IL client),該客戶(hù)端通常是一個(gè)filter graph多媒體框架或者應(yīng)用程序的一個(gè)功能片,IL client通過(guò)OpenMAX組件調(diào)用OpenMAX IL API可以以一種統(tǒng)一的方式來(lái)使用Codec和其他多媒體數(shù)據(jù)處理功能,無(wú)需擔(dān)心其底層的硬件結(jié)構(gòu)。
OpenMAX組件代表一個(gè)具體的功能模塊,可以是文件解析組件,也可以是編解碼組件等。OpenMAX組件有Loaded,Idle,Executin與WaitingForResource等6種狀態(tài)。每個(gè)組件最開(kāi)始處于Loaded狀態(tài),當(dāng)組件開(kāi)始執(zhí)行任務(wù)時(shí),先轉(zhuǎn)到Idle狀態(tài),這時(shí)需要獲取資源,如果獲取資源失敗,則轉(zhuǎn)入WaitingForResource狀態(tài),之后從Idle狀態(tài)轉(zhuǎn)入Executing狀態(tài)開(kāi)始執(zhí)行任務(wù),當(dāng)執(zhí)行完任務(wù)時(shí),組件釋放資源并轉(zhuǎn)入Loaded狀態(tài)。一旦組件正在使用的資源遭搶占,組件釋放資源再進(jìn)入WaitForResource狀態(tài)等待該資源可用。
圖2是以O(shè)penMAX部分組件為例的資源管理器框架示意圖,圖的右側(cè)根據(jù)不同類(lèi)型的Codec對(duì)協(xié)處理器資源進(jìn)行劃分,不同的Codec在運(yùn)行時(shí)用到對(duì)應(yīng)的資源。左側(cè)羅列了常用的OpenMAX編解碼組件,并根據(jù)組件種類(lèi)分成4組,同一組內(nèi)的組件在運(yùn)行時(shí)會(huì)用到相同的資源。例如,F(xiàn)R編碼和AMR編碼均會(huì)用到音頻編碼的數(shù)據(jù)段和程序段,當(dāng)這兩個(gè)組件同時(shí)申請(qǐng)資源時(shí)就會(huì)發(fā)生資源沖突。
圖1 OpenMAX IL API軟件全貌Fig.1 OpenMAX IL API software landscape
圖2 系統(tǒng)框架Fig.2 System framework
資源管理器目前維護(hù)多個(gè)組件對(duì)一個(gè)互斥資源的訪(fǎng)問(wèn),即在系統(tǒng)出現(xiàn)多個(gè)組件同時(shí)需要占用一個(gè)資源的情況下,根據(jù)組件的優(yōu)先級(jí)進(jìn)行資源的分配。每個(gè)組件由IL Client設(shè)置一個(gè)優(yōu)先級(jí)值,當(dāng)比較兩個(gè)含有相同優(yōu)先級(jí)值的組件時(shí),新近注冊(cè)等待該資源的組件的優(yōu)先級(jí)高于較長(zhǎng)時(shí)間前注冊(cè)的組件。如下是資源管理器需在相應(yīng)情形下應(yīng)完成的相應(yīng)功能:
(1)資源空閑時(shí),組件發(fā)起資源請(qǐng)求:組件獲得資源。
(2)低優(yōu)先級(jí)的組件正占用資源時(shí),高優(yōu)先級(jí)組件發(fā)起資源請(qǐng)求:通知低優(yōu)級(jí)組件資源將被搶占,等待低優(yōu)先級(jí)組件釋放資源,低優(yōu)先級(jí)組件釋放資源后可根據(jù)需要選擇是否進(jìn)入資源等待隊(duì)列,高優(yōu)先級(jí)組件獲得資源。
(3)高優(yōu)先級(jí)的組件正占用資源時(shí),低優(yōu)先級(jí)組件發(fā)起資源請(qǐng)求:通知低優(yōu)先級(jí)組件資源不可用,上層將組件注冊(cè)進(jìn)入資源等待隊(duì)列,在資源可用的時(shí)候得到通知。
(4)接受組件釋放資源。
(5)當(dāng)組件使用資源完畢時(shí),資源等待隊(duì)列為空:資源釋放后不做其他操作。
(6)當(dāng)組件使用資源完畢,資源等待隊(duì)列不為空:資源釋放后,找到資源等待隊(duì)列中優(yōu)先級(jí)最高的組件,知組件資源可用。
圖3是系統(tǒng)發(fā)生資源的獲取、搶占與恢復(fù)的主要流程,其中當(dāng)前組件為正在使用資源的組件。
組件調(diào)用AcquireResource接口申請(qǐng)資源,如果資源空閑,組件注冊(cè)為資源使用者。如果資源正在被使用,組件與當(dāng)前組件進(jìn)行優(yōu)先級(jí)的比較,組件優(yōu)先級(jí)高則資源管理器調(diào)用內(nèi)部接口ReleaseResourceRequest請(qǐng)求當(dāng)前組件釋放資源,等當(dāng)前組件釋放完資源,組件注冊(cè)為資源使用者;不然組件則調(diào)用WaitForResourceReques申請(qǐng)等待該資源,資源管理器響應(yīng)該請(qǐng)求并把組件添加到等待對(duì)列中。
組件處理完任務(wù)后調(diào)用接口ReleaseResource釋放資源,資源管理器查看等待隊(duì)列是否有等待該資源的組件,沒(méi)有則進(jìn)行反初始化,有則調(diào)用內(nèi)部接口WaitForResourceResponse給優(yōu)先級(jí)最高的組件,通知其資源可用,并把它注冊(cè)為資源使用者。
圖3 系統(tǒng)流程圖Fig.3 System flow chart
資源對(duì)象與資源管理器對(duì)象是資源管理器最主要的兩個(gè)數(shù)據(jù)結(jié)構(gòu)體。資源對(duì)象記錄了資源名稱(chēng),資源使用者指針等數(shù)據(jù),資源管理器通過(guò)此結(jié)構(gòu)體實(shí)現(xiàn)對(duì)資源的操作。資源管理器對(duì)象維護(hù)了一張可用資源鏈表。
3.1.1 資源對(duì)象
3.1.2 資源管理器
組件到資源管理器的交互通過(guò)接口函數(shù),資源管理器到組件通信通過(guò)消息傳遞。接口函數(shù)內(nèi)部既可以用函數(shù)執(zhí)行直接實(shí)現(xiàn),也可通過(guò)消息機(jī)制實(shí)現(xiàn),資源管理器主要基于直接執(zhí)行模式。
3.2.1 資源管理器操作相關(guān)接口
資源管理器操作主要完成資源管理器和資源的創(chuàng)建刪除以及信息查詢(xún)等。在實(shí)現(xiàn)中,在資源管理器操作類(lèi)接口的訪(fǎng)問(wèn)不做保護(hù),這些保護(hù)主要涉及到rm_Deinit()和rm_DeleteResource(),即在進(jìn)行資源銷(xiāo)毀之前不對(duì)資源當(dāng)前的狀態(tài)做任何檢查,同時(shí)對(duì)這兩個(gè)函數(shù)與組件調(diào)用類(lèi)接口之間也不做互斥訪(fǎng)問(wèn)保護(hù)。這樣,就要求rm_Deinit()和rm_DeleteResource()的調(diào)用時(shí)機(jī)由調(diào)用者確認(rèn),即保證沒(méi)有任何組件使用或注冊(cè)資源的時(shí)候進(jìn)行操作。主要包括以下函數(shù);
rm_Init()創(chuàng)建一個(gè)資源管理器,初始化并返回句柄,需確??芍貜?fù)調(diào)用。
rm_Deinit()釋放資源管理器中的所有資源,并最終釋放資源管理器。在釋放資源時(shí),會(huì)通知所有關(guān)聯(lián)的組件釋放該資源。
rm_AddResource()為資源管理器增加一個(gè)資源。
rm_DeleteResource()刪除資源管理器中的一個(gè)資源。該函數(shù)對(duì)被釋放資源不做任何檢查,在調(diào)用該函數(shù)前需要確保資源已經(jīng)被所有相關(guān)組件釋放,否則該函數(shù)釋放資源后相關(guān)組件會(huì)發(fā)生不可預(yù)知后果。
3.2.2 組件調(diào)用接口
所有組件調(diào)用函數(shù)都會(huì)對(duì)等待列表進(jìn)行操作,檢查等待者隊(duì)列,如果等待者符合執(zhí)行條件,就會(huì)被加為使用者。以下組件調(diào)用接口是在組件資源操作過(guò)程中頻繁使用的接口,通過(guò)互斥量pRsrc->mtxOp,保證互斥訪(fǎng)問(wèn)。
rm_AcquireResource():請(qǐng)求一個(gè)資源,可設(shè)定搶占超時(shí),搶占在規(guī)定時(shí)間內(nèi)無(wú)法完成,則資源請(qǐng)求失敗。函數(shù)工作流程:
rm_ReleaseResourceResponse():搶占請(qǐng)求時(shí),被搶占組件釋放指定的資源,在實(shí)現(xiàn)中,該接口的功能可以統(tǒng)一到rm_ReleaseResource(),但為了兼容性該接口仍保留,實(shí)質(zhì)上調(diào)用這兩接口沒(méi)有區(qū)別。
3.2.3 組件回調(diào)函數(shù)
回調(diào)函數(shù)完成從資源管理器向組件的通信。由于回調(diào)函數(shù)在資源管理器的線(xiàn)程中執(zhí)行,因此它必須是非阻塞的,所有需要延遲處理的工作一般需要在回調(diào)函數(shù)中通過(guò)向組件發(fā)送事件的方式完成。每個(gè)資源資源管理器維護(hù)一組組件回調(diào)函數(shù)指針和對(duì)應(yīng)用戶(hù)指針,組件回調(diào)包括以下兩個(gè):
ReleaseResourceRequest():它向OpenMAX組件發(fā)送釋放資源消息[5],通知組件應(yīng)當(dāng)讓出當(dāng)前資源(給更高優(yōu)先級(jí)組件使用),OpenMAX組件的消息線(xiàn)程根據(jù)消息調(diào)用rm_ReleaseResource()來(lái)釋放資源。函數(shù)實(shí)現(xiàn):
WaitForResourceResponse():penMAX發(fā)送事件通知處于等待資源狀態(tài)的組件資源可以使用,組件消息線(xiàn)程根據(jù)事件初始化等待資源的組件,進(jìn)行相關(guān)處理。
3.2.4 內(nèi)部實(shí)現(xiàn)函數(shù)
內(nèi)部實(shí)現(xiàn)函數(shù)主要供組件調(diào)用函數(shù)調(diào)用,主要函數(shù)如下:
InsertClient():用于在組件鏈表(RM_LIST類(lèi)型)中添加一個(gè)組件。
RemoveClient():用于根據(jù)組件單元指針(RM_CLIENT*)類(lèi)型組件鏈表中刪除一個(gè)組件。
Serve()[6]:維護(hù)資源,被組件接口調(diào)用,執(zhí)行組件pUser指針為空,則從等待鏈表中提取最高優(yōu)先級(jí)的組件作為pUser;當(dāng)執(zhí)行組件pUser的優(yōu)先級(jí)低于等待鏈表中最高優(yōu)先級(jí)組件則進(jìn)行搶占。函數(shù)工作
流程如下;
通過(guò)測(cè)試用例對(duì)資源獲取,搶占及恢復(fù)進(jìn)行測(cè)試,測(cè)試其功能性,規(guī)范性及正確性。
在ADS環(huán)境下編譯包含資源管理器和相關(guān)測(cè)試組件的測(cè)試工程,并通過(guò)TRACE將代碼下載到EVB板上。硬件配置:EVB板,橫河仿真器。軟件配置:ADS1.2,TRACE32
資源的獲取,搶占等操作是在組件進(jìn)行狀態(tài)轉(zhuǎn)換過(guò)程中,通過(guò)組件消息線(xiàn)程調(diào)用資源管理器接口進(jìn)行,資源管理器一旦成功完成相關(guān)的操作,線(xiàn)程就會(huì)釋放事件信號(hào)量,如果資源管理器操作失敗系統(tǒng)就會(huì)死在線(xiàn)程里。測(cè)試用例的原理就是兩個(gè)組件先后申請(qǐng)資源,通過(guò)在等待事件信號(hào)量后加LOG打印函數(shù)TEST_CRIT來(lái)反映系統(tǒng)運(yùn)行情況,從而體現(xiàn)資源管理器的相關(guān)操作是否成功。測(cè)試用例代碼如下:
測(cè)試結(jié)果如圖4所示。
結(jié)果顯示組件能順利的進(jìn)行狀態(tài)的轉(zhuǎn)換,表明資源管理器能成功進(jìn)行資源的調(diào)配。但發(fā)現(xiàn)當(dāng)組件正在處理幀數(shù)據(jù)時(shí),發(fā)生資源被其他組件搶占,會(huì)導(dǎo)致當(dāng)前幀的處理出現(xiàn)錯(cuò)誤并丟棄。為了防止這種情況的出現(xiàn),在系統(tǒng)中增加一個(gè)互斥量[8]將數(shù)據(jù)處理過(guò)程與搶占過(guò)程進(jìn)行互斥。組件調(diào)用獲取資源接口前,先申請(qǐng)?jiān)摶コ饬?,完成后續(xù)工作之后再釋放該互斥量,使用這種方法來(lái)可以保證搶占時(shí)數(shù)據(jù)處理的正確性。
圖4 測(cè)試結(jié)果Fig.4 The result of test
目前,組件發(fā)生資源沖突時(shí),通過(guò)該資源管理器OpenMAX用戶(hù)可以接收到相應(yīng)的消息事件,自動(dòng)完成資源的調(diào)度,從而解決資源沖突問(wèn)題。該方法思路簡(jiǎn)單清晰,易于實(shí)現(xiàn)。但當(dāng)出現(xiàn)資源與資源、資源與組件之間關(guān)系比較復(fù)雜,不能表現(xiàn)出簡(jiǎn)單的互斥性時(shí),例如,音頻解碼空間可能需要占用音頻編碼空間或者視頻解碼空間時(shí),音頻解碼空間資源與音頻編碼空間資源就不能表現(xiàn)出簡(jiǎn)單的互斥性,這時(shí)將需要用到內(nèi)存復(fù)用技術(shù)[9],對(duì)資源的管理也會(huì)有更高的要求。資源管理器的后續(xù)設(shè)計(jì)需要對(duì)這方面的擴(kuò)展問(wèn)題做充分考慮。
[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.