V4L2(video for linux) 可以支持多种设备,它可以有以下5种接口:

1、视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头.V4L2的最初设计就是应用于这种功能的.下面也是着重讲解这种应用;

2、视频输出接口(video output interface):可以驱动计算机的外围视频图像设备——像可以输出电视信号格式的设备;

3、直接传输视频接口(video overlay interface):它的主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过系统的CPU;

4、视频间隔消隐信号接口(VBI interface):它可以使应用可以访问传输消隐期的视频信号;

5、收音机接口(radio interface):可用来处理从AM或FM高频头设备接收来的音频流;

V4L2驱动的主要功能是使程序有发现设备的能力和操作设备.它主要是用过一系列的回调函数来实现这些功能.像设置高频头的频率,帧频,视频压缩格式和图像像参数等等.

一、V4L2的移植

V4L2提供了三种不同的API来传输外围设备和用户空间的数据。下面就vivi(drivers/media/video/vivi.c)来讲解一个V4L2驱动的编写。注意它是一个虚拟的设备驱动,没有与实际的硬件打交道。

    1、分析几个重要数据结构:

     vivi.c包含头文件v4l2-device.h和v4l2-ioctl.h,其中v4l2-device.h中包含了v4l2-subdev.h,v4l2-subdev.h中又包含了v4l2-common.h,v4l2-common.h中包含了v4l2-dev.h。

在v4l2-dev.h中定义了结构体video_device和v4l2_file_operations;

在v4l2-ioctl.h中定义了结构体v4l2_ioctl_ops;

在v4l2-device.h中定义了结构体v4l2_device;

1) vivi_fops

static const struct v4l2_file_operations vivi_fops = {

.owner           = THIS_MODULE,

.open           = vivi_open,

.release        = vivi_close,

.read           = vivi_read,

.poll        = vivi_poll,

.ioctl          = video_ioctl2, /* V4L2 ioctl handler */

.mmap           = vivi_mmap,

};

2) 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_g_fmt_vid_cap     = vidioc_g_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

};

3) vivi_template

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,

};

其中函数vivi_xxx和vidioc_xxx都是在vivi.c中实现的。如果要基于某个硬件来实现V4L2的接口,那这些函数就需要调用硬件的驱动去实现。

4) vivi_dev

struct vivi_dev {

    struct list_head           vivi_devlist; //内核双向链表,在内核数据结构里有描述

    struct semaphore           lock;   //信号量,防止竞态访问

    int                        users;  //用户数量计数

    /* various device info */

    unsigned int               resources;

    struct video_device        video_dev; //这个成员是这个结构的核心,用面向对象的话来说就是基类

    struct vivi_dmaqueue       vidq;       //DMA队列

    /* Several counters */

    int                        h,m,s,us,jiffies;   //定时器定义

    char                       timestr[13];     //其它一些资源变量.

};

    像这样变义的结构在Linux C 中很普遍,这也是利用C来实现面向对象编程的强大方法。建立这个结构对象之后,所有的操作都是基于这个结构,或者这个结构派生出的来的其它结构。

    5) vivi_fh

struct vivi_fh {

    struct vivi_dev            *dev;

    /* video capture */

    struct vivi_fmt            *fmt;

    unsigned int               width,height;

    struct videobuf_queue      vb_vidq;

    enum v4l2_buf_type         type;

};

    这个结构即是vivi_dev结构的更深层次封装,基于那个结构加入了更多的描述信息,如视频制式、视频画面大小、视频缓冲队列等等。在open的时候,会把这个结构赋给file结构中的private_data域。在释放设备时注销.其它的像ioctl,mmap,read,write等等都会用到这个结构,其实整个模块的编写的cdev差不多。只是视频设备的基类是video_device,而字符设备的基类是cdev而已。

    2、数据传输方式:

    在设备与应用程序之间有三种数据传输方式:

    1)read与write这种方式,它像其它设备驱动一样,但是这种方式很慢,对于数据视频流不能满足其要求;

2)直接的内存访问,可以通过其映射方式来传输(IO数据流,交换指向缓冲区指针的方法);这是视频设备通常用的方法,采用mmap()的方法,即有内核空间里开辟内存,再在程序里把这部分的内存映射到程序空间。如果有设备内存,即直接映射到设备的内核,这种性能更高。

    3)异步IO口访问,但是这种方法在V4L2模块中还没有实现。(重要:需要确认)

     vivi中的mmap是利用第二种方法来实现的,这也是视频设备常用的方法:

static int

vivi_mmap(struct file *file, struct vm_area_struct * vma)

{

    struct vivi_fh *fh = file->private_data;

    int ret;

    dprintk (1,"mmap called, vma=0x%08lx/n",(unsigned long)vma);

    ret=videobuf_mmap_mapper(&fh->vb_vidq, vma);

    dprintk (1,"vma start=0x%08lx, size=%ld, ret=%d/n",

        (unsigned long)vma->vm_start,

        (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,

        ret);

    return ret;

}

    videobuf_mmap_mapper(&fh->vb_vidq, vma);  这个核心函数把设备的I/O内存或者设备内存映射到系统为它开辟的虚拟内存。

    3、操控设备的实现: ioctl

static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

{

    return video_usercopy(inode, file, cmd, arg, vivi_do_ioctl);  

}

    vivi_do_ioctl 这个函数里调用一些命令来设备V4L2模块中的一些结构参数来改变或者获取设备的参数

V4L2驱动的移植与应用(一)的更多相关文章

  1. V4L2驱动的移植与应用(二)

    二.V4L2的应用 下面简单介绍一下V4L2驱动的应用流程. 1.  视频采集的基本流程 一般的,视频采集都有如下流程: 2.  打开视频设备 在V4L2中,视频设备被看做一个文件.使用open函数打 ...

  2. V4L2驱动的移植与应用(二+三)【转】

    转自:http://blog.chinaunix.net/uid-10747583-id-298489.html 原文地址:http://blog.csdn.net/wxzking/archive/2 ...

  3. V4L2驱动的移植与应用(三)

    三.V4L2的demo capture.c是官方示例程序. capture.c 程序中的 process_image 函数: capture.c 程序主要是用来演示怎样使用 v4l2 接口,并没有对采 ...

  4. v4l2驱动编写篇【转】

    转自:http://blog.csdn.net/michaelcao1980/article/details/53008418 大部分所需的信息都在这里.作为一个驱动作者,当挖掘头文件的时候,你可能也 ...

  5. WIFI驱动的移植 realtek 8188

    一般我们拿到的android源代码中wifi应用层部分是好的, 主要是wifi芯片的驱动要移植并添加进去. wifi驱动的移植, 以realtek的8188etv为例到官网下载相应的驱动, 解压后可以 ...

  6. 【Linux高级驱动】触摸屏驱动的移植

    触摸屏驱动的移植 流程 注意:看框架图 1.添加input.c组件 Device Drivers  ---> Input device support  --->  Generic inp ...

  7. V4L2驱动内核文档翻译(一)

    随着一些视频或者图像硬件的复杂化,V4L2驱动也越来越趋于复杂.许多硬件有多个IC,在/dev下生成多个video设备或者其他的诸如,DVB,ALSA,FB,I2C ,IR等等非V4L2的设备.所以, ...

  8. 2.1 摄像头V4L2驱动框架分析

    学习目标:学习V4L2(V4L2:vidio for linux version 2)摄像头驱动框架,分析vivi.c(虚拟视频硬件相关)驱动源码程序,总结V4L2硬件相关的驱动的步骤:  一.V4L ...

  9. v4l2驱动文档之——streaming IO【转】

    转自:http://blog.csdn.net/zoe6553/article/details/17715441 v4l2驱动编写篇第六B--流输入输出 在本系列文章的上一期中,我们讨论了如何通过re ...

随机推荐

  1. TCP/IP协议全解析 三次握手与四次挥手[转]

    所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立.所谓四次挥手(Four-Way Wavehand) ...

  2. linux上的用户管理

    作为一个专业的服务器发行版,CentOS上存在着n多个用户,作为一个专业的运维工程师,linux的用户管理和用户组的管理是做为一个SA必不可少的工作. 下面我们就先来谈谈linux中的用户管理: us ...

  3. ABP官方文档翻译 4.4 授权

    授权 介绍 关于IPermissionChecker 定义权限 检查权限 使用AbpAuthorize特性 AbpAuthorize特性注意点 抑制授权 使用IPermissionChecker 在R ...

  4. xBIM IFC 墙壁案例

    目录 xBIM 应用与学习 (一) xBIM 应用与学习 (二) xBIM 基本的模型操作 xBIM 日志操作 XBIM 3D 墙壁案例 xBIM 格式之间转换 xBIM 使用Linq 来优化查询 x ...

  5. BZOJ 1951: [Sdoi2010]古代猪文 [Lucas定理 中国剩余定理]

    1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 2194  Solved: 919[Submit][Status] ...

  6. js事件机制

    js事件属性:

  7. 记一次酷狗音乐API的获取,感兴趣的可以自己封装开发自己的音乐播放器

    1.本教程仅供个人学习用,禁止用于任何的商业和非法用途,如涉及版权问题请联系笔者删除. 2.随笔系作者原创文档,转载请注明文档来源:http://www.cnblogs.com/apresunday/ ...

  8. python怎么实现数组增加一行或多行

    对数组增加一行或一列很简单,网上一搜一大把的事例.比如增加一行或一列: import numpy as np a = np.array([[1, 2, 3]]) row = a[0] col = a[ ...

  9. VS2010+opencv2.4.10+gsl_1.8配置实现RobHess的SIFT程序

    最近在做sift方面的毕业设计,弄了一天终于把RobHess的SIFT程序调通了.虽然网上有很多相关博文,但是我还是想把我的调试的过程跟大家分享一下.由于工程没法在博文上传,所以有需要的可以在下方留言 ...

  10. php实现粘贴截图并完成上传功能

    <?php header("Access-Control-Allow-Origin:*"); $url = 'http://'.$_SERVER['HTTP_HOST']; ...