/* 仿照vivi.c */
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/mutex.h>
#include <linux/videodev2.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/highmem.h>
#include <linux/freezer.h>
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
static struct v4l2_format myvivi_format;
static int myvivi_vidioc_querycap(struct file *file, void  *priv, struct v4l2_capability *cap)
{strcpy(cap->driver, "myvivi");strcpy(cap->card, "myvivi");cap->version = 0x0001;cap->capabilities =  V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;return 0;
}
/* 列举支持哪种格式 */
static int myvivi_vidioc_enum_fmt_vid_cap(struct file *file, void  *priv, struct v4l2_fmtdesc *f)
{if (f->index >= 1)return -EINVAL;strcpy(f->description, "4:2:2, packed, YUYV");f->pixelformat = V4L2_PIX_FMT_YUYV;return 0;
}
/* 返回当前所使用的格式 */
static int myvivi_vidioc_g_fmt_vid_cap(struct file *file, void *priv,struct v4l2_format *f)
{memcpy(f, &myvivi_format, sizeof(myvivi_format));return (0);
}
/* 测试驱动程序是否支持某种格式 */
static int myvivi_vidioc_try_fmt_vid_cap(struct file *file, void *priv,struct v4l2_format *f)
{unsigned int maxw, maxh;enum v4l2_field field;if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV)return -EINVAL;field = f->fmt.pix.field;if (field == V4L2_FIELD_ANY) {field = V4L2_FIELD_INTERLACED;} else if (V4L2_FIELD_INTERLACED != field) {return -EINVAL;}maxw  = 1024;maxh  = 768;/* 调整format的width, height, * 计算bytesperline, sizeimage*/v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,&f->fmt.pix.height, 32, maxh, 0, 0);f->fmt.pix.bytesperline =(f->fmt.pix.width * 16) >> 3;f->fmt.pix.sizeimage =f->fmt.pix.height * f->fmt.pix.bytesperline;return 0;
}
static int myvivi_vidioc_s_fmt_vid_cap(struct file *file, void *priv,struct v4l2_format *f)
{int ret = myvivi_vidioc_try_fmt_vid_cap(file, NULL, f);if (ret < 0)return ret;memcpy(&myvivi_format, f, sizeof(myvivi_format));return ret;
}
static const struct v4l2_ioctl_ops myvivi_ioctl_ops = {// 表示它是一个摄像头设备.vidioc_querycap      = myvivi_vidioc_querycap,/* 用于列举、获得、测试、设置摄像头的数据的格式 */.vidioc_enum_fmt_vid_cap  = myvivi_vidioc_enum_fmt_vid_cap,.vidioc_g_fmt_vid_cap     = myvivi_vidioc_g_fmt_vid_cap,.vidioc_try_fmt_vid_cap   = myvivi_vidioc_try_fmt_vid_cap,.vidioc_s_fmt_vid_cap     = myvivi_vidioc_s_fmt_vid_cap,
#if 0    /* 缓冲区操作: 申请/查询/放入队列/取出队列 */.vidioc_reqbufs       = myvivi_vidioc_reqbufs,.vidioc_querybuf      = myvivi_vidioc_querybuf,.vidioc_qbuf          = myvivi_vidioc_qbuf,.vidioc_dqbuf         = myvivi_vidioc_dqbuf,// 启动/停止.vidioc_streamon      = myvivi_vidioc_streamon,.vidioc_streamoff     = myvivi_vidioc_streamoff,
#endif
};
static const struct v4l2_file_operations myvivi_fops = {.owner     = THIS_MODULE,.ioctl      = video_ioctl2, /* V4L2 ioctl handler */
};
static struct video_device *myvivi_device;
static void myvivi_release(struct video_device *vdev)
{
}
static int myvivi_init(void)
{int error;/* 1. 分配一个video_device结构体 */myvivi_device = video_device_alloc();/* 2. 设置 */myvivi_device->release = myvivi_release;myvivi_device->fops    = &myvivi_fops;myvivi_device->ioctl_ops = &myvivi_ioctl_ops;/* 3. 注册 */error = video_register_device(myvivi_device, VFL_TYPE_GRABBER, -1);return error;
}
static void myvivi_exit(void)
{video_unregister_device(myvivi_device);video_device_release(myvivi_device);
}
module_init(myvivi_init);
module_exit(myvivi_exit);
MODULE_LICENSE("GPL");

写一个虚拟摄像头驱动3相关推荐

  1. V4L2(三)编写虚拟摄像头驱动

    内核版本:linux-3.5 开发板:tiny4412 概述 前面简单分析了内核中虚拟摄像头驱动 vivi 的框架与实现,本文参考 vivi 来写一个虚拟摄像头驱动,查询.设置视频格式相对简单,难点在 ...

  2. 虚拟摄像头驱动原理及开发

    (以下所说的都是基于微软的windows平台)                类似功能的产品,如著名的e2eSoft的 VCam,国内新浪的9518虚拟视频, 新浪的虚拟视频是DirectShow应用 ...

  3. 二十四、V4L2框架主要结构体分析和虚拟摄像头驱动编写

    一.V4L2框架主要结构体分析 V4L2(video for linux version 2),是内核中视频设备的驱动框架,为上层访问视频设备提供统一接口. V4L2整体框架如下图: 图中主要包括两层 ...

  4. 深入学习Linux摄像头(三)虚拟摄像头驱动分析

    深入学习Linux摄像头系列 深入学习Linux摄像头(一)v4l2应用编程 深入学习Linux摄像头(二)v4l2驱动框架 深入学习Linux摄像头(三)虚拟摄像头驱动分析 深入学习Linux摄像头 ...

  5. 第1.4节_摄像头驱动_从零写一个虚拟驱动

    1.1th(搭建起虚拟摄像头驱动框架) /* 仿照vivi.c */ #include <linux/module.h> #include <linux/delay.h> #i ...

  6. Linux摄像头驱动第一篇之虚拟摄像头驱动vivi.c

    本文学习自韦东山老师的摄像头驱动模块 目录 一 摄像头驱动程序学习切入点以及V4L2模型概览 二 简析虚拟视频驱动 VIVI.C 2.1 初始化.设置.注册过程 2.2 简析vivi.c的open,r ...

  7. [转]写一个块设备驱动(第八章)

    第8章 +---------------------------------------------------+ |                 写一个块设备驱动                 ...

  8. 手把手带你写一个中断输入设备驱动

    今天群里有人问,要开始驱动开发的话从什么开始比较好. 我说,应该开始去摸索触摸屏驱动,现在我想了下,触摸屏驱动可能会难了些,但是从一个GPIO开始,我觉得一定是一件很容易的事情. 所以这篇文章就来了. ...

  9. [转]写一个块设备驱动(第一章)

    写一个块设备驱动1,2(转) 2009/09/03 15:42 第1章 +---------------------------------------------------+ |          ...

最新文章

  1. 在CentOS 6.8 x86_64的nginx 1.10.3上开启http2功能
  2. linux触摸屏两指缩放_自定义TextView实现单指拖动,双指缩放旋转
  3. 洛谷P3616 富金森林公园
  4. 思科路由器由于IP INPUT进程导致cpu负荷高的判断方法
  5. Sphinx——自动生成Python文档
  6. 将数据导入到mysql_Mongodb数据导入到mysql
  7. 【图像算法】七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)...
  8. jsonp 获取图片文件流_【国际IT专场】Laravel Media Library多媒体文件的上传与管理...
  9. CTF-Crypto-RSA整理
  10. jsp九大内置对象所属类及作用
  11. ST NFC+MTK平台
  12. SVN 小乌龟(TortoiseSVN)本地文件更新报错Another process is blocking the working copy database 解决方法
  13. Kali利用Redis未授权漏洞入侵服务器
  14. 苹果x人脸识别突然失灵_苹果官网维修进度显示下图“服务正在进行中”是代表诊断通过帮你维修手机了吗。...
  15. App Store评论优化,让你的APP评论上涨
  16. Android TextView 字体 加粗以及判断是否加粗
  17. Element-UI学习之旅-Border边框及图标
  18. 常用的一些LDO芯片及使用
  19. 《脱颖而出——成功网店经营之道》一1.3 两个人的战争:二东之争
  20. 原神手游怎么用电脑玩 原神模拟器玩法教程

热门文章

  1. 卷积神经网络的卷积及池化(pooling)
  2. 班主任寒假收心话术发家长群
  3. NNLM(神经网络语言模型)
  4. AE实现矢量数据的基本操作_简单渲染(IRender)
  5. 百度账号服务器内部错误是怎么回事,浅析,HTTP500内部服务器错误,怎么解决...
  6. 新年贺词新年祝福短信
  7. 如何在虚拟计算机添加3块硬盘,win7旗舰版下如何建立虚拟硬盘
  8. java如何导出et文件_Springboot使用POI实现导出Excel文件示例
  9. Windows误删注册表恢复方法
  10. 或将不再公开?第五轮学科评估结果陆续放出,对保研有哪些影响?