1. 程式人生 > >struct V4l2_device/video_device/v4l2_buffer/v4l2_subdev/ Video for Linux Two

struct V4l2_device/video_device/v4l2_buffer/v4l2_subdev/ Video for Linux Two

V4L2核心API提供了一套標準方法的用於處理視訊緩衝器(稱為“videobuf”)。這些方法允許驅動程式以一致的方式來實現read(),mmap()和overlay()。目前使用的裝置上的視訊緩衝器,支援scatter/gather方法(videobuf-dma-SG),線性存取的DMA的(videobuf-DMA-contig),vmalloc分配的緩衝區,主要用於在USB驅動程式(DMA緩衝區的方法videobuf-vmalloc)。

videobuf層的功能為一種V4L2驅動和使用者空間之間的粘合層。它可以處理儲存視訊幀緩衝區的分配和管理。有一組可用於執行許多標準的POSIX I / O系統呼叫的功能,包括read(),poll()的,happily,mmap()。另一套功能可以用來實現大部分的V4L2的ioctl()呼叫相關的流式I/ O的,包括緩衝區分配,排隊和dequeueing,流控制。驅動作者使用videobuf規定了一些設計決定,但回收期在驅動器和一個V4L2的使用者空間API的貫徹實施在減少程式碼的形式。


關於videobuf的層的更多資訊,請參閱Documentation/video4linux/videobuf

V4l2驅動架構

所有的驅動程式有以下結構:
        1) 每個裝置包含裝置狀態的例項結構。
        2) 子裝置的初始化和命令方式(如果有).
        3) 建立V4L2的裝置節點 (/dev/videoX, /dev/vbiX and /dev/radioX)和跟蹤裝置節點的具體資料。
        4)檔案控制代碼特定的結構,包含每個檔案控制代碼資料;
        5) 視訊緩衝處理。

驅動原始碼分析

vivi.c 虛擬視訊驅動程式----- 此程式碼模擬一個真正的視訊裝置V4L2 API (位於drivers/media/video目錄下)


 入口:+int __init vivi_init(void)
                + vivi_create_instance(i) /*建立裝置*//**/。
                        + 分配一個vivi_dev的結構體 /*它巢狀這結構體v4l2_device 和video_device*/
                        + v4l2_device_register(NULL, &dev->v4l2_dev);/*註冊vivi_dev中的V4l2_device*/
                        + 初始化視訊的DMA佇列

                        + 初始化鎖
                        + video_device_alloc(); 動態分配video_device結構體
                        + 構建一個video_device結構體 vivi_template 並賦給上面分配的video_device
                               static struct video_device vivi_template = {
                                         . name        = "vivi",
                                         .fops           = &vivi_fops,
                                         .ioctl_ops     = &vivi_ioctl_ops,
                                         .minor        = -1,
                                         .release    = video_device_release,

                                         .tvnorms              = V4L2_STD_525_60,
                                         .current_norm         = V4L2_STD_NTSC_M,
                                };
                      + video_set_drvdata(vfd, dev);設定驅動程式專有資料
                      + 所有控制元件設定為其預設值
                      + list_add_tail(&dev->vivi_devlist, &vivi_devlist);新增到裝置列表
         + 構建 v4l2_file_operations 結構體vivi_fops 並實現.open .release .read .poll .mmap函式----- .ioctl 用標準的v4l2控制處理程式
         + 構建 v4l2_ioctl_ops結構體 vivi_ioctl_ops
                            static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
                                       .vidioc_querycap      = vidioc_querycap,
                                       .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
                                       .vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
                                       .vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
                                       .vidioc_reqbufs       = vidioc_reqbufs,
                                       .vidioc_querybuf      = vidioc_querybuf,
                                       .vidioc_qbuf          = vidioc_qbuf,
                                       .vidioc_dqbuf         = vidioc_dqbuf,
                                       .vidioc_s_std         = vidioc_s_std,
                                       .vidioc_enum_input    = vidioc_enum_input,
                                       .vidioc_g_input       = vidioc_g_input,
                                       .vidioc_s_input       = vidioc_s_input,
                                       .vidioc_queryctrl     = vidioc_queryctrl,
                                       .vidioc_g_ctrl        = vidioc_g_ctrl,
                                       .vidioc_s_ctrl        = vidioc_s_ctrl,
                                       .vidioc_streamon      = vidioc_streamon,
                                       .vidioc_streamoff     = vidioc_streamoff,
                            #ifdef CONFIG_VIDEO_V4L1_COMPAT
                                      .vidiocgmbuf          = vidiocgmbuf,
                          #endif
                      };
          + int vivi_open(struct file *file)
                    + vivi_dev *dev = video_drvdata(file);  訪問驅動程式專用資料
                    + 分配+初始化控制代碼(vivi_fh)資料
                    + 重置幀計數器
                    + videobuf_queue_vmalloc_init(); 初始化視訊緩衝佇列
                    + 開啟一個新執行緒用於開始和暫停
          + 實現自定義的v4l2_ioctl_ops 函式