class="hide-preCode-box">

五、虚拟摄像头驱动

驱动位于drivers\media\platform\vivid文件夹下

【转载】Linux摄像头驱动1——vivid_linux 摄像头驱动_seiyaaa的博客-CSDN博客

参考资料

摄像头驱动——V4L2框架分析 - 朱果果 - 博客园 (cnblogs.com)

Linux V4l2驱动 – 框架概述 - 忆云竹 (eyunzhu.com)

深入学习Linux摄像头(二)v4l2驱动框架_v4l2_subdev_ops_JT同学的博客-CSDN博客

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/m0_61737429/article/details/129782000","extend1":"pc","ab":"new"}">>
id="article_content" class="article_content clearfix"> id="content_views" class="markdown_views prism-atom-one-dark">

class="toc">

Linux--V4L2视频驱动框架

Linux–V4L2驱动框架

一、V4L2 框架

v4l2驱动框架主要的对象有video_device、v4l2_device、v4l2_subdev、videobuf

v4l2_device和v4l2_subdev的关系:

subdev的设计目的是为了多路复用,就是用一个v4l2_device可以挂接多个v4l2_subdev。所谓的多路复用就是使用一个摄像头控制器来控制多个摄像头。比如手机上有前置和后置摄像头。

在V4L2驱动中,使用v4l2_device来表示摄像头控制器(ISP)。使用v4l2_subdev来表示具体的某一个摄像头(Sensor)。

对于手机而言 ,一般都有两个摄像头,一个前置摄像头,一个后置摄像头,其接发下图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhEUpd9Q-1679823694000)(image/Linux之V4L2视频应用驱动/20190815164203333.png)]

在V4L2驱动中,使用v4l2_device来表示摄像头控制器

使用v4l2_subdev来表示具体的某一个摄像头的I2C控制模块,进而通过其控制摄像头

v4l2_device里有一个v4l2_subdev链表,可以选择v4l2_device去控制哪一个v4l2_subdev

v4l2框架图如下:

二、V4L2驱动主要数据结构

V4l2驱动的代码在drivers\media\v4l2-core文件夹下

  1. videobufxx_xxx.c系列文件是用于实现视频的内存分配,videobuf2_xxx系列文件是对应v4l2,而videobuf_xxx系列文件是对应于v4l(video for linux version1)。
  2. v4l2-dev.c对应于video_device的实现。
  3. v4l2-device.c对应 v4l2_device的实现。
  4. v4l2-ioctl.c对应 ioctl的实现。
  5. v4l2-subdev.c对应 42vl_subdev的实现等等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gCC1pW6u-1679823694002)(image/Linux之V4L2视频应用驱动/1679802252106.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ktzeoCfO-1679823694003)(image/Linux之V4L2视频应用驱动/1679802627676.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WuDmXTKr-1679823694003)(image/Linux之V4L2视频应用驱动/1679802655865.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5z7I4O6q-1679823694004)(image/Linux之V4L2视频应用驱动/1679801446289.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cLPshbGD-1679823694005)(image/Linux之V4L2视频应用驱动/1679802947458.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1CaZzZ5-1679823694006)(image/Linux之V4L2视频应用驱动/1679803243676.png)]

三、V4L2提供的外部接口

static inline int __must_check video_register_device(struct video_device *vdev,
						     enum vfl_devnode_type type,
						     int nr)
    
void video_unregister_device(struct video_device *vdev);
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
int __must_check v4l2_device_register(struct device *dev,
				      struct v4l2_device *v4l2_dev);


void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
					     struct v4l2_subdev *sd);

void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

四、V4L2驱动框架模板

步骤:

#include <...>

static struct video_device* video_dev;
static struct v4l2_device v4l2_dev;

/* 实现各种系统调用 */
static const struct v4l2_file_operations video_dev_fops = {
	.owner		    = THIS_MODULE,
	.release        = vdev_close,
	.read           = vdev_read,
	.poll		    = vdev_poll,
	.ioctl          = video_ioctl2,
	.mmap           = vdev_mmap,
};

/* 实现各种系统调用 */
static const struct v4l2_ioctl_ops video_dev_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_enum_input    = vidioc_enum_input,
	.vidioc_g_input       = vidioc_g_input,
	.vidioc_s_input       = vidioc_s_input,
	.vidioc_streamon      = vidioc_streamon,
	.vidioc_streamoff     = vidioc_streamoff,
};

static int __init video_init(void)
{
    /* 分配并设置一个video_device */
    video_dev = video_device_alloc();
    video_dev->fops = &video_dev_fops;
    video_dev->ioctl_ops = &video_dev_ioctl_ops;
    video_dev->release = video_device_release;
    video_dev->tvnorms = V4L2_STD_525_60;
    video_dev->current_norm = V4L2_STD_NTSC_M;

    /* 注册一个v4l2_device */
    v4l2_device_register(video_dev->dev, &v4l2_dev);    
    video_dev->v4l2_dev = &v4l2_dev;

    /* 注册一个video_device字符设备 */
    video_register_device(video_dev, VFL_TYPE_GRABBER, -1);

    return 0;
}

static void __exit video_exit(void)
{
    video_unregister_device(video_dev);
    v4l2_device_unregister(&v4l2_dev);
    video_device_release(video_dev);
}


module_init(video_init);
module_exit(video_exit);
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

五、虚拟摄像头驱动

驱动位于drivers\media\platform\vivid文件夹下

【转载】Linux摄像头驱动1——vivid_linux 摄像头驱动_seiyaaa的博客-CSDN博客

参考资料

摄像头驱动——V4L2框架分析 - 朱果果 - 博客园 (cnblogs.com)

Linux V4l2驱动 – 框架概述 - 忆云竹 (eyunzhu.com)

深入学习Linux摄像头(二)v4l2驱动框架_v4l2_subdev_ops_JT同学的博客-CSDN博客

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/m0_61737429/article/details/129782000","extend1":"pc","ab":"new"}">>
注:本文转载自blog.csdn.net的ssq不是上上签的文章"https://blog.csdn.net/m0_61737429/article/details/129782000"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!