视频输入设备-V4L2的开发流程简述
一、摄像头的工作原理与应用
基本概念
V4L2的全称是Video For Linux Two,其实指的是V4L的升级版,是linux系统关于视频设备的内核驱动,同时V4L2也包含Linux系统下关于视频以及音频采集的接口,只需要配合对应的视频采集设备就可以实现对视频以及音频进行采集。

Linux下包含V4L2的接口资源(宏定义、枚举、请求码等),这些资源被包含在一个头文件中,头文件名字叫做videodev2.h,头文件路径:/usr/include/linux/videodev2.h,用户需要在程序中使用该头文件 #include <linux/videodev2.h>
在这个头文件的末尾部分有很多关于视频采集的请求码,这些请求码通过一个系统调用中的ioctl()函数,通过发送不同请求码给内核驱动,内核驱动会返回对应的信息。

ioctl函数使用说明
头文件:#include <sys/ioctl.h>
函数原型:int ioctl(int fd, unsigned long request, ...); 变参函数
函数参数
参数一:fd 需要操作的文件的描述符 open函数的返回值
参数二:request 传递给设备驱动的对应请求
.....
返回值 成功 返回0 失败 返回-1
注意:ioctl是专门作为设备输入输出操作的系统调用,需要传入对应设备的命令码,不同的设备会定义不同的命令码

开发流程
Video for Linux Two是一套针对不同类型视频设备及相关数据的关联驱动规范。设备的类型决定了通过read()和write()传递的数据类型,以及驱动支持的ioctl命令集。已经定义或计划定义几种设备类型如下图:

由于需要使用摄像头捕捉画面,所以需要调用open函数打开摄像头,插入摄像头之后Linux系统提供的摄像头的设备节点是 /dev/video7。(每个人插入摄像头之后提供的设备节点可能不一样,需要注意)

以下代码都是对V4L2原码的解读以及注释:
(1) 使用视频采集设备之前需要提前打开设备,利用Linux系统的open函数打开设备文件!

(2)根据用户需求设置摄像头采集画面的格式,利用v4l2提供的struct v4l2_format结构体!
现在市面的摄像头的采集画面的格式有多种,如果购买的摄像头价格比较便宜,则一般采集的画面的格式都是YUV4:2:2格式,YUYV(YUV4:2:2)格式指的是每4个字节代表两个像素点,所以YUYV格式的图像一个像素点大小为2个字节,并且Y和UV交替存储。
YUV是一种常用的颜色编码格式,主要用在电视系统和模拟视频领域,也是使用3个分量表示颜色,Y指的是亮度,U和V指的是色度,用来描述影像色彩和饱和度。YUV格式大体上分为两大类:平面格式(YUV分量分开存)和打包格式(YUV分量合在一起按照一定的编码格式存)。
主流的采样方式有三种:YUV4:2:2 、YUV4:2:0、YUV4:4:4
YUV4:2:0 : 对于每4个像素(2*2的块),共享一组U和Y值,每个像素都有独立的Y值
YUV4:4:4 :对于每个像素,Y、U、V都有独立的采样值
YUV4:2:2 :对于每2个水平相邻的像素,共享一组U和V值,而每个独立的像素都有一个Y值

如果想要把YUV格式的图像显示到LCD屏幕上就要做相应的转换,如下图。

在摄像头采集画面之前,需要设置摄像头采集画面的参数,比如帧宽度、帧高度、图像格式等,要通过一个结构体struct v4l2_format进行设置,注意,当前使用的摄像头只支持YUYV格式的采集(这里我的摄像头只支持YUYV格式的采集)。

V4L2设备以流的形式处理多媒体数据,流由包含格式化数据的缓冲区组成。一个设备可以有多个同时的流。大多数流是视频图像,但也可能存在其他类型。v4l2_format结构包含一个联合体,用于处理不同的格式结构,以便以后可以添加更多。应用程序必须始终设置类型字段,用于指示正在使用的格式类型以及它适用于哪个流。
(3)向v4l2驱动申请帧缓存区,利用帧缓存循环存储摄像头捕获到的图像,一般申请4个!
需要定义struct v4l2_requestbuffers结构体变量,在这个结构体中可以设置需要申请的帧缓存的数量,一般申请4个帧缓存,这样每个帧缓存都会存储一帧图像,循环调用就可以提高视频采集的效率。

内存映射方式:有以下三种
直接读取:利用read、write,直接对内存数据不断拷贝,占用大量内存空间(不推荐)
内存映射:利用mmap函数把驱动的帧缓存映射到应用程序的内存中,效率高(推荐)
用户指针:内存片段由应用程序自己分配,需要设置V4L2_MEMORY_USERPTR(不推荐)

(4)获取申请成功的每个帧缓存的参数信息,并且为每个帧缓存申请捕获图像大小的堆内存
想要从帧缓存中得到采集到的数据,需要知道从驱动中申请的每个缓存块的信息(缓存块地址、缓存块的大小),所以需要定义struct v4l2_buffer结构体变量存储,并把缓存进行内存映射。

(5)为了让摄像头可以把采集的图像存储在申请的帧缓存中,所以需要把申请的帧缓存入队

(6)缓存区入队之后,用户可以启动图像捕捉,然后摄像头就可以循环的把图像存入缓存区

(7)依次把缓存区出队,然后用户对缓存区存储的图像数据进行处理,但是要实现超时处理

把缓存块按照索引依次出队,然后保存缓存块中的数据后,再把缓存块重新入队,但是需要使用select()函数实现多路复用检测是否采集到数据,实现超时处理。
select函数一般用于网络编程,该函数可以帮用户监听多个文件描述符的状态,如果监听的多个文件中的某个文件的描述符发生的改变(读写或异常),select函数可以及时通知进程。

(8)把出队的缓存区中的YUYV格式的颜色分量转换为RGB格式的颜色分量并显示在LCD上

本次使用的摄像头只支持采集YUYV格式的图像,而在LCD屏上显示的是RGB数据,所以需要把采集到的图像转换成RGB。RGB对于大家来说并不陌生,看到的光就是由RGB三种颜色按一定比例混合得到,是使用红、绿、蓝三原色的亮度来表示颜色,三种颜色互相叠加实现混色,所以适用于显示屏等器件。在LCD屏中每个像素点的颜色都是由RGB组成的,LCD屏中一个像素点4个字节,RGB分别占用一个字节,每个字节的取值范围都是0~255,不过又加入了透明度,所以LCD屏中一个像素点就是由ARGB构成的。
下面的代码不是V4L2的原码,是我写的将一个YUV格式的像素点转换为RGB格式的函数
===============================================

如果可以实现一个像素点的格式转换,则只需要根据摄像头采集画面的宽和高把所有的像素点依次进行转换。
如果一帧YUV格式的图像已经转换为一帧RGB格式的图像,则只需要把RGB格式图像的像素点拷贝到LCD屏的像素点中即可。

提示:如果需要项目原码可以在我的项目专栏中找到
相关文章:
视频输入设备-V4L2的开发流程简述
一、摄像头的工作原理与应用 基本概念 V4L2的全称是Video For Linux Two,其实指的是V4L的升级版,是linux系统关于视频设备的内核驱动,同时V4L2也包含Linux系统下关于视频以及音频采集的接口,只需要配合对应的视频采集设备就可以实…...
python基础课程整理--元组的基础
好的,下面详细列举Python元组的特点,包括取值、增加、修改和删除操作: 元组(Tuple) 元组(Tuple)的特点如下: 定义:使用圆括号 () 包裹,可以存储多个元素。…...
Windows设置目录及子目录大小写不敏感暨git克隆报错同名文件已存在的解决办法
在Windows系统中设置目录及其子目录为大小写不敏感,可以通过以下步骤完成: 步骤说明: 以管理员身份运行命令提示符或PowerShell 右键点击“开始”菜单,选择“命令提示符(管理员)”或“Windows PowerShell&…...
浅论数据库聚合:合理使用LambdaQueryWrapper和XML
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、数据库聚合替代内存计算(关键优化)二、批量处理优化四、区域特殊处理解耦五、防御性编程增强 前言 技术认知点:使用 XM…...
CentOS 7.9 安装 ClickHouse 文档
1. 环境准备 确保系统为 CentOS 7.9,并已安装 Docker。如果未安装 Docker,请先安装 Docker。 安装 Docker # 卸载旧版本 Docker(如果有) sudo yum remove -y docker docker-client docker-client-latest docker-common docker-…...
WPS条件格式:B列的值大于800,并且E列的值大于B列乘以0.4时,这一行的背景标红
一、选择数据区域 选中需要应用条件格式的区域(例如A2:E100 )。 二、打开条件格式 点击“开始”选项卡,选择“条件格式” > “新建规则”。 三、选择规则类型 选择“使用公式确定要设置格式的单元格”。 四、输入公式 在公式框中输入以…...
SQL分几种
SQL(Structured Query Language)是用于管理关系型数据库的标准语言。根据功能,SQL 语句可以分为以下几类: 1. 数据查询语言(DQL,Data Query Language) 用于从数据库中查询数据。 核心语句&…...
MWC 2025 | 紫光展锐联合移远通信推出全面支持R16特性的5G模组RG620UA-EU
2025年世界移动通信大会(MWC 2025)期间,紫光展锐联合移远通信,正式发布了全面支持5G R16特性的模组RG620UA-EU,以强大的灵活性和便捷性赋能产业。 展锐芯加持,关键性能优异 RG620UA-EU模组基于紫光展锐V62…...
AI-Ollama本地大语言模型运行框架与Ollama javascript接入
1.Ollama Ollama 是一个开源的大型语言模型(LLM)平台,旨在让用户能够轻松地在本地运行、管理和与大型语言模型进行交互。 Ollama 提供了一个简单的方式来加载和使用各种预训练的语言模型,支持文本生成、翻译、代码编写、问答等多种…...
ios使用swift调用deepseek或SiliconFlow接口
调用SiliconFlow API 注册并获取API密钥:打开硅基流动平台官网Models,进行注册和认证。登录后,进入首页,点击左上角三个横杠,选择API密钥,生成密钥并复制。配置第三方应用:打开安装好的Chatbox…...
PROFINET转PROFIBUS从案例剖析网关模块的协议转换功能
一、 案例背景 在当下追求高效协同的工业自动化生产体系里,设备间的无缝互联互通堪称关键要素。某企业的生产车间中,有一台性能稳定的变频器,其配备的是PROFIBUS接口。与此同时,操控整个生产线的核心大脑——西门子1500 PLC&…...
VsCode/Cursor workbench.desktop.main.js 的入口
这个也是main函数开始的,下面就是最后一行代码,表示export出rSo 函数作为它的名字公开为main, 和dll export表有点像了。 export {rSo as main}; 其中rSO是 function rSo(i) {return new nSo(i).open() } nSO是一个类,应该是就是workbenchM…...
VEC系列-RabbitMQ 入门笔记
消息队列(MQ)对于开发者来说是一个经常听到的词汇,但在实际开发中,大多数人并不会真正用到它。网上已经有很多关于 MQ 概述和原理的详细讲解,官网文档和技术博客也都介绍得很深入,因此,我在这里…...
第5章 使用OSSEC进行监控(网络安全防御实战--蓝军武器库)
网络安全防御实战--蓝军武器库是2020年出版的,已经过去3年时间了,最近利用闲暇时间,抓紧吸收,总的来说,第5章开始进入主机安全(HIDS)领域了,2022年的时候有幸做过终端安全一段时间&a…...
安装IK分词器;IK分词器配置扩展词库:配置扩展字典-扩展词,配置扩展停止词字典-停用词
安装IK分词器;IK分词器配置扩展词库:配置扩展字典-扩展词,配置扩展停止词字典-停用词 安装IK分词器IK分词配置扩展词库配置扩展字典-扩展词配置停止词字典-停用词测试配置字典前配置字典后 本文 ElasticSearch 版本为:7.17.9&…...
cursor+deepseek实现完整的俄罗斯方块小游戏
<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>俄罗斯方块</title><style>body {margin: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background: …...
Oracle 数据库基础入门(五):限制查询与范式三约定深度解析
在 Oracle 数据库的学习进程中,限制查询与范式三约定是两个极为重要的概念。限制查询帮助我们精准获取特定范围的数据,而范式三约定则为数据库设计提供了科学的指导框架。对于 Java 全栈开发者而言,掌握这些知识不仅有助于高效地从数据库中提…...
pgsql行列转换
目录 一、造测试数据 二、行转列 1.函数定义 2.语法 3.示例 三、列转行 1.函数定义 2.语法 3.示例 一、造测试数据 create table test ( id int, json1 varchar, json2 varchar );insert into test values(1,111,{111}); insert into test values(2,111,222,{111,22…...
Nginx 开启Baise认证
开启Baise认证 需要再站点Server配置中添加一下配置,添加htpasswd文件 server{auth_basic "HTTP Basic Authentication";auth_basic_user_file /etc/nginx/htpasswd;# 其他配置信息... }如果你的 Linux 服务器没有安装 htpasswd 工具,可以通…...
Android 多用户相关
Android 多用户相关 本文主要记录下android 多用户相关的adb 命令操作. 1: 获取用户列表 命令: adb shell pm list users 输出如下: Users:UserInfo{0:机主:c13} running默认只有一个用户, id为0 ,用户状态为运行 2: 创建新用户 命令: adb shell …...
基于python实现的疫情数据可视化分析系统
基于python实现的疫情数据可视化分析系统 开发语言:Python 数据库:MySQL所用到的知识:Django框架工具:pycharm、Navicat 系统功能实现 总体设计 系统实现 系统功能模块 系统首页可以查看首页、疫情信息、核酸检测、新闻资讯、个人中心、后…...
计算机毕业设计SpringBoot+Vue.js陕西民俗网(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Win7重装不翻车!ISO镜像安全下载渠道+BIOS设置避雷手册
一、写在前面:为什么你需要这份教程? 当电脑频繁蓝屏、系统崩溃甚至无法开机时,重装系统可能是最后的救命稻草。但市面上的教程往往存在三大痛点: ⚠️ 镜像来源不明导致系统被植入后门 ⚠️ 启动盘制作失败反复折腾 ⚠️ 操作失…...
[项目]基于FreeRTOS的STM32四轴飞行器: 四.LED控制
基于FreeRTOS的STM32四轴飞行器: 四.LED控制 一.配置Com层二.编写驱动 一.配置Com层 先在Com_Config.h中定义灯位置的枚举类型: 之后定义Led的结构体: 定义飞行器状态: 在Com_Config.c中初始化四个灯: 在Com_Config.h外部声明…...
macos查询pip默认镜像地址
在 macOS 系统中,查询 pip 的默认镜像地址可以通过以下几种方法: 方法 1:直接通过 pip config list 命令查询 运行以下命令查看当前 pip 的配置(包括镜像地址): pip config list 如果输出中包含 global…...
计算机毕业设计SpringBoot+Vue.js青年公寓服务平台(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
【虚拟仿真】Unity3D中实现激光/射线的发射/折射/反射的效果(3D版)
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群:398291828小红书小破站大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。...
flutter环境最新踩坑
## Flutter 开发常见问题排查与解决 ### 1. 项目初始化与依赖问题 bash # 清理项目 flutter clean # 获取依赖 flutter pub get # 详细日志运行 flutter run -v ### 2. 网络和下载问题 - 网络慢可能导致依赖下载卡住 - 使用 -v 参数可查看详细日志 - 检查网络连接 - 可以尝…...
使用 Spring Boot 实现前后端分离的海康威视 SDK 视频监控
使用 Spring Boot 实现前后端分离的海康威视 SDK 视频监控系统,可以分为以下几个步骤: 1. 系统架构设计 前端:使用 Vue.js、React 或 Angular 等前端框架实现用户界面。后端:使用 Spring Boot 提供 RESTful API,负责与…...
VScode 中文符号出现黄色方框的解决方法
VScode 中文符号出现黄色方框的解决方法 我的vscode的python多行注释中会将中文字符用黄色方框框处: 只需要打开设置搜索unicode,然后将这一项的勾选取消掉就可以了: 取消之后的效果如下: 另一种情况:中文显示出现黄色…...
