======================================================================================================
轉載請註明原文地址:http://blog.csdn.net/crushonme/article/details/10245169
=======================================================================================================
Netra(DM8168)處理器是個多核處理器,每個核之間相互獨立卻又相互關聯,如何高效簡潔地利用每個核完成一套系統功能是非常關鍵的,RDK這套軟件平臺就是針對這種多核平臺設計的一套多通道視頻應用方案,主要用於DVR、NVR、IPNC之類的產品。
這個軟件框架結構允許用戶創建不同的多路數據流來實現視頻的採集、視頻處理(DEI、Noise Filter、Encode、Decode、SwMs、Merge等)和視頻播放功能,其框架設計非常值得學習。
以下爲相關縮寫解釋:
*****************************************************************************************************
HDVPSS:High Definition Video Processing Subsystem
HDVICP:High Definition Video and Image CoProcessor
Ducati:Dual Core M3 Processors controlling HDVPSS and HDVICP hardware engines
Video M3:ARM Cortex M3 Core(inside Ducati subSystem)controlling HDVICP codecs
VPSS M3:ARM Cortex M3 Core(inside Ducati subSystem)controlling HDVPSS,also called DSS M3
DEI:Deinterlacer
McFW:Multi Channel Framework
IPC:Inter Processor Communication
******************************************************************************************************
1、Rdk平臺軟件框架圖
在Rdk平臺軟件中做了很好的分層,如下圖所示:
注意:上圖中核間通過Syslink/IPC通信,任意2個核之間都可以直接通信,是一個星型網絡,上圖畫的連接關係描述的是對等層次的概念。
上圖中相關層的功能及相關描述如下表所示:
層 | 處理器 | 描述 | 相關TI軟件包 |
Linux | HOST A8 |
Linux OS, includes, filesystems, SATA, Ethernet, USB and other IO drivers |
Linux PSP |
BIOS6 |
VPSS M3 Video M3 DSP |
BIOS RTOS used as OS on Video-M3, VPSS-M3, DSP. Provides features like threads, semaphores, interrupts. Queues and message passing between links is implemented using BIOS semaphores. |
BIOS XDC (used for BIOS and other configuration) |
Syslink / IPC |
HOST A8 VPSS M3 Video M3 DSP |
Software APIs used for communicating between processors. Provides features like processor loading and booting, multiprocessor heaps, multiprocessor linked list (ListMP), message queues, notify etc |
Syslink IPC |
HDVPSS Drivers |
VPSS M3 |
HDVPSS drivers like capture, display, deinterlacer, scaling based on FVID2 interface to control and configure the HDVPSS HW |
HDVPSS |
Video Encode/Decode |
Video M3 |
Video encode / decode APIs based on XDM / XDIAS interface. Uses framework components for resource allocation |
XDIAS Framework components IVAHD HDVICP2 API H264 decoder H264 encoder |
Links |
Links HOST A8 VPSS M3 Video M3 DSP |
Implementation of individual links. Some links are specific to a processor while some links are common across processors |
DVR RDK |
Link API | HOST A8 |
The link API allows users to create , connect, and control links on HOSTA8, VPSS M3, Video M3 and DSP. Link API is used to create a chain of links which forms a user defined use-case. The connection of links to each other is platform dependant. |
McFW |
McFW API | HOST A8 |
Multi-Channel FrameWork API. Multi-Channel Application specific API which allows user to setup and control pre-defined application specific chains for DVR, NVR, using a single simplified API interface. This allows users to directly use the links without having to understand the detailed link API. The McFW API is platform independent and same API will work on DM816x, DM814x, DM810x |
McFW |
User Application |
HOST A8 |
Typically GUI and other application specific components like file read/write, network streaming. |
Customer specific |
2、基於Rdk框架的實例
Capture (YUV422I) 16CH D1 60fps
|
NSF (YUV420SP)
|
dup1---->IPCM3OUT(VPS) -> IPCM3IN(VID) -> ENC -> IPC_BITS_OUT_M3 -> IPC_BITS_IN_A8 -> fwrite() - Write to filesystem
| !
| !
+-<----IPCM3IN(VPS) <- IPCM3OUT(VID) -> DEC <- IPC_BITS_IN_M3 <- IPC_BITS_OUT_A8 <- fread() - read from harddisk
|
MERGE
|
DUP2
|||
+--------+|+------------+
| | |
| | |
SW Mosaic SW Mosaic SW Moasic
(DEIH YUV422I) (DEI YUV422I) (SC5 YUV422I)
| | |
GRPX0 | GRPX1,2 | |
| | | | |
On-Chip HDMI Off-Chip HDMI SDTV (NTSC)
1080p60 1080p60 480i60
3、Link Api機制
3.1 link api的概念
link在上圖中的視頻數據流中是最基本的單元模塊,每個link中包含了一個基於BIOS6/Linux的任務、線程、消息盒(使用操作系統的信號量實現)。由於每個link運行一個獨立的現成,因此link之間可以並行運行。消息盒是關聯用戶指定的link,讓link之間有個互相對話的機制,用來傳遞信令。而對於視頻流數據、幀數據的傳遞link實現了專門的接口來實現,只傳遞指針,而不是數據。
在實現上節所介紹的數據流可以通過將多個link連接來實現chain,link API允許用戶Create、Start、Stop、Delete、Control各個link。在Rdk中TI基於link API進行再次封裝,用於特定的應用場合,其各種參數均是爲特定的產品定製,可以是相關業務的開發更迅速。
3.2 link內部結構
3.3 link的特性
- 視頻處理的工作量可以均衡到每個核心上去執行,如下表:
Processor |
OS |
Used for |
HOST A8 | Linux | System setup and control, GUI, IO peripheral control like SATA, Ethernet, USB, Audio |
VPSS M3 | BIOS6 |
HDVPSS control for video capture, video display, scaling, deInterlacing … |
Video M3 | BIOS6 | HDVICP2 Video compression / decompression (H264 encode, H264 decode) |
DSP | BIOS6 | SW OSD, custom video processing algorithms |
- 每個link都有自己獨立的任務/線程用於完成視頻採集或播放等處理;
- 每個link都可以處理來自多個通道的視頻幀數據,每個通道的視頻寬高和數據格式都可以不同;
- A8作爲HOST可以用來連接多個link形成數據流的鏈並對其進行控制;
- 數據鏈被建立並啓動時,數據鏈中的每個link將和它的下游link進行幀數據的交互;
- links之間的幀數據交互可以在多個核心之間進行,並且並不需要A8 HOST的干涉,從而降低A8的開銷;
- 在數據鏈運行過程中用戶可以發送控制信令給任意link來動態設置相關的link參數;
3.4 link接口
link接口可以分成以下幾類:
- link API——被用戶調用來配置和控制link的接口;
- Inter link API——被其他links調用來交換幀數據的接口;
- link output queue——被其他links通過Inter Link API接口實用的幀buffer隊列;
3.5 link間的消息傳遞
每個Link通過一個32位的該LinkId來識別,ID高4位標識了這個Link是在哪個核上運行,低24位標識了該Link的名稱:
Bits | Description |
[0..27] | Link ID |
[28..31] | Processor ID on which this link runs 0:DSP 1:Video M3 2:VPSS M3 |
每個Link API都需要這個LinkID參數來發送消息,當用戶發送消息到一個Link時,根據這ID函數內部判斷這個消息是發給本地的Link還是遠端核心的Link;如果是本地的直接調用BIOS/LINUX API函數,否則就通過Syslink模塊的MessageQ發送這個消息到指定的核心,讓對端的核心調用對應的函數處理。
3.6 link API
下面將通過表格的形式來看看link API的部分接口及相關功能:
API | Description |
System_linkCreate | Creates a link ——allocates driver, codec, memory resources. |
System_linkGetInfo | Get information about a link like number of channels, properties of each channel. MUST be called after System_linkCreate() for a link |
System_linkStart | Start the link ——starts the driver or codec |
System_linkControl | Send a link specific control command with optional arguments |
System_linkStop | Stop the link —— stops the driver or codec |
System_linkDelete | Deletes a link —— free’s driver, codec, memory resources |
3.7 Inter link API
下面的表格介紹了在link內部實現的交換幀數據的API,對於用戶來說,這部分API是不需要關心的:
API | Description |
System_GetLinkInfoCb | Function to return information about a link like number of channels, properties of each channel |
System_LinkGetOutputFramesCb |
Function to return captured or generated or output frames to the caller (another link) |
System_LinkPutEmptyFramesCb | Function to release consumed frames back to the original link for reuse |
System_LinkGetOutputBitBufsCb | Function to return generated or output bitstream frame to the caller (another link) –Valid only for Encode Link |
System_LinkPutEmptyBitBufsCb | Function to release consumed bitstream frames back to the original link for reuse –Valid only for Encode Link |
在每個link中必須實現一些函數並在初始化時註冊這些函數指針給link管理的核心模塊,用於幀數據的獲取、釋放、dump相關狀態等。
對於任一個link想從它的上游link獲取幀數據都需要調用link管理核心函數System_getLinksFullFrames(),該函數內部會發送消息到對應的上游link,觸發該link向管理模塊註冊的回調函數System_LinkGetOutputFramesCb()將幀數據傳遞給該link;
同樣的,在當一個link想釋放處理完畢的幀buffer給上游link時需要調用link管理核心函數System_putLinksEmptyFrames(),該函數內部會發送消息到對應的上游link,觸發它註冊的回調函數System_LinkPutEmptyFramesCb()將幀buffer回收,用於後續的數據處理;
通過上述的方法,對於一個link來說就不需要關心和它交互的是哪一個link,所有的尋址都通過linkID來自動查找,並且同一個link實現可以和不同的link交互,而不需要改變函數的實現。
3.8 Link Output Queues 的管理
一個Link可以有一個或多個輸出隊列用來存放採集到的或處理完畢的幀數據,每個Link的輸出隊列內存由自己分配;
大多數Links只有一個輸出隊列,但是有些link有多個,從而可以實現多路不同的輸出數據流滿足不同的應用需求,例如,Noise filter Link可以輸出16路幀數據到2個輸出隊列,每個輸出隊列輸出8路通道數據跟別給2個DEI Links模塊處理。
一個輸出隊列中可以有多個視頻channels的數據,每個channel可以有不同的大小和數據格式;
數據結構 FVID2_Frame是在VPSS驅動中定義的,Links之間就通過該結構參數傳遞幀數據的信息,如幀數據的Buf指針,而幀數據本身並不會被拷貝,從而節省內存開銷;
當一個Link採集完或處理完一幀數據後會發送一個消息“SYSTEM_CMD_NEW_DATA”給下游的Link,從而通知它有數據可取;當下遊Link收到該消息後會調用System_getLinksFullFrames()函數來獲取對用的幀數據,處理完後再調用System_putLinksEmptyFrames()函數來歸還給上游Link繼續使用。
因此一個Link需要知道:
- 上游Link的LinkID和QueID,從而從該隊列裏面獲取幀數據
- 下游LinkID,從而在有新數據產生時通知下游Link來取
3.9 IPC link核間幀數據交互
IPC Link,是用來多核之間的幀數據傳遞的。
如VPSS上的採集Link想把幀數據發送給Video Link處理,先將幀數據傳遞給本地的IPC Link,然後IPC Link再通過Syslink/IPC發送到Video Link上的IPC Link,然後再轉發給Video Link,這樣的話對於採集Link的實現來說就非常清晰簡單,它的實現都是發送給本地的另一個Link;
IPC Link的實現有點複雜,因爲它涉及的幀數據傳遞是在多個核之間,這裏面就牽扯到cache的一致性問題,考慮到每個核的特性以及高效性,總共設計了3個內部Links用於幀數據的傳遞機制:
- Intra-processor links
即同一核心內部的link,如採集à降噪處理,都是在VPSS M3內部完成,採用簡單且高效的隊列機制實現。
- Inter M3 (Video / VPSS) links
即M3內部核心之間的link,由於Video和Vpss所在的2個M3核心是同屬於一個雙核M3處理器,它們的cache是共享的;如降噪(VPSS NF)à編碼(VIDEO Enc),採用Notify機制的IPC ListMP被用來在2個M3核心之間傳遞幀信息(FVID2_Frame),不需要任何cache操作和地址轉換。
- Inter processor (M3 to A8 or DSP)
即處理器內部核心之間,如編碼(VideoM3)àBitStream In(HostA8),採用Notify機制的IPC ListMP被用來在2個核心之間傳遞幀信息(FVID2_Frame)需要cache同步和地址轉換操作。
4、chain數據鏈路的建立
一個Chain是由多個links按照一定的應用需求按順序連接成一條視頻處理的數據流。
一個Chain可以銷燬後重新按照新的需求組成新的Chain,不需要重啓系統。
Chain創建是特別需要相關link的順序
- 通過System_linkCreate()函數按照由source>>sink 的順序創建需要的Links,Source Link即沒有上游Link的Link,如:視頻採集;Sink Link是沒有下游Link的Link,如:視頻播放;這個創建順序是非常重要的,因爲一個Link創建時它會查詢上游Link的一些信息,如上游Link需要的channel的個數和屬性,從而按照這些參數配置自己。
- 下一步調用System_linkStart()函數啓動每個Link,啓動順序一般從Sink Link往前到Sorce Link,當然你也可以不按照這個順序,不過不推薦,因爲這樣可以保證每個Link在它的上游Link啓動前準備好接收數據,避免過多的緩衝引入額外的時延。
- 當一個Chain運行後控制命令就可以發送到各個Links來控制它,如調用System_linkControl()函數發送改變畫面合成風格的命令給相應的Link,具體的命令定義由每個Link的功能實現來決定;
- 注意:一般來說System_linkControl()函數是在System_linkCreate()創建了Link之後才能調用,不過有些控制命令可以在System_linkCreate()調用之前調用,以完成Link創建之前必須的一些初始化,如復位;
- 當Chain工作完成或銷燬時可以調用System_linkStop()函數先停止每個Link,注意:停止的順序必須從Source開始依次到Sink結束;因爲一個Link可能阻塞着等待下游Link釋放當前Link的輸出Buffer,如果下游Link先停止的話當前Link可能會出於wait for ever的狀態而永久退不出來,因此上游Link必須先停止,之後才能停止下游Link;
- 最後等所有Link全部停止後,可以調用System_linkDelete()函數刪除所有Links,刪除順序沒有要求;
- 當Chain銷燬後就可以按照之前的順序重新創建一個新的Chain來完成另一個工作了。
參考文獻:
- DVR_RDK_McFW_Link_API_Training.pdf
- DM81xx_DVR_RDK_Overview.pdf
- TI NVR RDK Source Code