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. 获取sap登陆用户名的中文描述

    一.业务场景: 当通过MKPF-USNAM查找ADRP-NAME_LAST时,中间缺少一个表,即USR21.否则,MKPF-USNAM不能和ADRP-PERSNUMBER直接对等. 二.解决方法: D ...

  2. Hadoop学习笔记四

    一.fsimage,edits和datanode的block在本地文件系统中位置的配置 fsimage:hdfs-site.xml中的dfs.namenode.name.dir  值例如file:// ...

  3. HDU 5608 function [杜教筛]

    HDU 5608 function 题意:数论函数满足\(N^2-3N+2=\sum_{d|N} f(d)\),求前缀和 裸题-连卷上\(1\)都告诉你了 预处理\(S(n)\)的话反演一下用枚举倍数 ...

  4. 2018/1/19 Netty学习笔记(一)

    这段时间学了好多好多东西,不过更多是细节和思想上的,比如分布式事物,二次提交,改善代码质量,还有一些看了一些源码什么的; 记录一下真正的技术学习,关于Netty的学习过程; 首先说Netty之前先说一 ...

  5. mysqldump 备份导出数据排除某张表

    就用 --ignore-table=dbname.tablename参数就行,可以忽略多个. /usr/bin/mysqldump -- -uroot -p123456 dbname --ignore ...

  6. 奥酷HTML5视频直播系统AMS6.0

    今日,北极星通自主研发的流媒体服务系统Aoku Media Server6.0发布了,将正式支持HTML5直播,这使得网页中无需有flash播放插件或者其他插件,可直接观看直播,HTML5直播也会使得 ...

  7. HashMap中的散列函数、冲突解决机制和rehash

    一.概述 散列算法有两个主要的实现方式:开散列和闭散列,HashMap采用开散列实现. HashMap中,键值对(key-value)在内部是以Entry(HashMap中的静态内部类)实例的方式存储 ...

  8. ASP.NET CORE MVC 实现减号分隔(Kebab case)样式的 URL

    ASP.NET CORE MVC 中,默认的 Route 模板是: /{controller}/{action}  .我们可以通过开启 URL 小写转换将 URL 变为小写,但此方式在 Control ...

  9. eclipse中创建一个maven项目

    1.什么是Maven Apache Maven 是一个项目管理和整合工具.基于工程对象模型(POM)的概念,通过一个中央信息管理模块,Maven 能够管理项目的构建.报告和文档. Maven工程结构和 ...

  10. ios音乐播放器demo

    闲暇时间,写了一个音乐播放器. 个人认为,基于Demo 的学习是最有效果的. 想学习的同学,欢迎下载.知识,只有在传播的时候才有价值. 不懂之处,欢迎留言询问,将热情解答. 运行图 项目结构图 Git ...