Netra基於Rdk平臺的軟件框架設計

======================================================================================================

轉載請註明原文地址:http://blog.csdn.net/crushonme/article/details/10245169

=======================================================================================================

        Netra(DM8168)處理器是個多核處理器,每個核之間相互獨立卻又相互關聯,如何高效簡潔地利用每個核完成一套系統功能是非常關鍵的,RDK這套軟件平臺就是針對這種多核平臺設計的一套多通道視頻應用方案,主要用於DVRNVR、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來識別,ID4位標識了這個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路通道數據跟別給2DEI Links模塊處理。

    一個輸出隊列中可以有多個視頻channels的數據,每個channel可以有不同的大小和數據格式;

    數據結構 FVID2_Frame是在VPSS驅動中定義的,Links之間就通過該結構參數傳遞幀數據的信息,如幀數據的Buf指針,而幀數據本身並不會被拷貝,從而節省內存開銷;

    當一個Link採集完或處理完一幀數據後會發送一個消息“SYSTEM_CMD_NEW_DATA”給下游的Link,從而通知它有數據可取;當下遊Link收到該消息後會調用System_getLinksFullFrames()函數來獲取對用的幀數據,處理完後再調用System_putLinksEmptyFrames()函數來歸還給上游Link繼續使用。

因此一個Link需要知道:

  • 上游LinkLinkIDQueID,從而從該隊列裏面獲取幀數據
  • 下游LinkID,從而在有新數據產生時通知下游Link來取

上游LinkLinkIDQueID 以及下游LinkID 都是在System_linkCreate()時由A8 HOST端來指定的。


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,由於VideoVpss所在的2M3核心是同屬於一個雙核M3處理器,它們的cache是共享的;如降噪(VPSS NFà編碼(VIDEO Enc),採用Notify機制的IPC ListMP被用來在2M3核心之間傳遞幀信息(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即沒有上游LinkLink,如:視頻採集;Sink Link是沒有下游LinkLink,如:視頻播放;這個創建順序是非常重要的,因爲一個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來完成另一個工作了。



參考文獻:

  1. DVR_RDK_McFW_Link_API_Training.pdf
  2. DM81xx_DVR_RDK_Overview.pdf
  3. TI NVR RDK Source Code
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章