嵌入式Linux系統下MPEG-4專用編碼器驅動設計

<script src="/html/ad/jswz/ad-jswz_6.js" type="text/javascript"></script>
摘要:嵌入式視頻監控的方案設計已有衆多論述,但針對實現過程中Linux下視頻MPEG-4編碼的驅動設計鮮有提及。本文以視頻編碼芯片IME6410的驅動設計爲實例,主要論述了基於Video for Linux (V4L) 規範的視頻驅動實現方法,包括硬件接口、設備初始化、文件操作實現等,並着重分析了V4L規範、視頻驅動及內核之間的內在聯繫。 關鍵詞:嵌入式Linux,Video4Linux,驅動, IME6410

AbstractThere are many researches on the design of embedded video surveillance system already. However, the method of design about Linux driver for MPEG-4 Codec has rarely been reported. In this paper, Linux driver for video Codec is discussed and an example of driver design for IME6410 is presented. The implement of driver based on V4L interface was introduced, of which the hardware interface, device initialization, file operations etc are involved as well. The fundamental relations between V4L interface, video drivers and linux kernel are analyzed deeply.

Key wordsEmbedded Linux,Video4Linux,driver, IME6410


1 引言

隨着嵌入式技術與流媒體技術的蓬勃發展,視頻監控系統正由基於PC的監控方案轉爲嵌入式的視頻監控方案。由於嵌入式的數字監控系統有着布控區域廣泛、可組成非常複雜的監控網絡且性能穩定可靠等優點,因此更具發展前景[1]。目前,基於MPEG-2壓縮標準的嵌入式視頻監控已經得到廣泛應用,即便如此,用戶和環境對視頻監控的要求越來越苛刻,尋求一種更好的壓縮方法和傳輸方式成爲新的目標。基於該目標,本文以一種專用MPEG-4編碼芯片IME6410爲例,從視頻壓縮的角度改進視頻監控方案。其中,主要描述了視頻編碼部分在嵌入式Linux下的驅動程序設計與實現。

本文首先介紹了本系統硬件結構,之後深入剖析了V4L規範,在此規範基礎上以IME6410爲例具體闡述驅動程序的設計開發過程,包括芯片初始化,設備註冊等,最後給出結論。

 

2 視頻系統硬件設計

在本系統中,MPEG-4編碼芯片採用IME6410。它是一款單路音視頻壓縮器件,其外圍集成了多種外設控制器和接口,如SDRAM控制器、I2C接口、I2S接口、主機控制器等。IME6410內部帶有RAM,可存放供芯片運行的Firmware程序。根據芯片特性,設計其外圍電路如圖1所示。

 

1 視頻服務器編碼部分硬件圖

編碼芯片IME6410在音視頻壓縮過程中產生的大量中間數據則須放置在大容量的32位外部SDRAM中,IME6410的視頻接口符合CCIR-601 16位標準,對外支持YUV422,對內採用YUV420採樣。外部視

頻Decoder採用SAA7111,支持NTSC/PAL制式,SAA7111的片內寄存器可通過其外部I2C接口設置。在視頻服務器系統中,有的ARM處理器自帶I2C總線,有的則沒有,而壓縮芯片IME6410片內帶有I2C總線控制器,提供作爲master的訪問方式,因而可以通過用IME6410間接控制SAA7111。單路視頻編碼輸出的數據量不超過14.745Mbps,應用16位總線的ARM 9系統負荷量不大。

視頻採集及壓縮部分的大致數據流如下:從攝像頭採集的模擬信號通過A/D傳送給IME6410,IME6410將視頻數據在SDRAM中進行實時編碼壓縮,併合成音頻編碼(可選),將編碼後的數據送往片內1K的FIFO中,當FIFO半滿或者全滿時,產生外部信號nfull,ARM控制器可通過中斷方式或者查詢方式獲知FIFO狀態,在需要時讀取FIFO數據,將其放在自己的RAM存儲器中以備後處理。

 

3 驅動程序設計

驅動程序介於操作系統與硬件之間,與硬件底層聯繫緊密。Linux下的視頻採集及壓縮系統中,一般都需要用到Video for Linux(V4L)驅動規範[2],該模塊是底層驅動程序與應用程序之間的接口。它爲Linux下的視頻設備提供了一套API 和相關的標準,按照V4L規定的接口訪問方式控制和讀寫設備,即可完成視頻編碼及相關參數的採集或設置。

 

1.V4L規範的深入剖析

V4L 將視頻設備分爲四類[3],規定所有視頻設備文件的主設備號都是一致的都是81 ,但是,對於不同的硬件類型,其特殊文件的次設備號不一致,且各類設備都有一段獨立的次設備號範圍。通過這種方式,可以從設備文件的次設備號中判斷該設備到底屬於那種類型。V4L 和特定的設備驅動是通過它定義的一些數據結構和相關的函數關聯起來的,其中關鍵的數據結構是video_device 結構,其定義如下: 

struct video_device

{

char name[32];     //設備名

int type;    // 設備類型

int minor;   //次設備號

devfs_handle_t devfs_handle;   //設備句柄

/*以下爲重要成員指針,有刪減*/

int (*open)(struct video_device *, int mode);

void (*close)(struct video_device *);

long (*read)(struct video_device *, char *, unsigned long, int noblock);

long (*write)(struct video_device*,char *, unsigned long, int noblock);

int (*ioctl)(struct video_device *, unsigned int , void *);

int (*mmap)(struct video_device *, const char*, unsigned long);

int (*initialize)(struct video_device *);

};

該結構對應於驅動程序控制的一個設備,其中的minor 成員代表該設備對應的次設備號,其他的open,close,read,write,ioctl等成員都代表相應的函數指針,這些函數指針都是指示特定設備的相關操作,V4L 利用統一的接口註冊了另一個設備操作結構,這個統一的設備操作結構裏的驅動接口函數根據被打開特殊設備文件的次設備號,來定位該設備文件對應的struct video_device ,從而實現對特定設備的控制。爲了實現這種定位,V4L 定義了一個靜態數組static struct video_device *video_device[256],每個特定的設備都在該數組裏佔據一項。設計驅動程序時,需要通過V4L 提供的一個設備註冊函數video_register_device 將每個所要控制的硬件設備數據結構填充到該靜態數組中,調用該函數的時候,應該提供設備特定數據結構以及設備類型。

video_register_device函數在videodev.c中實現,事實上V4L規範的主要實現都在該文件中,文件位於/driver/media/video/目錄下。videodev.c本身也是一個驅動模塊,一般通過menuconfig選項在內核編譯時靜態加載。加載V4L模塊的初始化函數module_init() 主要完成了字符型設備註冊的功能,過程如下:首先註冊一個主設備號爲81的字符型設備驅動,通過次設備號區分每個特定設備的驅動程序。註冊成功後,如果存在proc文件系統,則在/proc文件目錄下創建專用目錄/proc/video/dev/,當實際設備文件被註冊後,將在該目錄下生成一個設備文件[4]

當註冊一個實際設備,調用註冊函數video_register_device時,註冊要求的三個參數分別爲設備結構體(device struct),設備類型,次設備號。類型決定了次設備號的起始地址段,當註冊次設備號爲-1時,系統自動爲設備分配一個可用的最小設備號,若指定的設備還存在initialize函數,則亦在此運行,然後執行devfs_register,自動創建/dev目錄下的設備文件如video0,掛載文件操作file_operations指針,該指針地址同樣指向V4L模塊加載時定義的文件指針,最後在/proc/video/dev/下創建設備文件(上已提及)。所以,V4L與具體驅動設備註冊之間的掛鉤主要就是通過devfs_register 函數實現。

在剖析V4L接口規範後,根據其結構體,最重要的工作是模塊初始化, module_init系統調用加載video_IME_init函數,完成硬件初始化及設備結構填充工作。

 

2.完成IME6410和SAA7111的初始化

首先需要對IME6410及SAA7111分別初始化,在硬件設計中,設置SAA7111寄存器所採用的I2C接口通過IME6410輸出,所以必須先對IME6410初始化。

不同於一般的芯片,IME6410的芯片需要先下載Firmware程序然後才能正常工作,此時再初始化其片內寄存器,配置成要求的參數。根據硬件設計,首先配置ARM處理器的外部總線接口(EBI),從時序、延遲、電平有效等多方面滿足IME6410的時序要求。其次,根據圖2流程初始化IME6410,IME6410下載Firmware較爲特殊,在硬件選擇Host下載後,片內ROM檢測外部總線類型及寬度,隨即等候Host端向其發送數據,其接收數據的方式類似於flash燒寫的有限狀態機:先接收下載程序待存放的基地址和偏移地址;再接收Firmware的一個半字(half word)數據;然後,再次從Host端口等待一個傳送命令,並開始真正的將數據存到片內RAM中,主機可通過查詢狀態寄存器獲知傳送情況,並循環以上過程完成下載過程,下載完畢後的IME6410將自動置位版本寄存器及各種編碼方式寄存器,查詢版本寄存器獲知Firmware下載是否成功。

 

2 視頻外設初始化流程圖

Firmware使能片內I2C模塊,對ARM控制器而言就是一個外部I2C控制器,在Linux中利用宏抽象I2C讀寫操作。IME6410的片內I2C總線只支持最多四字節的塊寫操作,這給SAA7111的寄存器初始化增添了麻煩,但因爲SAA7111內部待設置的寄存器不多,通過幾次操作即可完成。

 

3.實現視頻設備註冊和中斷程序註冊

視頻設備註冊調用的源函數包含了模塊計數增1,因而無需調用MOD_INC_USE_COUNT宏計數[4]。在視頻註冊調用時引用的video_device 數據結構應填充完畢,其文件操作指針通過回調函數指定,如:

static struct video_device IME_template =

{     ……

open:      video_IME_open,

read:       video_IME _read,

ioctl:       video_IME _ioctl,

 ……

};

該結構體中各文件操作指針回調函數的功能按實際需求定義,這裏列出本系統中的部分功能分配。

open:open操作使能IME6410的工作,首先查詢IME6410的狀態寄存器,當一切正常時,使能IME6410寄存器開始圖像編碼。

read:讀取IME6410的FIFO,每次讀取一包(512字節)的緩衝區,對於每一包數據,其前4個字節標註了包大小及類型等信息,供應用層使用。

write:IME6410不需要實現寫數據操作,因而基本不起作用。

mmap:映射視頻設備緩衝到本地內存緩存。

ioctl:不同於一般的設備文件,符合V4L的視頻文件操作一般都通過ioctl函數設置、獲取各類參數甚至圖像數據。V4L列出了所有的相關操作[5],對於本視頻編碼只實現一部分實用操作,如表1,視頻採集或編碼的操作差異較大,需要實現各自的控制方式。有些通過ARM設定的參數就直接在本地訪問了。

視頻編碼控制操作

VIDIOCGPICT

獲取圖像參數,包括分辨率,幀速率,比特率控制等

VIDIOCSPICT

設置圖像參數

VIDIOCGMBUF

獲取本地映射緩存的參數,主要是其地址和大小

VIDIOCMCAPTURE

獲取圖像編碼到映射緩衝區

VIDIOCSYNC

獲取幀結束標誌

 

中斷程序的註冊採用request_irq系統調用,在本程序中,採用外部IO中斷,須根據ARM芯片硬件設置選擇中斷向量號。中斷句柄指向了中斷處理程序,該程序在內核態執行。當IME6410的FIFO半滿或全滿時,ARM處理器產生IO中斷,Linux內核相應中斷句柄,從而進入中斷處理程序,程序讀取一包數據後,通過消息機制通知上層應用。

編譯後的驅動程序在/dev目錄下生成名爲v4lvideo0的inode節點文件。至此,完成整個驅動程序的設計與編寫。

 

4 結束語

本文深入剖析了V4L規範與視頻驅動的上下關係,以編碼芯片IME6410爲例,介紹了基於視頻編碼模塊的驅動開發的具體方法,針對視頻壓縮編碼選擇了合理的ioctl命令。編譯後的程序文件其系統調用遵循V4L規範,在應用程序的測試中獲得了較好的性能。文中適用於一切符合V4L規範的視頻驅動開發。

本文作者創新點:

1.  在嵌入式Linux上設計了符合V4L規範的驅動程序,使該驅動程序有一定的通用性。

2.  提供了符合V4L規範的驅動程序設計一般方法

3.  爲專用MPEG-4編碼器在嵌入式系統中的應用提供了一種參考方法

 

參考文獻:

1 南冰,李興華,荊濤. 基於MPEG-4標準和嵌入式技術的監控系統設計[J]. 微計算機信息,2005,9-3:112-113

2 Alan Cox. Video4Linux Programming.[M] [email protected]. 2000

3 李根深,邢漢承.Linux平臺下PCI接口視頻採集卡的驅動程序編寫技術[J],計算機輔助工程,2003, Vol.12 No.1:12-19

4 ALESSANDRO RUBINI.魏永明等譯.LINUX 設備驅動程序[M]. 北京 中國電力出版社,2002

5 楊繼華,嚴國萍.基於嵌入式Linux與S3C2410平臺的視頻採集[J],單片機與嵌入式系統應用,2004, No.11:69-71

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章