三、
V4L2 API
及数据结构
V4L2
是
V4L
的升级版本,为
linux
下视频设备程序提供了一套接口规范。包括一套数据结构和底层
V4L2
驱动接口。
1
、常用的结构体在内核目录
include/linux/videodev2.h
中定义
struct v4l2_requestbuffers //
申请帧缓冲,对应命令
VIDIOC_REQBUFS
struct v4l2_capability //
视频设备的功能,对应命令
VIDIOC_QUERYCAP
struct v4l2_input
//
视频输入信息,对应命令
VIDIOC_ENUMINPUT
struct v4l2_standard //
视频的制式,比如PAL
,NTSC
,对应命令
VIDIOC_ENUMSTD
struct v4l2_format
//
帧的格式,对应命令VIDIOC_G_FMT
、VIDIOC_S_FMT
等
struct v4l2_buffer
//
驱动
中的一帧图像缓存,对应命令VIDIOC_QUERYBUF
struct v4l2_crop
//
视频信号矩形边框
v4l2_std_id
//
视频制式
2
、常用的
IOCTL
接口命令也在
include/linux/videodev2.h
中定义
VIDIOC_REQBUFS //
分配内存
VIDIOC_QUERYBUF //
把
VIDIOC_REQBUFS
中分配的数据缓存转换成物理地址
VIDIOC_QUERYCAP //
查询驱动功能
VIDIOC_ENUM_FMT //
获取当前驱动支持的视频格式
VIDIOC_S_FMT //
设置当前驱动的频捕获格式
VIDIOC_G_FMT //
读取当前驱动的频捕获格式
VIDIOC_TRY_FMT //
验证当前驱动的显示格式
VIDIOC_CROPCAP //
查询驱动的修剪能力
VIDIOC_S_CROP //
设置视频信号的矩形边框
VIDIOC_G_CROP //
读取视频信号的矩形边框
VIDIOC_QBUF //
把数据从缓存中读取出来
VIDIOC_DQBUF //
把数据放回缓存队列
VIDIOC_STREAMON //
开始视频显示函数
VIDIOC_STREAMOFF //
结束视频显示函数
VIDIOC_QUERYSTD //
检查当前视频设备支持的标准,例如
PAL
或
NTSC
。
3
、操作流程
V4L2
提供了很多访问接口,你可以根据具体需要选择操作方法。需要注意的是,很少有驱动完全实现了所有的接口功能。所以在使用时需要参考驱动源码,或仔细阅读驱动提供者的使用说明。
下面列举出一种操作的流程,供参考。
(
1
)打开设备文件
int fd = open(Devicename,mode);
Devicename
:
/dev/video0
、
/dev/video1
……
Mode
:
O_RDWR [| O_NONBLOCK]
如果使用非阻塞模式调用视频设备,则当没有可用的视频数据时,不会阻塞,而立刻返回。
(
2
)取得设备的
capability
struct v4l2_capability capability
;
int ret = ioctl(fd, VIDIOC_QUERYCAP, &capability);
看看设备具有什么功能,比如是否具有视频输入特性。
(
3
)选择视频输入
struct v4l2_input input
;
……初始化
input
int ret = ioctl(fd, VIDIOC_QUERYCAP, &input);
一个视频设备可以有多个视频输入。如果只有一路输入,这个功能可以没有。
(
4
)检测视频支持的制式
v4l2_std_id std;
do {
ret = ioctl(fd, VIDIOC_QUERYSTD, &std);
} while (ret == -1 && errno == EAGAIN);
switch (std) {
case V4L2_STD_NTSC:
//……
case V4L2_STD_PAL:
//……
}
(
5
)设置视频捕获格式
struct v4l2_format fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
fmt.fmt.pix.height = height;
fmt.fmt.pix.width = width;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
if(ret) {
perror("VIDIOC_S_FMT/n");
close(fd);
return -1;
}
(
6
)向驱动申请帧缓存
struct v4l2_requestbuffers
req;
if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
return -1;
}
v4l2_requestbuffers
结构中定义了缓存的数量,驱动会据此申请对应数量的视频缓存。多个缓存可以用于建立
FIFO
,来提高视频采集的效率。
(
7
)获取每个缓存的信息,并
mmap
到用户空间
typedef struct VideoBuffer {
void
*start;
size_t
length;
} VideoBuffer;
VideoBuffer*
buffers = calloc( req.count, sizeof(*buffers) );
struct v4l2_buffer
buf;
for (numBufs = 0; numBufs < req.count; numBufs++) {//
映射所有的缓存
memset( &buf, 0, sizeof(buf) );
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = numBufs;
if (ioctl(
fd, VIDIOC_QUERYBUF, &buf) == -1) {//
获取到对应
index
的缓存信息,此处主要利用
length
信息及
offset
信息来完成后面的
mmap
操作。
return -1;
}
buffers[numBufs].length = buf.length;
//
转换成相对地址
buffers[numBufs].start = mmap(NULL, buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd, buf.m.offset);
if (buffers[numBufs].start == MAP_FAILED) {
return -1;
}
(
8
)开始采集视频
int buf_type= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
int ret = ioctl(fd, VIDIOC_STREAMON, &buf_type);
(
9
)取出
FIFO
缓存中已经采样的帧缓存
struct v4l2_buffer buf;
memset(&buf,0,sizeof(buf));
buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory=V4L2_MEMORY_MMAP;
buf.index=0;//
此值由下面的
ioctl
返回
if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1)
{
return -1;
}
根据返回的
buf.index
找到对应的
mmap
映射好的缓存,取出视频数据。
(
10
)将刚刚处理完的缓冲重新入队列尾,这样可以循环采集
if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
return -1;
}
(
11
)停止视频的采集
int ret = ioctl(fd, VIDIOC_STREAMOFF, &buf_type);
(
12
)关闭视频设备
close(fd);
分享到:
相关推荐
在Linux系统中,基于V4L2(Video for Linux Two)接口进行视频驱动开发是一项关键任务,它涉及多个层面的技术知识。首先,开发者需要对所选摄像头的特性有深入理解,包括但不限于访问控制机制、参数配置方法以及信号...
编写基于V4L2视频驱动主要涉及到以下几个知识点: ● 摄像头方面的知识 要了解选用的摄像头的特性,包括访问控制方法、各种参数的配置方法、信号输出类型等。 ● Camera解码器、控制器 如果摄像头是模拟量输出的,...
### 基于V4L2的视频驱动开发详述 #### 一、视频驱动的整体框架 在基于V4L2框架下的视频驱动开发中,理解视频驱动的整体框架至关重要。通常,这一框架由多个组成部分构成,包括硬件接口、驱动程序核心逻辑以及与...
在本项目中,我们将基于Qt开发平台,结合V4L2驱动,来实现视频的实时采集和帧数据的保存。 首先,Qt是一个跨平台的C++图形用户界面应用程序框架,它提供了丰富的库和工具,使得开发者可以在不同操作系统上构建用户...
S3C2440 camera 控制器是基于 V4L2 的视频驱动开发的关键组件,支持 ITU-R BT601/656 格式的数字图像输入,支持的 2 个通道的 DMA,Preview 通道和 Codec 通道。 V4L2 的 API 和数据结构 编写驱动前要熟悉应用程序...
综上所述,"基于v4l2视频采集和传输"涉及到Linux下的视频处理、多线程编程和设备驱动交互等多个核心知识点。通过v4l2 API,我们可以构建高效的视频采集和传输系统,同时利用多线程架构来优化系统的响应和性能。
本项目“基于V4L2的简单抓图程序”旨在教我们如何利用V4L2接口来实现从摄像头或者其他视频源抓取图像。 首先,我们要理解V4L2的核心概念。V4L2是一个驱动模型,它提供了标准的API,使得开发者可以轻松地处理各种...
### 基于Linux视频驱动接口V4L2视频采集编程深入解析 #### 一、V4L2视频采集概述 视频采集在嵌入式系统、监控系统以及各种需要实时视频处理的应用中扮演着关键角色。Linux操作系统提供了丰富的工具和API来支持视频...
这个基于V4L2的摄像头驱动程序提供了一种在Linux系统中与摄像头交互的方法,无论是在嵌入式开发板上还是在个人计算机上。下面将详细解释这个驱动程序的工作原理、V4L2框架以及如何编译和使用。 1. V4L2框架详解: ...
### 基于Linux的V4L2视频架构驱动编写详解 #### 一、V4L2概述 V4L2 (Video for Linux Version 2) 是Linux操作系统中用于视频采集设备的一种标准接口,它是V4L (Video for Linux) 的升级版本。V4L最初在1997年发布...
V4L2(Video for Linux Two)是Linux内核中用于多媒体设备,特别是视频捕获设备的接口。这个驱动学习的主题对于嵌入式系统开发者,尤其是那些在JZ2440平台上工作的人来说,是非常重要的。JZ2440是一款基于ARM920T...
总的来说,基于V4L2的视频监控项目涉及了嵌入式系统开发、Linux驱动编程、视频处理和网络通信等多个领域的知识,是一个综合性的实践项目。通过分析`video_linux.c`,我们可以深入理解如何在Linux环境中利用V4L2接口...
V4L2驱动编程指南是指导开发者如何编写基于V4L2框架的视频驱动的文档,通常涉及到视频设备的注册、初始化、配置以及数据传输等核心概念。文档基于经典系列文章《Video4Linux2》进行翻译和整理,适合对V4L2编程有初步...
基于 Linux V4L2 子系统的 ISP 及 ...本文讨论了基于 Linux V4L2 子系统的 ISP 及 Camera 驱动接口标准化方法及应用,涵盖了 ISP 的硬件接口、驱动实现方法、应用开发等方面的内容,为开发者提供了有价值的参考信息。
在Linux系统中,开发一个基于V4L2(Video for Linux Two)和Qt的USB摄像头采集显示程序是一项常见的任务,特别是在嵌入式设备或者多媒体应用中。V4L2是Linux内核提供的一种接口,用于与视频设备进行交互,如USB...
3. **V4L2视频采集**:通过调用V4L2 API,打开摄像头设备,设置捕获参数(如分辨率、帧率等)。然后,使用`mmap`或`read`方法从设备读取视频帧。 4. **处理视频帧**:将从V4L2设备读取的原始视频帧数据转换为Qt可以...
在嵌入式Linux系统中,使用ARM处理器进行设备驱动开发是一项常见的任务,特别是涉及到多媒体设备如摄像头时。本文将深入探讨如何在ARM Linux环境下利用V4L2(Video for Linux Two)框架驱动摄像头进行拍照,并分析...
【标题】"基于V4l2的OpenCV人脸检测Demo"是针对计算机视觉领域的一个实践项目,主要展示了如何使用OpenCV库进行实时的人脸检测,并结合V4L2(Video for Linux Two)接口来访问和处理来自摄像头的视频流。在Linux系统...