Linux中V4L2分析

1、vivi.c分析html

一、vivi.c是Linux中虛擬的v4l2驅動,使用它來學習v4l2驅動架構linux

 1.vivi驅動涉及文件:緩存

            vivi.c                        驅動的具體實現架構

            v4l2-common.capp

            V4L2-dev.c            video_register_device(struct video_device *vdev...);框架

            V4L2-device.c       v4l2_device_register(struct device *dev,struct v4l2_device *v4l2_device);ide

            videobuf_core.c函數

            videobuf_vmalloc.c學習

2.主要關注如下幾個結構體:spa

             struct video_device   視頻類設備的基類,另外字符設備驅動的基類爲cdev,全部的操做都是圍繞cdev結構體

             struct v4l2_file_operations   包含vivi_read,vivi_open等函數具體實現。在系統調用的時候,會首先調用cdev的file_operations的v4l2_read,v4l2_open等函數,在這些函數中會使用struct file中的video_device來調用vivi_read等函數具體去實現。

             struct v4l2_ioctl_ops            ioctl操做的函數的具體實現

             struct V4l2_device

             struct videobuf_buffer           視頻數據緩衝區,對應一幀視頻,裏面包含視頻的大小等信息

             struct videobuf_queue          視頻緩衝區隊列

        以上幾個結構體可能不會被單獨使用,通常都被包含在某個更大的對象結構中,好比video_device和v4l2_device都包含在vivi_dev中,而vivi_dev被包含在viv_fh中,videobuf_buffer被包含在vivi_buffer中。

這個struct file_opertions v4l2_fops是字符設備給上層提供的系統調用,這裏的函數最終調用的仍是struct v4l2_file_operations (vivi_fops)的實現,能夠查看v4l2_open的實現。videobuf_queue_ops中實現了緩衝隊列的一些操做,buffer_setup,buffer_prepare,buffer_queue,buffer_release等,可是這些申請的緩衝隊列都是在內核空間,在vivi_mmap函數中videobuf_mmap_mapper(struct videobuf_queue *q,struct vm_area_struct *vma);將緩衝隊列映射到vm_area_struct虛擬地址

3.分析程序流程:

在vivi.c文件中

vivi_create_instance()

      v4l2_device_register()

      給video_device vdev對象賦值v4l2_file_operations和v4l2_ioctl_ops等

      video_device_register()

          初始化video_device對象vdev

          初始化video_device中的cdev結構體

                      cdev_add()註冊字符設備

          初始化video_device中struct device結構體

                     device_register()在/dev/目錄下建立設備節點

  v4l2_dev.c文件裏file_operations中的v4l2_ioctl最終調用的仍是vivi.c文件裏v4l2_file_operations中的video_ioctl2函數,可是這裏的video_ioctl2不像vivi_open,vivi_read等是具體的實現,video_ioctl2具體的實現已經單獨拿出來放到v4l2_ioctl.c文件中了,因此video_ioctl2最終調用的是v4l2_ioctl.c文件中的__video_do_ioctl(file,cmd,arg)函數,而__video_do_ioctl(file,cmd,arg)函數又回過來調用vivi_ioctl中vivi_ioctl_ops中的函數。

 

 2、V4L2架構分析

  v4l2向上爲應用程序提供了統一的調用接口,向下爲設備驅動程序提供了統一的V4L2框架;Linux中V4L2驅動的視頻設備(如攝像頭、視頻採集卡)的設備文件爲/dev/videoX,主設備號81,對於視頻設備次設備號爲0-63(是字符設備),Radio設備爲64-127,Teltext設備爲192-223,VBI設備是224-255,V4L2驅動的視頻設備在用戶空間經過ioctl()控制,還能夠進行mmap()映射。

要想了解 V4l2 有幾個重要的文檔是必需要讀的:

1、源碼Documentation/video4linux目錄下的V4L2-framework.txtvideobuf

2、V4L2的官方API文檔V4L2 API Specification

3、源碼drivers/media/video目錄下的sample程序vivi.c(虛擬視頻驅動程序,此代碼模擬一個真正的視頻設備V4L2 API)。

V4l2能夠支持多種設備,它能夠有如下幾種接口:

1. 視頻採集接口(video capture interface):這種應用的設備能夠是高頻頭或者攝像頭.V4L2的最初設計就是應用於這種功能的.

2. 視頻輸出接口(video output interface):能夠驅動計算機的外圍視頻圖像設備--像能夠輸出電視信號格式的設備.

3. 直接傳輸視頻接口(video overlay interface):它的主要工做是把從視頻採集設備採集過來的信號直接輸出到輸出設備之上,而不用通過系統的CPU.

4. 視頻間隔消隱信號接口(VBI interface):它可使應用能夠訪問傳輸消隱期的視頻信號.

5. 收音機接口(radio interface):可用來處理從AM或FM高頻頭設備接收來的音頻流.

 

V4L2 驅動核心

V4L2 的驅動源碼在drivers/media/video目錄下,主要核心代碼有:

v4l2-dev.c                  //linux版本2視頻捕捉接口,主要結構體 video_device 的註冊
v4l2-common.c               //在Linux操做系統體系採用低級別的操做一套設備structures/vectors的通用視頻設備接口。
                            //此文件將替換videodev.c的文件配備常規的內核分配。
v4l2-device.c               //V4L2的設備支持。註冊v4l2_device
v4l22-ioctl.c               //處理V4L2的ioctl命令的一個通用的框架。
v4l2-subdev.c               //v4l2子設備
v4l2-mem2mem.c              //內存到內存爲Linux和videobuf視頻設備的框架。設備的輔助函數,使用其源和目的地videobuf緩衝區。

頭文件linux/videodev2.h、media/v4l2-common.h、media/v4l2-device.h、media/v4l2-ioctl.h、media/v4l2-dev.h、media/v4l2-ioctl.h等。

 來源:http://zjbintsystem.blog.51cto.com/964211/464729       http://www.rosoo.net/a/201001/8382.html   (此兩者相似)

Video4linux2通常操做流程(視頻設備):
1. 打開設備文件。 int fd=open(」/dev/video0″,O_RDWR);
2. 取得設備的capability,看看設備具備什麼功能,好比是否具備視頻輸入等。VIDIOC_QUERYCAP,struct v4l2_capability
3. 選擇視頻輸入,一個視頻設備能夠有多個視頻輸入。VIDIOC_S_INPUT,struct v4l2_input
4. 設置視頻的制式和幀格式,制式包括PAL,NTSC,幀的格式個包括寬度和高度等。
VIDIOC_S_STD,VIDIOC_S_FMT,struct v4l2_std_id,struct v4l2_format
5. 向驅動申請幀緩衝,通常不超過5個。struct v4l2_requestbuffers
6. 將申請到的幀緩衝映射到用戶空間,這樣就能夠直接操做採集到的幀了,而沒必要去複製。
7. 將申請到的幀緩衝所有入隊列,以便存放採集到的數據.VIDIOC_QBUF,struct v4l2_buffer
8. 開始視頻的採集。VIDIOC_STREAMON
9. 出隊列以取得已採集數據的幀緩衝,取得原始採集數據。VIDIOC_DQBUF
10. 將緩衝從新入隊列尾,這樣能夠循環採集。VIDIOC_QBUF
11. 中止視頻的採集。VIDIOC_STREAMOFF
12. 關閉視頻設備。close(fd);
經常使用的結構體(參見linux-2.6.18_pro500/include/linux/include/linux/videodev2.h):
struct v4l2_requestbuffers reqbufs;//向驅動申請幀緩衝的請求,裏面包含申請的個數
struct v4l2_capability cap;//這個設備的功能,好比是不是視頻輸入設備
struct v4l2_input input; //視頻輸入
struct v4l2_standard std;//視頻的制式,好比PAL,NTSC
struct v4l2_format fmt;//幀的格式,好比寬度,高度等
struct v4l2_buffer buf;//表明驅動中的一幀
v4l2_std_id stdid;//視頻制式,例如:V4L2_STD_PAL
struct v4l2_queryctrl query;//查詢的控制
struct v4l2_control control;//具體控制的值

  open(CAPTURE_DEVICE, O_RDWR | O_NONBLOCK, 0))關於阻塞模式和非阻塞模式,應用程序可以使用阻塞模式或非阻塞模式打開視頻設備,若是使用非阻塞模式調用視頻設備,即便還沒有捕獲到信息,驅動依舊會把緩存(DQBUFF)裏的東西返回給應用程序。

 

 

 

參考:http://blog.csdn.net/luckywang1103/article/details/17406029

關於如何建立設備節點的:用戶空間的udev會根據device_create建立相應的設備節點;這裏只是簡單說說個人理解class_create與class_register功能上相似,只是class_register須要分配struct class對象內存並初始化。自動建立設備節點class_create與device_create或者class_register,device_register,用戶空間的udev會根據device_create建立相應的設備節點

 linux中class_create和class_register說明:http://www.cnblogs.com/skywang12345/archive/2013/05/15/driver_class.html  (未看

v4l2驅動架構解析與開發引導: http://www.360doc.com/content/13/1010/16/7775902_320343471.shtml

相關文章
相關標籤/搜索