第四章 輸入端與輸出端模組
4.3 SVIP 模組
4.3.1 SVIP Unit
在讓 tmVcapSvip 模組能夠運作之前,必須先取得 tmVcapSvip 模組在硬體環境上的 一些資訊,例如關於 SVIP 的資料設定、A/D 晶片上的設定資訊、以及上述兩者之間的 連接關係,這些資料主要是透過 tmVcapSvip 模組中 Unit 的函式來存取,因此應用層可 以透過以下幾個 OL 層所提供的 Unit 介面函式來執行操作。
‐ tmolVcapSvipUnit_GetCapabilities( )
‐ tmolVcapSvipUnit_Open( )
‐ tmolVcapSvipUnit_GetInstanceSetup( )
‐ tmolVcapSvipUnit_InstanceSetup( )
‐ tmolVcapSvipUnit_Close( )
Unit 在應用層上函式執行的順序與一般模組相同,皆是先取得描述 Capabilities 的 資料結構,接著分配記憶體空間給 Instance 結構,取得並設定 Instance,所以接下來便 tmVdecAna_GetSupportedSources( ) 取得目前環境中所支援的輸入影像數目。
tmVdecAna_GetVideoStatus( ) 取得目前輸入影像的狀態,判斷輸入訊號是否有 被鎖住。
tmVdecAna_SetVideoStd( ) 設定影像的格式標準,例如 ntsc。
tmVdecAna_SetSourceType( ) 設定影像的型態,例如 TV、video、camera 等。
tmVdecAna_SetAcquisitionWindow( ) 設定輸入影像的視窗座標。
43
依序討論上述的函式內容,並藉由這些函式的運作流程來了解 Unit 的內容設定。
1. tmolVcapSvipUnit_GetCapabilities( )
在這個函式中主要是取得 Unit 的 Capabilities 設定,而 Unit 的 Capabilities 如圖 4.8 所示,具有三個結構成員,Default 層的 Capabilities、DL 層的 Capabilities、Unit 所 支援的 Stream 數等,除了 Default Capabilities 的值是設定在 OL 層中,可以直接連 結到位址取得資料,其餘兩個結構成員則必須到 DL 層或 BSL 層才能得到設定的資 料,因此在這部分會藉由一個 SVIP Unit 的初始化函式 SvipUnit_localInit( )來執行。
在 SVIP Unit 初始化函式 SvipUnit_localInit( )中,初始化的方式主要是藉由 DL 層以 及 BSL 層的函式來取得 SVIP 上的設定的資訊,包含了 SVIP 上的拿取影像的時脈 頻率、MMIO 的位址、輸入影像的 Stream 設定……等,並將這些取得的訊息設定 在 Unit 的資料結構中。圖 4.9 為 SvipUnit_localInit( )函式的內容,在這個函式中會 再藉由連結到三個相關的函式來執行初始化的動作,以下依序為這三個函式的內容 介紹。
typedef struct _tmolVcapSvipUnit_Capabilities_t {
ptsaDefaultCapabilities_t pDefCapabilities; //Default capabilities tmdlSvipUnit_Capabilities_t * psvipCapabilities; //DL capabilities UInt32 numberOfStreams;
} tmolVcapSvipUnit_Capabilities_t, *ptmolVcapSvipUnit_Capabilities_t;
圖 4.8 Unit Capabilities 資料結構
圖 4.9 SvipUnit_localInit()內容
static tmErrorCode_t svipUnit_localInit (tmUnitSelect_t svipUnitNumber) { // 取得可使用的 unit 數目
tmolVcapSvip_GetNumberOfUnits( );
// 取得 DL 層的 Capabilities tmdlSvipUnit_GetCapabilities( );
// 取得 VdecAna 的介面
tmolSvip_VdecGetNumberOfStreams( );
44
(1) tmolVcapSvip_GetNumberOfUnit( )
Unit 的初始化,首先必須取得硬體上可使用的 unit 數,unit 是指在 DSP 上 SVIP 所在的區塊,由於 DSP 上有兩組 SVIP,所以不論是否有使用到兩組 SVIP,取得 的 unit 數通常會是二。這部分在程式上的流程可參照圖 4.10,當 OL 層的 GetNumberOfUnit()函式被呼叫時,會連結到 DL 層的 GetNumberOfUnit()函式來 取得 unit 數,而在取得 unit 數的同時,DL 層的 dlSvipLocalInit()函式會開始對 unit 的 instance 結構做一些初始值的設定。其中部分 instance 的設定資訊與硬體相關,
例如暫存器的位址,由於這方面的資訊在 SVIP 向 tmbslCore 註冊時,已將資料 存放置 BSL 層上的一個結構中,所以 DL 層就會利用 tmbslCore 的介面函式,到 BSL 層中取得 SVIP 硬體模組的資訊。
(2) tmdlSvipUnit_GetCapabilities( )
Unit 的 Capabilities 資料結構包含了三個結構成員,分別是 Default 的 Capabilities、
DL 的 Capabilities、Unit 所支援的 Stream 數。DL 上的 Capabilities 是 tmVcapSvip 模組中對 Default Capabilities 沒提供的部分所增加的結構成員,主要內容是關於 模組版本以及 SVIP 所支援 Instance 數目的設定,而 OL 以及 DL Capabilities 的資 料結構關係則如圖 4.11 所示。其中在執行上述第一階段的 tmolVcapSvip_
GetNumberOfUnit( )函式時,DL 層的 Capabilites 資料結構已經在初始化函式 dlSvipLocalInit( )中,設定好結構成員的參數值,因此在 DL 層的 tmdlSvipUnit_
GetCapabilities()函式裡,會將已經設定好的 Capabilities 資料結構位址直接回傳給 模組的 OL 層。
OL layer
DL layer
BSL layer
tmolVcapSvip_GetNumberOfUnits()
tmdlVcapSvip_GetNumberOfUnits() dlSvipLocalInit()
tmbslCore gBslInterfaceInfo[index]
tmbslCoreGetModuleInfo(SVIP_A120_MOD_ID,...) Initialize unit instance
圖 4.10 取 unit 數的程式流程
45
(3) tmolSvip_VdecGetNumberOfStream( )
這部分主要是取得從 A/D 單元傳到入 SVIP 上的影像數量( Streams ),而 A/D 單 元的資訊存放在 tmbslCore 層裡,因此 tmVcapSvip 模組會透過 BSL 的介面函式 去取得 Stream 數的資訊,並將取得的數字設定給 OL 層 Capabilities 中存放 Stream 數的結構成員。
當執行完上述函式的內容,Unit 的初始化算是告一段落,同時 Unit Capabilities 的 資料結構也設定完成,接下來就繼續討論 Unit 另一個資料結構 Instance 的相關設定。由 於 Unit 是 tmVcapSvip 模組用來處理硬體相關資訊,所以在 Instance 結構中並不具有 Default 層所提供的 Setup 資料結構,而設定的過程上也不會透過 Default 層的函式來執 行,而是直接至 DL 層或 BSL 層來存取資料。因此在 Unit 的 Instance 資料結構中,包含 了許多 DL 層以及 BSL 層所定義的結構成員,如圖 4.12 所示,用來存放 DL 層與 BSL 層上資料結構的設定參數。
圖 4.11 Unit Capabilities 的結構關係
typedef struct _tag_tmdlSvipUnit_Capabilities_t {
UInt32 size; // DL capabilities 資料結構的大小,單位為 byte tmSWVersion_t version; // SVIP Device Library 的軟體版本
UInt32 numSupportedInstances;// SVIP 所支援的 Instance 數 } tmdlSvipUnit_Capabilities_t, *ptmdlSvipUnit_Capabilities_t;
DL Capabilities OL Capabilities
ptsaDefaultCapabilities_t pDefCapabilities; // Default capabilities tmdlSvipUnit_Capabilities_t * psvipCapabilities; // DL capabilities UInt32 numberOfStreams;
……
圖 4.12 Unit 的 Instance 結構
typedef struct tag_olSvipUnit_InstVars_t { ……
Int dlUnitInst;
ptmolVcapSvipUnit_InstanceSetup_t pSetup;
UInt32 numPorts;
……
ptmbslVdecAnaSvipConfig_t pVdecAnaSvipIntfs[MAX_ANALOG_DECODER_UNITS];
ptmbslVdecAna_t vdecInstances[MAX_ANALOG_DECODER_UNITS];
……
}olSvipUnit_InstVars_t, * polSvipUnit_InstVars_t;
DL 層的 Unit Instance 與 Instance 的 Setup 結構
由 BSL 層取得的 VdecAna 資訊
46
而在應用程式上,為了取得硬體 A/D 與 SVIP 這兩部分的設定資訊,以及設定 Unit Instance 結構中尚未有值的結構成員,會透過 Unit 所提供的 Open( )、GetInstanceSetup( )、
以及 InstanceSetup( )三個函式,來存取 Instance 的結構參數,以下即為這三個函式執行 內容的說明。
2. tmolVcapSvipUnit_Open( )
在 Unit 的 Open( )函式中,首先會分配記憶體給 Unit 的 Instance 結構,提供 Unit 存 放 Instance 設定的空間,接著藉由 DL 層的 Open( )函式來取得 DL 層 Instance 的資 料設定。其中 DL 層的 Instance 在前面描述過的 tmolVcapSvip_GetNumberOfUnit( ) 函式執行過程中,在呼叫初始化函式 dlSvipLocalInit( )來執行時,已經設定好 Instance 裡部分的值,因此這部分 DL 層的 Open()函式,則會直接回傳 DL Instance 資料結構 的位址給 OL 層。除了回傳 DL Instance 位址之外,DL 層的 Open()函式還會呼叫一 個初始化硬體的函式,tmdlSvipUnit_InitHw(),在這個函式裡會設定 SVIP 的暫存器 初始值,而暫存器這部分的詳細內容會在下一小節 Stream 裡說明。
Unit 的 Instance 在取得 DL 層 Instance 的結構位址之後,接下來會藉由 DL 層的 GetInstanceSetup()函式來取得 DL Instance 的 Setup 結構,Instance 的 Setup 結構是 Instance 結構裡提供給應用層修改設定的部分,所以在取得 DL Instance 的 Setup 結 構後,會將這個結構的值設定到 Unit Instance 裡,做為 OL 層提供給應用層變更設 定的初始值,Unit 的 Open()函式內容如圖 4.13 所示。
3. tmolVcapSvipUnit_GetInstanceSetup( )
當應用層呼叫此函式時,是為了要取得 Instance Setup 的結構位址以便設定結構裡 的參數,由於在 Open()函式中已經取得 Instance Setup 的位址,所以在這個函式裡
tmolVcapSvipUnit_Open { ……
tmdlSvipUnit_Open ();
//取 DL 的 Instance
tmdlSvipUnit_GetInstanceSetup() //取 Instance 的 Setup 結構 OL layer
tmdlSvipUnit_Open { ……
pUnitInst = &gUnitInst[unitNumber];
//存放 DL Instance 的位址 tmdlSvipUnit_InitHw(unitNumber) //設定 Svip 的暫存器
DL layer
圖 4.13 Unit Open 函式內容
47
只要將結構位址回傳給應用層即可。而應用程是在取得位址後,會對 Instance Setup 裡的參數重新設定一次,設定的內容大致上與預設值相同,只有在一些判斷的布林 系數上會做更改。
4. tmolVcapSvipUnit_InstanceSetup( )
當應用程式設定好 Instance Setup 結構後,即可藉由 InstanceSetup()函式將資料傳給 下層來更新設定。在 InstanceSetup( )函式中,會把從應用層傳入的資料複製到 DL 層的 Instance Setup 結構中,除了複製資料外,DL Instance Setup 結構上還有一個 port 的參數需要設定,port 這個參數結構主要是在設定 A/D 晶片與 SVIP 之間的連接埠 關係。由於 DSP 上具有兩組 SVIP,所以當 A/D 晶片處理完訊號的轉換後,必須將 影像資料傳入其中一個 SVIP,這部分的資訊設定在 A/D 晶片的資料結構裡,因此 這裡會藉由函式 tmolSvip_VdecGetPortSetup( )來取得 A/D 與 DSP 的硬體連接格式、
數位輸入的格式……等設定。
在 4.2 節 tmVdecAna 模組設定中有提到,tmVdecAna 模組會把到 BSL 層中取得的 硬體資訊存放在自己的資料結構裡,A/D 晶片的設定資訊也包含於其中,因此便可 將這些資料應用於目前的所要設定的連接埠上。而在 tmolSvip_VdecGetPortSetup( ) 函式中,則會依據 tmVdecAna 模組所提供的數據來設定 port 的結構參數。當取得 連接埠的設定資訊後,整個 Instance 的資料結構就算是設定完成,此時 InstanceSetup() 函式會呼叫 DL 層的 InstanceSetup( )函式,把前面對 Instance 所做的變更設定到 DL 層裡。接下來 DL 層則會依據這些 Instance 的值來設定 SVIP 的暫存器。而 Unit 這 部分的設定到此就大致上告一段落,下一小節則會針對模組的另一部分 Stream,以 及其運作流程與影像擷取的方式進行討論。