V4L linux視頻處理

V4L是 Video for Linux的縮寫,它是Linux 內核中關於視頻設備的子系統,它爲linux 下的視頻驅動提供了統一的接口,使得應用程序可以使用統一的API 函數操作不同的視頻設備,極大地簡化了視頻系統的開發和維護。
    由於早期的 V4L 有很多缺陷,Bill Dirks 等人對其進行了重新設計,並取名爲Video for Linux  2(V4L2使用),最早出現於Linux2.5.x 版本。V4L2 相比於V4L 有更好的擴展性和靈活性,並且支持的硬件設備更多。 
    因此在應用程序V4L編程實際是指v4l2,我們這個系列的以V4L2爲主,但由於歷史的原因,V4L2一般兼容V4L.所以很多程序可以用V4L接口.


1.V4L支持設備
    V4L2(video for linux) 可以支持多種設備,它可以有以下幾種接口:
    1. 視頻採集接口(video capture interface):這種應用的設備可以是高頻頭或者攝像頭.V4L2的最初設計就是應用於這種功能的.下面也是着重講解這種應用.
    2. 視頻輸出接口(video output interface):可以驅動計算機的外圍視頻圖像設備--像可以輸出電視信號格式的設備.
    3. 直接傳輸視頻接口(video overlay interface):它的主要工作是把從視頻採集設備採集過來的信號直接輸出到輸出設備之上,而不用經過系統的CPU.
    4. 視頻間隔消隱信號接口(VBI interface):它可以使應用可以訪問傳輸消隱期的視頻信號.
    5. 收音機接口(radio interface):可用來處理從AM或FM高頻頭設備接收來的音頻流.
  
2.V4L處理基本流程
    跟一般設備處理一樣,大體上V4L處理有四個流程.
    2.1 打開V4L設備結點
    一般V4L設備結點名是 /dev/videoN.如第一個V4L設備是/dev/video0.

      int fd = open("/dev/video0",O_RDWR |O_NONBLOCK);

    2.2配置設備/查詢設備屬性
    主要通過ioctl來操作,像V4L2 常見的的命令有
    
       int ioctl (int __fd, unsigned long int __request, .../*args*/) ;

        __request是V4L2一些ioctl命令,常見如下:  
    1. VIDIOC_REQBUFS:分配內存
    2. VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的數據緩存轉換成物理地址
    3. VIDIOC_QUERYCAP:查詢驅動功能
    4. VIDIOC_ENUM_FMT:獲取當前驅動支持的視頻格式
    5. VIDIOC_S_FMT:設置當前驅動的頻捕獲格式
    6. VIDIOC_G_FMT:讀取當前驅動的頻捕獲格式
    7. VIDIOC_TRY_FMT:驗證當前驅動的顯示格式
    8. VIDIOC_CROPCAP:查詢驅動的修剪能力
    9. VIDIOC_S_CROP:設置視頻信號的邊框
    10. VIDIOC_G_CROP:讀取視頻信號的邊框
    11. VIDIOC_QBUF:把數據從緩存中讀取出來
    12. VIDIOC_DQBUF:把數據放回緩存隊列
    13. VIDIOC_STREAMON:開始視頻顯示函數
    14. VIDIOC_STREAMOFF:結束視頻顯示函數
    15. VIDIOC_QUERYSTD:檢查當前視頻設備支持的標準,例如PAL或NTSC。
    2.3 處理V4L視頻數據
    在V4L設備中,有的設備從硬件取出,送到應用程序處理,比如攝像頭硬件取得視頻數據後,通過V4L接口把視頻數據發送應用程序, 比如顯示屏幕或保存成爲文件.
    有的設備是從應用發往硬件處理,如電視接口.
    在V4L接口,設定了三種應用程序與驅動的交互方式,分別是
    直接讀取設備文件方式(read/write)、用戶指針方式(userptr)以及mmap 映射方式。

    1)mmap方式,驅動將內部數據空間映射到應用程序空間上,雙方直接在這個空間進行數據交換,是效果最高的方法,這也是最常用的方式之一
    2)
直接讀取設備文件方式 直接調用 read()、write()函數進行數據的讀入和輸出,該方法一般配合select()使用。
    3)用戶指針方式 首先由應用程序申請一段緩衝區,然後將緩衝區傳給驅動,驅動將其作爲緩衝區,從而實現了內存共享。這一方法用的較少.

 2.4 關閉設備
    調用close();如果是內存映射方式,在關閉前還需要調用munmap解除映射.
發佈了137 篇原創文章 · 獲贊 31 · 訪問量 116萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章