楊振永,王延杰,王明佳,韓秋蕾,陳懷章
(1.中國科學院 長春光學精密機械與物理研究所,吉林 長春 130033;2.中國科學院大學,北京 100049)
近年來,隨著數(shù)字多媒體技術的飛速發(fā)展,安防監(jiān)控領域對視頻質量有了越來越高的要求,特別是由于犯罪分子作案手段越來越難以發(fā)覺捕捉,標清視頻很難發(fā)現(xiàn)其中的細節(jié)[1]。因此,視頻設備的高清化成為了安防監(jiān)控領域發(fā)展的必然趨勢,而基于高清設備的軟件開發(fā)也成為了必須要解決的問題。
V4L2(Video for Linux 2)是嵌入式Linux操作系統(tǒng)為音視頻采集和顯示而提供的驅動框架,在Linux 2.5.46版本以后正式成為Linux內核的一部分,它為音視頻采集和顯示應用提供了API接口[2]。目前V4L2已支持多種視頻設備的采集和顯示,同時驅動本身經過不斷的完善,也可以提供越來越多的圖像預處理功能?;赩4L2的應用開發(fā)已經十分成熟,但是新的設備必然帶來新的問題,V4L2在高清視頻采集中也會受到資源不足等問題的困擾。
本文針對TMS320DM8168高清視頻監(jiān)控系統(tǒng),首先介紹了V4L2采集的譯碼芯片TVP7002及其與DM8168的接口連接,之后介紹了V4L2視頻設備的驅動設計和應用程序開發(fā),并對其中出現(xiàn)的問題進行了分析解決,最后給出了視頻監(jiān)控系統(tǒng)的效果。結果表明,V4L2在DM8168高清視頻監(jiān)控系統(tǒng)中具有良好的可靠性和穩(wěn)定性,可以為系統(tǒng)提供穩(wěn)健的高清視頻流。
以TMS320DM8168為核心的高清視頻監(jiān)控系統(tǒng),主要由高清視頻的采集和顯示模塊、視頻處理模塊、SATA存儲模塊和網絡傳輸模塊4部分組成,總體結構如圖1所示。
由圖中可以看出,TMS320DM8168內部集成的Cortex-A8 ARM處理器是系統(tǒng)的主處理器,控制著整個系統(tǒng)的運行,單片系統(tǒng)內部集成的C674x DSP處理器主要完成視頻算法的處理,Cortex-M3 ARM處理器是系統(tǒng)多媒體控制器,控制了視頻的高清視頻處理子系統(tǒng)HDVPSS和加速視頻壓縮解壓縮的硬件加速器HDVICP2,HDVPSS控制著視頻采集與顯示模塊,SATA控制器控制著視頻數(shù)據(jù)的SATA存儲,網絡控制器控制著網絡傳輸部分,支持10/100/1 000 Mbit/s的網絡傳輸[3]。
圖1 系統(tǒng)總體框圖
系統(tǒng)使用TVP7002作為視頻譯碼芯片,與DM8168對應的視頻采集接口連接。DM8168單片系統(tǒng)中視頻采集和顯示部分以高清視頻處理子系統(tǒng)HDVPSS為基礎,HDVPSS支持兩個獨立的視頻采集端口VIN[0]和VIN[1],能夠支持兩路并行的高達165 MHz的視頻采集,其中VIN[0]可采集單通道16/24 bit(YCbCr/RGB)視頻或者雙通道 8 bit(YCbCr)視頻,VIN[1]可配置為單通道 16 bit(YCbCr)視頻或者雙通道8 bit(YCbCr)視頻,當采集高清視頻時,視頻需要符合BT.1120協(xié)議,當采集標清視頻時,符合BT.656協(xié)議;HDVPSS還有3個獨立的視頻輸出端口VOUT[0]、VOUT[1]和HDMI輸出端口,其中VOUT[0]最高可顯示30 bit視頻,它支持RGB、YUV444、Y/C和BT.656等多種格式;VOUT[1]可顯示16 bit視頻,它支持Y/C和BT.656格式;HDMI輸出接口,支持HDMI 1.3a協(xié)議,最高頻率達到162 MHz。此外,VIN[]和VOUT[]都支持內嵌同步信息和獨立同步信息兩種同步方式。
TVP7002支持3個獨立的數(shù)字通道,支持480i、576i、480p、576p、720p、1 080i和1 080p格式的視頻譯碼,輸出時鐘從12 MHz到165 MHz不等,輸出可為30 bit RGB/YCbCr 4∶4∶4或20 bit 4∶2∶2視頻,同步信息可以內嵌到視頻數(shù)據(jù)中或者獨立于視頻數(shù)據(jù)之外,芯片可以通過I2C總線配置。系統(tǒng)的視頻接口關鍵連接如圖2所示。
由圖中可以看出,視頻采集選用了VIN[0]通道采集16 bit YCbCr 4∶2∶2高清視頻,其中VIN[0]_D[15:8]傳輸亮度分量Y,VIN[0]_D[7:0]傳輸色度分量Cb/Cr,視頻同步信息嵌入到有效數(shù)據(jù)之中。DM8168通過I2C總線配置TVP7002芯片,芯片I2C地址選擇引腳接高電平,其I2C地址為7 bit 1011101。
圖2 視頻采集接口
視頻顯示接口使用HDMI輸出通道,HDMI通道最高輸出頻率達到162 MHz,每對差分線速度達到3.4 Gbit/s,因此,為了確保良好的信號完整性,增加了TPD12S521靜電釋放ESD保護芯片。
DM8168中HDVPSS系統(tǒng)管理著視頻的采集和顯示,V4L2驅動作為HDVPSS的一部分,為視頻采集程序提供了API接口函數(shù)。HDVPSS的軟件結構如圖3所示。
圖3 VPSS軟件結構圖
由圖中可以看出,VPSS硬件可以分為2個部分:Cortex-M3和Cortex-A8,其中Cortex-M3管理VPSS的視頻、圖像的采集和顯示管道,Cortex-A8為驅動提供了硬件抽象層FVID2,為驅動程序提供了底層支持;Cortex-M3和Cortex-A8之間的通信通過SysLink管理。Cortex-A8上運行Linux操作系統(tǒng),它分為內核空間和用戶空間,驅動程序V4L2和FBDEV以及文件系統(tǒng)管理接口SYSFS都在內核空間,它們?yōu)橛脩艨臻g的應用程序提供API接口函數(shù)。FBDEV是幀緩沖設備,主要用于LCD顯示,它將內存中的圖像數(shù)據(jù)與LCD的像素位置一一對應,具有操作簡單、靈活多變的特點,本系統(tǒng)HDMI輸出接口采用的就是幀緩沖驅動,這里不再詳細介紹。SYSFS接口為應用程序控制驅動提供了接口,可以配置視頻顯示驅動,改變顯示通道[4]。
V4L2驅動是Linux中標準的視頻采集和顯示驅動,是Linux內核中關于視頻設備的中間驅動層。它在Linux內核中注冊為字符設備,其主設備號為81[5],從設備號為0~255,其中0~63用于視頻設備,64~127用于音頻設備,192~223用于Teletext設備,224~255用于VBI設備。理解V4L2驅動前需要先了解platform driver平臺驅動的概念。platform與I2C、PCI等總線類似,都是為了便于管理系統(tǒng)的外設資源,將設備和驅動連接在一起,但是platform是一種虛擬總線,并沒有嚴格的總線協(xié)議,只是為了將外設掛載在一種總線上,便于統(tǒng)一管理,在SOC單片系統(tǒng)中,platform driver平臺驅動很常見,它有獨立的注冊函數(shù)和注銷函數(shù),即platform_driver_register()和platform_driver_unregister()。
V4L2視頻采集驅動有兩種實現(xiàn)方法:將采集設備作為普通V4L2設備,直接控制TVP7002譯碼芯片實現(xiàn)視頻數(shù)據(jù)的采集,或者利用內核中實現(xiàn)好的V4L2驅動框架,將譯碼芯片掛載為V4L2的子設備,通過實現(xiàn)V4L2驅動的接口函數(shù),完成視頻的采集[6]。第1種方法代碼量大,難度也大,第2種方法工作量較小,可移植性強,因此,選擇了第2種方法實現(xiàn)V4L2采集驅動。
V4L2采集驅動從注冊平臺驅動開始,將采集驅動注冊到platform總線上。在driver的probe()探測函數(shù)里完成資源分配以及V4L2設備的注冊。在probe()函數(shù)中video_device結構體與視頻采集設備是一一對應的,每個video_device都有自己的采集設備。本系統(tǒng)的采集驅動支持4路視頻通道,在調用video_register_device()函數(shù)后,將在/dev目錄上生成video0、video4、video5和video6這4個設備節(jié)點,每個視頻通道都有各自的操作函數(shù)集 v4l2_file_operations和控制函數(shù)集v4l2_ioctl_ops。除了以上內容,probe()函數(shù)還要將V4L2子設備與V4L2設備綁定在一起。由于TVP7002使用I2C總線配置,因此,最初TVP7002是注冊為I2C子設備的,此時需要使用函數(shù)v4l2_i2c_new_subdev_board()將I2C子設備添加為一個V4L2子設備。該函數(shù)主要完成2個工作:根據(jù)函數(shù)傳遞的I2C設備相關信息向I2C總線添加(或探測)一個I2C設備,然后向V4L2驅動注冊V4L2子設備。DM8168有2個通用的I2C控制器,TVP7002使用第2個,因此,調用v4l2_i2c_new_subdev_board()函數(shù)前需要使用i2c_get_adapter()函數(shù)獲取對應的I2C適配器。
TVP7002作為V4L2的子設備v4l2_subdev,首先會注冊為I2C子設備i2c_client,為了將兩者關聯(lián)起來,在TVP7002驅動的probe函數(shù)中調用了v4l2_i2c_subdev_init()函數(shù),在該函數(shù)中兩者將彼此的*private指針指向對方。v4l2_i2c_subdev_init()函數(shù)還調用了v4l2_subdev_init()函數(shù)將TVP7002的操作函數(shù)集賦給對應V4L2子設備的操作函數(shù)。TVP7002作為v4l2_subdev,對應/dev/video0設備節(jié)點,主要實現(xiàn)了core函數(shù)集和video函數(shù)集兩類,其中core函數(shù)集中定義了對TVP7002芯片的寄存器配置函數(shù),如獲得芯片id函數(shù)g_chip_ident、寄存器值獲取函數(shù)g_register、寄存器值設置函數(shù)s_register等,video函數(shù)集為V4L2的部分操作函數(shù)提供了底層實現(xiàn)。此外,TVP7002的probe()函數(shù)中還設置了芯片的初始化狀態(tài)。
V4L2設置完視頻采集參數(shù)后,需要為將要采集到的視頻分配緩存,對視頻緩沖幀的管理是V4L2非常重要的一部分,它關系到視頻能否正確地傳遞給應用層,一般V4L2驅動會使用Linux提供的videobuf_queue結構管理視頻的緩沖幀,它為驅動提供了統(tǒng)一的V4L2用戶空間接口,增加了可移植性。Videobuf層位于V4L2驅動層和應用層之間,包含一系列的函數(shù),可實現(xiàn)標準POSIX I/O系統(tǒng)調用以和V4L2的ioctl()函數(shù)調用,它們可用于管理幀視頻的緩沖區(qū)分配、FIFO隊列出入和流控制等。
Videobuf支持3種類型的緩沖區(qū),第1種是在物理和虛擬地址上都不連續(xù)的緩沖區(qū),這種緩沖區(qū)在Linux中非常常見,幾乎所有的用戶空間緩沖區(qū)都是這種類型,但是這種分配方式需要硬件支持分散/聚集DMA操作;第2種是在物理上連續(xù),在虛擬地址上不連續(xù)的緩沖區(qū),這種緩沖區(qū)使用vmalloc()函數(shù)分配,很難用于DMA操作;第3種是在物理和虛擬地址上都連續(xù)的緩沖區(qū),這種緩沖區(qū)可以很方便地使用DMA操作,但是容易造成內存空間的溢出[7]。
為了方便管理緩沖區(qū),videobuf提供了4個接口函數(shù)buf_setup()、buf_prepare()、buf_queue()和 buf_release()。與之對應,在v4l2_ioctl_ops函數(shù)組中提供了vidioc_reqbufs()、vidioc_qbuf()、vidioc_streamon()和 vidioc_streamof()這4個函數(shù)。int(*buf_setup)(struct videobuf_queue*q,unsigned int*count,unsigned int*size)用于通知videobuf申請的I/O緩沖幀的信息,包括緩沖區(qū)的數(shù)量(在2~32之間)、緩沖區(qū)類型和大小等;int(*buf_prepare)(structvideobuf_queue*q,structvideobuf_buffer*vb,enum v4l2_field field)用于設置緩沖幀的寬、高等信息;buf_queue()和buf_release()用于實現(xiàn)緩沖幀數(shù)據(jù)流的啟停。
V4L2驅動提供了符合POSIX I/O標準的系統(tǒng)調用函數(shù)open()、read()以及控制函數(shù)ioctl()。通過這些函數(shù)可以方便地完成視頻的采集工作。采集程序流程圖如圖4所示。
圖4 視頻采集流程圖
這里以采集720p 60 YCbCr 4∶2∶2高清視頻為例介紹視頻采集的流程:
1)打開視頻設備:本驅動設備節(jié)點為/dev/video0,可以使用cap_fd=open(“/dev/video0”,O_RDWR)打開視頻設備。
2)設置視頻格式:在申請緩沖區(qū)前,需要判斷視頻的格式,首先查詢設備處理能力VIDIOC_QUERYCAP[8],若設備支持視頻采集,則查詢采集的視頻格式VIDIOC_QUERY_DV_PRESET,本例中得到的是V4L2_DV_720P60,之后根據(jù)得到的視頻格式,設置參數(shù)VIDIOC_S_DV_PRESET,以上操作均是使用V4L2的ioctl()函數(shù)完成的。
3)申請幀緩沖區(qū):V4L2支持兩種不同的幀緩沖區(qū)操作:映射內存mmap和用戶指針類型內存userptr。本系統(tǒng)采集的都是高清視頻,一幀720p圖像將近1.76 Mbyte,而由于硬件限制,DM8168采集和顯示的幀緩沖區(qū)都不能低于4個,DM8168很難留出這么大的空間用于內存映射,因此,這里使用用戶指針類型的內存。具體的操作步驟是:使用VIDIOC_G_FMT獲得當前視頻寬、高等信息、使用VIDIOC_S_FMT設置視頻信息、使用VIDIOC_REQBUFS申請4個用戶指針類型的幀緩沖區(qū),內存分配使用LCD設備緩沖區(qū),這樣可以直接顯示。
4)緩沖幀入列:videobuf通過將緩沖幀送入FIFO隊列來保證視頻流的順序,這里使用VIDIOC_QBUF將申請到的每個幀緩沖區(qū)依次送入FIFO隊列中。
5)采集過程:視頻的采集過程實際是FIFO隊列的入隊出隊過程,該過程使用VIDIOC_STREAMON啟動,使用VIDIOC_STREAMOFF終止,其中VIDIOC_DQBUF使視頻幀出隊列,VIDIOC_QBUF使視頻幀入隊列,取出的視頻幀可以做相應的處理。
6)關閉視頻設備:采集結束后需要釋放緩沖區(qū),并且關閉設備節(jié)點close(cap_fd)。
這里以采集720p 60高清視頻為例,測試V4L2驅動及應用程序的可靠性。
將V4L2視頻采集驅動編譯為獨立的內核模塊,加載該模塊,編譯并運行采集應用程序,顯示得到的視頻如圖5所示。
圖5 視頻采集的圖像
采集到的高清視頻流暢,沒有出現(xiàn)丟幀的情況,由圖中可以看到采集到的畫面質量很好,證明了V4L2驅動和應用程序的可靠性。
本文主要介紹了V4L2在DM8168高清視頻監(jiān)控系統(tǒng)中的驅動和應用實現(xiàn)。文中首先介紹了V4L2高清視頻的結構基礎DM8168高清視頻監(jiān)控系統(tǒng),特別是視頻的輸入輸出接口,之后V4L2的軟件基礎HDVPSS以及視頻采集驅動在HDVPSS中的位置特點,最后詳細介紹了V4L2驅動程序的設計實現(xiàn)以及采集應用程序的流程步驟。通過采集720p 60高清視頻,表明本系統(tǒng)設計實現(xiàn)的V4L2驅動程序以及應用程序可以穩(wěn)定可靠地采集高清視頻,為高清視頻監(jiān)控系統(tǒng)提供優(yōu)質的高清視頻數(shù)據(jù)。
:
[1]蘇財貴,葉宇煌,蘇凱雄.HDMI接口在H.264高清視頻編解碼系統(tǒng)中的應用[J].電視技術,2012,36(21):67-70.
[2]黃俊偉,巴義.基于V4L2移動視頻監(jiān)控系統(tǒng)的研究與設計[J].電視技術,2012,36(17):159-162.
[3]Texas Instruments Incorporated.TMS320DM816x DaVinci video processors[EB/OL].[2013-07-11].http://www.ti.com/lit/ds/symlink/tms320dm8168.pdf.
[4]Texas Instruments Incorporated.DM816X AM389X VPSS video driver user guide PSP 04.00.00.12[EB/OL].[2013-07-24].http://processors.wiki.ti.com/index.php?oldid=79736.
[5]LIU Y,YU H,ZHANG P.The implementation of embedded image acquisition based on V4L2[C]//Proc.2011 International Conference on Electronics,Communications and Control.[S.l.]:IEEE Press,2011:549-552.
[6]徐家,陳奇.基于V4L2的視頻設備驅動開發(fā)[J].計算機工程與設計,2010,31(16):3569-3572.
[7]CORBET J.Videobuf:buffer management for V4L2 drivers[EB/OL].[2013-07-23].http://lwn.net/Articles/363349.
[8]趙玉峰.基于嵌入式Linux的實時視頻通信的實現(xiàn)[J].電視技術,2012,36(19):189-192.