linux中的USB摄像头驱动(应用层)(基于V4L2)

2023-11-01

V4L2 是 Video4Linux2 的缩写,是 Linux 内核中的一个视频设备驱动接口。 

 USB-V4L2 初始化流程

1.打开设备节点 open

2.配置参数:分辨率,fps,格式 ioctl

3.请求分配帧缓存->地址映射

4.加入队列中

/**
  ******************************************************************************
  * @file    usbcamera.c
  * @author  CJ
  * @version V1.0
  * @date    2020/8
  * @brief
  ******************************************************************************
  * @attention
  ******************************************************************************
  */

#include "usbcamera.h"
#include <sys/types.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <linux/fb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <dirent.h>
#include <stdlib.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/time.h>
#include <assert.h>
#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static UsbCameraSyspara g_cameraSyspara;

bool usbCamera_init()
{
    /* 1、打开设备节点 */
    g_cameraSyspara.fd = open("/dev/video0", O_RDWR);
    if(g_cameraSyspara.fd < 0)
    {
        printf("Camera device failed to open !\n");
        return false;
    }

    /* 2、定义v4l2_format结构体变量并完成赋值 */
    memset(&g_cameraSyspara.tV4l2Fmt, 0, sizeof(struct v4l2_format));
    g_cameraSyspara.tV4l2Fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;	//视频捕获
    g_cameraSyspara.tV4l2Fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

    //设置输出图像尺寸
    g_cameraSyspara.tV4l2Fmt.fmt.pix.width  = 1280;
    g_cameraSyspara.tV4l2Fmt.fmt.pix.height = 720;
    g_cameraSyspara.tV4l2Fmt.fmt.pix.field  = V4L2_FIELD_ANY;	//驱动自行选择合适的格式(逐行、隔行)接收images

    /* 3、调用IOCTL完成以上参数配置 */
    if(ioctl(g_cameraSyspara.fd, VIDIOC_S_FMT, &g_cameraSyspara.tV4l2Fmt) != 0)
    {
        printf("tV4l2Fmt failed !\n");
        return false;
    }
    printf("w = %d, h = %d\n", g_cameraSyspara.tV4l2Fmt.fmt.pix.width, g_cameraSyspara.tV4l2Fmt.fmt.pix.height);
    printf("size = %d\n", g_cameraSyspara.tV4l2Fmt.fmt.pix.sizeimage);
    printf("format = %x, nv12 = %x\n", g_cameraSyspara.tV4l2Fmt.fmt.pix.pixelformat, V4L2_PIX_FMT_YUYV);

    g_cameraSyspara.RGBData=(unsigned char*)malloc(g_cameraSyspara.tV4l2Fmt.fmt.pix.sizeimage);

    /* 4、定义v4l2_request结构体变量并完成赋值 */
    memset(&g_cameraSyspara.tV4l2ReqBuffs, 0, sizeof(struct v4l2_requestbuffers));

    g_cameraSyspara.tV4l2ReqBuffs.count   = 10;								//帧缓存个数
    g_cameraSyspara.tV4l2ReqBuffs.memory  = V4L2_MEMORY_MMAP;				//该缓存支持映射
    g_cameraSyspara.tV4l2ReqBuffs.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;	//视频捕获支持

    /* 5、调用IOCTL请求分配帧缓存 */
    ioctl(g_cameraSyspara.fd, VIDIOC_REQBUFS, &g_cameraSyspara.tV4l2ReqBuffs);

    /* 6、将帧缓存映射至进程空间 */
    unsigned int i;

    for(i = 0;i < g_cameraSyspara.tV4l2ReqBuffs.count;i++)
    {
        memset(&g_cameraSyspara.tV4l2Buf, 0, sizeof(struct v4l2_buffer));

        g_cameraSyspara.tV4l2Buf.index = i;								//帧缓存编号
        g_cameraSyspara.tV4l2Buf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;	//视频捕获支持
        g_cameraSyspara.tV4l2Buf.memory = V4L2_MEMORY_MMAP;				//内存映射支持

        //调用IOCTL获取每个帧缓存的相关信息,其中长度、偏移量将作为mmap的参数
        ioctl(g_cameraSyspara.fd, VIDIOC_QUERYBUF, &g_cameraSyspara.tV4l2Buf);

        //映射空间地址
        g_cameraSyspara.MyVideBuf[i] = (unsigned char *)mmap(0, g_cameraSyspara.tV4l2Buf.length, PROT_READ,MAP_SHARED, g_cameraSyspara.fd, g_cameraSyspara.tV4l2Buf.m.offset);

    }

    /* 7、将帧缓存加入队列循环采集 */
    for (i = 0; i <g_cameraSyspara.tV4l2ReqBuffs.count; i++)
    {
        memset(&g_cameraSyspara.tV4l2Buf, 0, sizeof(struct v4l2_buffer));
        g_cameraSyspara.tV4l2Buf.index = i;
        g_cameraSyspara.tV4l2Buf.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        g_cameraSyspara.tV4l2Buf.memory = V4L2_MEMORY_MMAP;
        ioctl(g_cameraSyspara.fd, VIDIOC_QBUF, &g_cameraSyspara.tV4l2Buf);
    }

    struct v4l2_streamparm Stream_Parm;

    Stream_Parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;

    int ret = ioctl(g_cameraSyspara.fd, VIDIOC_G_PARM, &Stream_Parm);
    printf("ret = %d >>!!!!!!!!!!!!!!!!!!: Frame rate: %u/%u\n",ret, Stream_Parm.parm.capture.timeperframe.numerator,
                                     Stream_Parm.parm.capture.timeperframe.denominator);
    Stream_Parm.parm.capture.timeperframe.numerator = 1;
    Stream_Parm.parm.capture.timeperframe.denominator = 15;
    printf("ret = %d >>!!!!!!!!!!!!!!!!!!: Frame rate: %u/%u\n",ret, Stream_Parm.parm.capture.timeperframe.numerator,
                                     Stream_Parm.parm.capture.timeperframe.denominator);
    ret = ioctl(g_cameraSyspara.fd, VIDIOC_S_PARM, &Stream_Parm);

    printf("ret = %d >>!!!!!!!!!!!!!!!!!!: Frame rate: %u/%u\n",ret, Stream_Parm.parm.capture.timeperframe.numerator,
                                     Stream_Parm.parm.capture.timeperframe.denominator);
    return true;
}

bool openUsbCamera()
{
    int iType = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    /* 启动摄像头开始采集 */
    if(ioctl(g_cameraSyspara.fd, VIDIOC_STREAMON, &iType) == 0)
    {
        return true;
    }

    return false;
}

bool clsoeUsbCamera()
{
    int iType = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if(ioctl(g_cameraSyspara.fd, VIDIOC_STREAMOFF, &iType) == 0)
    {
        return true;
    }

    return false;
}

unsigned char *getUsbCameraImage(unsigned int *size)
{
    fd_set readfds;
    unsigned int ListNum;

    FD_ZERO(&readfds);
    FD_SET(g_cameraSyspara.fd,&readfds);

    struct timeval tv;
    unsigned int time1, time2;
    gettimeofday(&tv, NULL);
    time1 = tv.tv_sec*1000000+tv.tv_usec;

    select(g_cameraSyspara.fd+1, &readfds, NULL, NULL, NULL);

    gettimeofday(&tv, NULL);
    time2 = tv.tv_sec*1000000+tv.tv_usec;
    printf("time = %dms\n", (time2-time1)/1000);



    memset(&g_cameraSyspara.tV4l2Buf, 0, sizeof(struct v4l2_buffer));
    g_cameraSyspara.tV4l2Buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    g_cameraSyspara.tV4l2Buf.memory  = V4L2_MEMORY_MMAP;

    /* read data */
    ioctl(g_cameraSyspara.fd, VIDIOC_DQBUF, &g_cameraSyspara.tV4l2Buf);
    ListNum = g_cameraSyspara.tV4l2Buf.index;	//数据地址 MyVideBuf[ListNum]

    memset(&g_cameraSyspara.tV4l2Buf, 0, sizeof(struct v4l2_buffer));
    g_cameraSyspara.tV4l2Buf.index  = ListNum;
    g_cameraSyspara.tV4l2Buf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    g_cameraSyspara.tV4l2Buf.memory = V4L2_MEMORY_MMAP;
    ioctl(g_cameraSyspara.fd, VIDIOC_QBUF, &g_cameraSyspara.tV4l2Buf);  //将缓冲区再次放入队列

    *size = g_cameraSyspara.tV4l2Fmt.fmt.pix.sizeimage;
    printf("format cnt = %d\n", ListNum);

    return g_cameraSyspara.MyVideBuf[ListNum];
}
/**
  ******************************************************************************
  * @file    usbcamera.h
  * @author  CJ
  * @version V1.0
  * @date    2020/8
  * @brief
  ******************************************************************************
  * @attention

  ******************************************************************************
  */
#ifndef USB_CAMERA_H
#define USB_CAMERA_H

#include "stdbool.h"
#include <linux/videodev2.h>

typedef struct _UsbCameraSyspara
{
    int fd;
    unsigned char *RGBData;              //解码
    struct v4l2_format  tV4l2Fmt;
    struct v4l2_buffer tV4l2Buf;			//缓存区的相关信息
    unsigned char* MyVideBuf[10];			//映射的空间地址
    struct v4l2_requestbuffers tV4l2ReqBuffs;
}UsbCameraSyspara;

bool usbCamera_init();
bool openUsbCamera();
bool clsoeUsbCamera();
unsigned char *getUsbCameraImage(unsigned int *size);
#endif

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux中的USB摄像头驱动(应用层)(基于V4L2) 的相关文章

  • 选择多个模式的 awk 代码

    这是我的输入文件 比如modified txt r4544 n479826 2012 08 28 07 12 33 0400 Tue 28 Aug 2012 1 line Changed paths M branches 8 6 0 con
  • Linux shell 标题大小写

    我正在编写一个 shell 脚本并有一个如下所示的变量 something that is hyphenated 我需要在脚本中的各个点使用它 如下所示 something that is hyphenated somethingthati
  • 在哪里存储 asp.net mvc 项目的图像以及如何从 site.master 引用它们

    我有一个新的 asp net mvc 项目 我正在尝试找出存储图像的最佳位置 以及如何从 site master 引用它们 如果我有一个标题图像 我想显示在所有页 建议或最佳实践 我通常做的是在我的内容文件夹中创建一个 图像 文件夹 只要保
  • 如何使用 PHP 在邮件正文中发送 Base64 图像?

    我正在尝试使用下面的代码使用 PHP 发送一封正文上包含 base64 图像的电子邮件 但该图像永远不会出现 如果我更改为 URL 它可以工作 但它不能与 base64 一起使用 我只在新页面上测试了base64 img src base6
  • 在 Magento 中使用缩略图切换基本图像

    在定制的产品视图页面上 我正在处理基本图像 大图像 和缩略图列表 这些缩略图是与媒体库中的产品相关的其他图像 它们只是普通图像 而不是定义的图像 缩略图 我的任务是获取它 以便当您单击缩略图时它会更改上面的基本图像 我已经可以工作了 但是我
  • Tk 初始化失败:无显示名称且无 $DISPLAY 环境变量

    我试图从 Ubuntu 终端调用 Centos 服务器上的工具 我收到以下错误 Tk 初始化失败 没有显示名称 也没有 DISPLAY 环境变量 请帮我解决这个问题 提前致谢 连接到你的 CentOS 机器ssh Y其中 每man ssh
  • Python 线程与 Linux 中的多处理

    基于此question https stackoverflow com questions 807506 threads vs processes in linux我假设创建新流程应该几乎和创造新线程在Linux中 然而 很少的测试显示出截
  • 在linux中使用setcap [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 要将 cap net raw 功能添加到 例如 bin ping 我们使用以下命令 setcap cap net raw ep bin ping ep
  • 终止 ssh 会话会终止正在运行的进程

    我正在使用 ssh 连接到我的 ubuntu 服务器 我使用命令启动编码程序 然而 似乎当我的 ssh 会话关闭时 因为我在进入睡眠状态的笔记本电脑上启动它 有没有办法避免这种情况 当然 阻止我的笔记本电脑休眠并不是永久的解决方案 运行你的
  • 更新表格视图图像子视图中的图像的最佳方法是什么?

    具体来说 如何从 uitableview 单元格中获取图像子视图 我的表视图从网络异步获取数据 当我第一次创建图像视图时 我通过以下方式添加了视图 imageView setImage image cell addSubview image
  • 如何更改Linux服务器中的MySQL表名不区分大小写?

    我正在开发一个旧网站 该网站曾经托管在 Apple 服务器上 当它迁移到新的 Linux 服务器时 它停止工作 我很确定这是因为 php 脚本中使用的所有 MySQL 查询对于表名都有不同的大小写组合 我不知道为什么原始开发人员在创建表名或
  • WPF 中的图像变得模糊

    我正在使用 C 在 WPF 中开发应用程序 我将图像放入 WrapPanel 中 并在带有一个边框的网格内显示 并在按钮中使用图像 问题是我的图像控件失去了质量 我无法在这里发布我的图片 所以我只是在这里描述 I used SnapsToD
  • 使用 xargs 时如何获取退出代码(并行)

    我制作了一个用于启动并行 rsync 进程的脚本 bin bash LIST 1 DEST DIR 2 RSYNC OPTS 3 echo rsyncing From SRC DIR To DEST DIR RSYNC OPTS RSYNC
  • 如何搭建qtwayland?

    我花了一整天的时间尝试使用QtWayland Compositor 1 0在 Qt 创建者中 我已经遵循了从那里开始的所有步骤https wiki qt io QtWayland https wiki qt io QtWayland但我收到
  • 如何从 swagger 文档生成静态 html 文件?

    我创建了一个 Swagger 文档yaml文件位于 api swagger swagger yaml 现在我想分享一个静态 HTML 文档及其定义 但它已在招摇项目 https github com swagger api swagger
  • 通过Javascript确定图像文件大小+尺寸?

    作为网络应用程序的一部分 一旦图像被下载并呈现在网页上 我需要确定图像的文件大小 kb 和浏览器上下文中的分辨率 这样我就可以在页面上显示该信息 显然 这需要在客户端完成 必须能够在没有 ActiveX 控件或 Java 小程序的情况下解决
  • AMD OpenCL 在 Linux 上工作所需的最小必要文件子集是什么?

    我已经使用 buildroot 构建了 Linux 内核 我已将开源 amdgpu 驱动程序和所需的固件合并到其中 驱动程序很好 检测 GPU 模式设置运行良好 调整 小文本 的分辨率 启动后会显示命令行 现在我需要运行 OpenCL 程序
  • php 发送带有图像的电子邮件

    我正在尝试发送一封带有图片的电子邮件 我的电子邮件正文是 当我收到电子邮件时 我看不到图片 相反 我 看 img src http planet earth bogus us icons secret pictures gif 我知道这是因
  • 导出多个 LD_LIBRARY_PATH 的正确方法

    对于linux的使用 我是一个新手 根据有关我的项目的指南 我必须多次导出 LD LIBRARY PATH 并且我不确定是否不覆盖它们 Cupti Tensorflow CUDAit export LD LIBRARY PATH LD LI
  • Android - 带图像的按钮 - 禁用按钮时图像变暗

    在 Android 中 我有一个包含图像和文本的按钮 禁用该按钮时 文本会自动变灰 但图像保持不变 当按钮被禁用时是否可以使图像变暗而不需要两个单独的图像 在您的代码中 您还可以使用彩色滤光片 http developer android

随机推荐

  • python小游戏——跑酷小恐龙代码开源

    作者 小刘在这里 每天分享云计算网络运维课堂笔记 努力不一定有回报 但一定会有收获加油 一起努力 共赴美好人生 夕阳下 是最美的 绽放 愿所有的美好 再疫情结束后如约而至 目录 一 效果呈现 二 主代码 三 cfg 四 README 一 效
  • Python配置免费的OCR图片识别文字(附代码)

    今天刷帖刷到一个网站 可以免费OCR识别 但是具体的次数我没有计算 文档上也没有具体说明 那么我们一起来看看吧 首先网址在这里 点我直达 1 我们需要注册一个账号 获取非常重要的参数 ColaKey 2 接着我们看一下文档说明 可跳过 点我
  • 用Python实现队列(queue)

    一 队列的定义 队列 一种先进先出 FIFO First in First Out 的线性结构 即在队列的尾部入队 在队列的头部出队 入队 即队列添加成员 在队列的尾部完成 出队 即队列删除成员 在队列的头部完成 在创建队列时 一般以数组为
  • 登陆界面的测试

    一 功能 1 用户名和密码 用户名和密码的合法性 长度 字符 空 用户名和密码的一致性 验证码的合法性和一致性 2 登陆功能 跳转正确 3 页面其他链接 如忘记密码 4 记住用户名 记住密码的功能 5 输入框是否支持复制和粘贴 6 密码显示
  • 图像分割:Python的SLIC超像素分割

    图像分割 Python的SLIC超像素分割 1 什么是超像素 2 为什么超像素在计算机视觉方面有重要的作用 3 简单线性迭代聚类 SLIC 4 效果图 5 源码 参考 1 什么是超像素 在单个或多个通道中 图像表示为像素网格 我们采用这些M
  • mysql8 java Could not create connection to database server. Attempted reconnect 3 times问题

    最近照着网上的一个博主的例子 学习ssm 结果一个mysql8 搞得我都崩溃了 各种连不上 总结一下出错原因 1 maven中的jdbc连接jar包 版本也要换成高版本
  • Linux基本权限(详解)

    目录 文件权限位 更改文件权限 chmod指令 chown指令 chgrp指令 数字权限 umask命令 文件权限位 显示当前目录下文件的详细信息 ls l 也可以写成 ll Linux下文件的权限位共有十个 按照1333来划分 第一位代表
  • 服务器操作系统比较,服务器操作系统比较

    服务器操作系统比较 内容精选 换一换 Atlas 800 训练服务器 型号 9000 安装上架 服务器基础参数配置 安装操作系统等操作请参见 Atlas 800 训练服务器 用户指南 型号9000 风冷 或 Atlas 800 训练服务器
  • 特征筛选3——卡方检验筛选特征(单变量筛选)

    sklearn文档 https scikit learn org stable modules generated sklearn feature selection chi2 html 卡方检验只适用分类任务 用来检验特征与y是否相互独立
  • java获取response与request

    java获取response与request 方式一 监听 web xml
  • Makefile 多个目标匹配的问题

    在windows下直接使用mingw32 make ZTHREAD A the static link library file of ZThread ZTHREAD A F ZJ tools cpp libs ZThread 2 3 2
  • Flutter 文字渐变色

    目前在做的项目需要用到渐变文字的需求 但是都用图的话 会导致包很大 所以打算自己去写一个渐变 本次渐变用到的组件是ShaderMask这个组件来完成咱们的文字渐变色 代码实现 text里面的文字需要设置为白色字体 ShaderMask sh
  • [ 云计算 华为云 ] 解决办法:如何更换华为云云耀云服务器L实例的镜像

    文章目录 问题描述 分析原因 解决办法 文末送书 ANSYS Workbench项目分析与案例实操详解 博主推荐理由 本书内容简介 本书作者简介 废话在前 直接看解决办法的这段可以过 讲道理 一般情况下云服务器 镜像是随便更换的 但是我发现
  • 华为OD机试 - 查找众数及中位数(Java)

    题目描述 众数是指一组数据中出现次数量多的那个数 众数可以是多个 中位数是指把一组数据从小到大排列 最中间的那个数 如果这组数据的个数是奇数 那最中间那个就是中位数 如果这组数据的个数为偶数 那就把中间的两个数之和除以2 所得的结果就是中位
  • count(*)和group by的用法

    https www cnblogs com gongchengshiwhl p 7994761 html https blog csdn net weixin 44938368 article details 109614917 1 cou
  • 将设计稿图标制作成iconfont(ps cs6 + ai cs6)

    项目开发中需要用到icon iconfont网站上找的icon风格各式各样 就想着把设计稿的图标直接转成icon就好了 1 先在ps装一个脚本 save ps to svg1 0 jsx 放在ps安装目录下的 Presets Scripts
  • python Opencv和pyautogui实现自动识图点击

    python Opencv和pyautogui实现自动识图点击 1 导入python及其他模块 匹配类是上一章博客内容 pyautogui自带的图片匹配效果不是很理想 就使用Opencv的图片匹配来实现图片的定位 python 使用模版匹配
  • Vue.js 学习笔记十三:Vue Router 之导航守卫

    目录 导航守卫 全局前置守卫 全局后置钩子 路由独享的守卫 组件内的守卫 导航守卫 我们来考虑一个需求 在一个 SPA 应用中 如何改变网页的标题呢 网页标题是通过
  • linux安装php7的方法

    1 安装依赖包 1 安装依赖包 1 yum install y gcc gcc c make zlib zlib devel pcre pcre devel libjpeg libjpeg devel libpng libpng devel
  • linux中的USB摄像头驱动(应用层)(基于V4L2)

    V4L2 是 Video4Linux2 的缩写 是 Linux 内核中的一个视频设备驱动接口 USB V4L2 初始化流程 1 打开设备节点 open 2 配置参数 分辨率 fps 格式 ioctl 3 请求分配帧缓存 gt 地址映射 4