-
Camera
驱动和编程
了解了
< br>framebuffer
,摄像头便只是
fb
的数据来源而已。
先了解些相关的概念:
V4L2(video
4
linux
2)
可以支持多种设备
,
它可以有以下几种接口
:
1.
视频采集接口
(video
capture
interface):
这种应用的设备可以是高频头或者摄像头
.
V4L2
的最初设计就是应用于这种功能的
.
2.
视频输出接口
(video
output
interface):
可以驱动计算机的外围视频图像设备
--
像可
以输出电视信号格式的设备
.
3.
直接传输视频接口
(video
overlay
interface):
它的主要工作是把从视频采集设备采
集过来的信号直接输出到输出设备之上
,
而不用经过系统的
CPU.
4.
视频间隔消隐信号接口
(VBI
in
terface):
它可以使应用可以访问传输消隐期的视频信
号
.
5.
收音机接口
(radio
p>
interface):
可用来处理从
AM
或
FM
高频头设备接收来的音频流
p>
.
Video4linux
下视频编程的流程:
(
1
)打开视频设备:
(
2
)读取设备信息
(<
/p>
3
)更改设备当前设置(没必要的话可以不做)
< br>
(
4
)进行视频采集,两种方
法
:
a.
内存映射
b.
直接从设备读取
(
5
)对采集的视频进行处理
(
6
)关闭视频设备。
/*
这样的流程地球人都晓得
*/
关键步骤介绍
:
(
1
p>
)
打开视频:
O
pen
(
”/dev/video0”
,
vdàfd);
关闭视频设备用<
/p>
close
(
”/dev/video0
”
,
vdàfd);
(
2
)
读
video_capability
中信息
ioctl
(
vd
->fd
,
VIDIOCGCAP,
&(
v
d
->capability))
成
功后可读取
vd->capability
各分量
eg.
(
3
)
读
video_pic
ture
中信息
ioctl
(vd->fd,
VIDIOCGPICT,
&(vd->picture))
;
(
4
)
改变<
/p>
video_picture
中分量的值
(可以不做的)
先为分量赋新值,再
调用
VIDIOCSPICT
Eg.
vd->
=
65535;
if(
ioctl
(vd->fd,
VIDIOCSPICT,
&(vd->picture))
<
0)
{
perror(
return
-1;
}
(
5
)
初始化
channel
(可以不做的)
<
/p>
必须先做得到
vd->capability
中的信息
for
(i
=
0;
i
<
vd->ls;
i++)
{
vd->channel[i].channel
=
i;
if
(ioctl(vd->fd,
VIDIOCGCHAN,
&(vd->channel[i]))
<
0)
{
perror(
return
-1;
}
}
/*
通
过
ioctl
,将
struct
p>
v4l_struct
作为参数的设备操作而已,那么重点将是整个
结构体:
s
truct
v4l_struct
*/
typedef
struct
v4l_struct
{
int
fd;
struct
video_capability
capability;
struct
video_channel
channel[4];
struct
video_picture
picture;
struct
video_window
window;
struct
video_capture
capture;
struct
video_buffer
buffer;
struct
video_mmap
mmap;
struct
video_mbuf
mbuf;
unsigned
char
*map;
int
frame;
int
framestat[2];
}
vd
;
/*
那么,对该结构体的了解便
成了关键
*/
Video4linu
x
支持的数据结构及其用途
(
1
)
video_capability
p>
包含设备的基本信息(设备名称、支持的最大最小分辨率、信号<
/p>
源信息等)
,
包含的分量:
name[32]
//
设备名称
maxwidth
,
maxheight,
minwidth,
minheight
Channels
//
信号源个数
type
//
是否能
capture
,彩色还是黑白,是否能裁剪等等。值如
VID_TYPE_CAPTURE
等
(
2
)
video_pictur
e
设备采集的图象的各种属性
brightness
0~65535
hue
colour
contrast
whiteness
depth
//
24
palette
//
VIDEO_PALETTE_RGB24
(
3
)
p>
video_channel
关于各个信号源的属性
Channel
//
信号源的编号
name
tuners
Type
//
VIDEO_TYPE_TV
|
IDEO_TYPE_CAMERA
Norm
制式
(
4
)
video_window
//
包含关于
capture
area
的信息
x
x
windows
中的坐标
.
y
x
windows
中的坐标
.
width
The
width
of
the
image
capture.
height
The
height
of
the
image
capture.
chromakey
A
host
order
RGB32
value
for
the
chroma
key.
flags
Additional
capture
flags.
clips
A
list
of
clipping
rectangles.
(Set
only)
clipcount
The
number
of
clipping
rectangles.
(Set
only)
(
5
)
video_mbu
f
//
利用
mmap
进行映射的帧的信息
size
//
每帧大小
Frames
//
最多支持的帧数
Offsets
//
每帧相对基址的偏移
(
6
)
video_bu
ffer
最底层对
buffer
的描
述
void
*baseBase
//
physical
address
of
the
buffer
int
height
//
Height
of
the
frame
buffer
int
width
//
Width
of
the
frame
buffer
int
depth
//
Depth
of
the
frame
buffer
int
bytesperline
//
Number
of
bytes
of
memory
between
the
start
of
two
adjacent
li
nes
实际显示的部分一般比它描述的部分小
(
7
)
video_mmap
//
用于
mmap
背景:
阅读新闻
Camera
驱动和编程
[
日期:
2012-12-31]
重点:
用
mmap
(内存映射)方式截取视频
mmap( )
系统调用使得进程之间通过映射同一个普通文件
实现共享内存。普通文件被映射到进程地址空间
后,进程可以向访问普通内存一样对文件
进行访问,不必再调用
read()
,
write
()等操作。
两个不同进
程
A
、
B
共享
内存的意思是,同一块物理内存被映射到进程
A
、
B
各自的进程地址空间。进程
A
可以即时看到进程
B
对共享内存中数据的更新,反之亦然<
/p>
采用共享内存通信的一个显而易见的好处是效率高,因为进程可
以直接读写内存,而不需要任何数据的拷
贝
< br>(
1
)设置
picture
p>
的属性
(
2
p>
)初始化
video_mbuf
,以得到所
映射的
buffer
的信息
ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf))
(
3
)可以修改
video_mmap
和帧状态的当前设置
Eg. vd-> = VIDEO_PALETTE_RGB24
vd->framestat[0] = vd->framestat[1] =
0; vd->frame = 0;
(
4
< br>)将
mmap
与
video_m
buf
绑定
void* mmap
( void * addr , size_t len , int prot , int flags
, int fd , off_t offset )
len //
映射到调用进程地址空间的字节数,它从被映射文件开头
offset
个字节开始算起
Prot //
指定共享内存的访问权限
PROT_READ
(可读)
,
PROT_WRITE
(可写)
, PROT_EXEC
(可执行)
flags //
MAP_SHARED MAP_PRIVATE
中必选一个
// MAP_
FIXED
不推荐使用
addr //
共内存享的起始地址,
一般设
0
,表示
由系统分配
Mmap( ) //
返回值是系统实际分配的起始地址
if((vd->map = (unsigned char*)mmap(0,
vd->, PROT_READ|PROT_WRITE, MAP_SHARED,
vd->fd, 0)) < 0)
{
perror(
来源:
Linux
社区
作者:
iibull
[
字体:大
中
小
]
return -1;
}
(
5
)
Mmap
p>
方式下真正做视频截取的
VIDIOCMCAPTURE
ioctl(vd->fd,
VIDIOCMCAPTURE, &(vd->mmap))
若调用成功,开始一帧的截取,是非阻塞的,
是否截取完毕留给
VIDIOCSYNC
来判断
(
6
)调用
VIDIOCSYNC
等待一帧截取结束
if(ioctl(vd->fd, VIDIOCSYNC, &frame) <
0)
{
perror(
return -1;
}
若成功,表明一帧截取已完成。可以开始做下一次
VIDIOCMCAPTURE
frame
是当前截取的帧的序号。
****
关于双缓冲:
video_mbuf = 2;
//
一帧被处理时可以采集另一帧
int frame;
//
当前采集的是哪一帧
int
framestat[2]; //
帧的状态
没开始采集
|
等待采集结束
帧的地址由
vd->map+
vd->s[vd->frame]
得到
采集工作结束后调用
munmap
取消绑定
munmap(vd->map, vd->)
/*
关于直接读取的方式,太落伍,不再赘述
*/
背景:
阅读新闻
Camera
驱动和编程
[
日期:
2012-12-31] <
/p>
来源:
Linux
社区
< br>
作者:
iibull
[
字体:大
中
小
] <
/p>
我们要区分
video
为
顺序式和交错式:
顺序式
video
顺序的传输
video
image
所有的行,
交错式
video
则把一个
video
划分成两个
fields
,
分别保存
video image
的奇数行和偶数行,
被称作奇数
field
和偶数
< br>field.
阴极射线电视机需要交替的显示行来组成一个完整的帧,
交替的时延需要我们交替的传输奇数
field
和偶数
field.
这个奇怪的技术的引用是因为:
在刷新率接近电影时,
图片会消退的过快。
使用
field
可以避免使用
double
buffer
以及额外的带宽需求。
首先要明确
camera
并不是在同一时间曝光一帧,
camera
通过
许多
fields
来传输这些帧的,这些
field
是在
不同瞬间拍照。屏
幕上的一个对象因此会在两个
field
之间产生动画效果。这
种情况下需要识别哪一帧更老
一点,也称作
“
< br>瞬间序
”
当驱动通过
fields
提供或者接
收
images
,应用层应该知道如何通过这些
fields
组合成帧,通过划分为
top
bottom field,
“
空间序
”:
top
field
的第一行是帧的第一行
,
bottom
field
的第一行是帧的第二行。
/*
问题:多个
fields
和一个完整的帧的关系
*/
然而因为
field
是一个跟着一个拍的,
争论帧是由
top
还是
bottom
开始的是没意义的,
任何两个相邻的
top
bottom
field,
或者
bottom
top field
都可以组成一个有效的帧。
与直觉相反
top
field
不一定是
older field, older
filed
是否包含
top
或者
bottom lines
是由<
/p>
video
标准决定
的
< br>.
因此要区分瞬间序和空间序。下面的图会给出清晰的解释。
所有的
video
capture
和
out devices
必须汇报当前的
field
顺序。
一些驱动可能允许选择不同的序,
end
应用可以在调用
VIDIOC_S_FMT
前初始化
struct
v4l2_pix_format
的
field
成员。否则可以使用
V4L2_FIELD_ANY
下面列出了可能的
field
p>
类型
Application
可以请求使用这个参数,如果
V4L2_FIELD_NONE,
V4L2_FIELD_TOP,
V4L2_FIELD_BOTTOM
V
4L2_FIELD_INTERLACE
中任
何一个格式都支持.
驱动选择使用哪一个格式依赖
于硬件
0
能力,以及请求的
image
尺寸,驱动选择一个然后返回
这个格
式。
struct_buffer
的
field
成员不可以为
V4L2_F
IELD_ANY.
Images
是顺序式格式,驱动可以指定这种
order
,当驱
动无法区分
V4L2_FIELD_TOP
和<
/p>
V4L2_FIELD_BOTTOM
1
V4L2_FIELD_TOP
Images
仅仅包含
top
field
2
Images
仅仅包含
bottom
field.
应用可能希望防止设备
捕获
interlaced
的图片,
因为这种图片会在运动物体
周围
3
产生毛状特效
V4L2_FIELD_ANY
V4L2_FIELD_NONE
V4L2_FIELD_BOTTOM
Images
包含
top
和
bottom field,
隔行交替,
fields
的瞬
间序依赖于当前
video
的标准。
M
/NTSC
首先传输
bottom
4
field,
其他的则先传输
top field
Images
包含
top
和
bottom field, top field
的行首先存放
在
memory
中,然
后紧跟着
bottom
field
的行。
Fields
p>
一直以瞬间序存储,较老的放在内存前面。
Images
的尺
5
寸和帧相关,而不是
field
Images
包含
top
和
bottom field, bottom field
的行首先
存放在
memory
中,然后紧跟着
top
field
的行。
Fields
p>
一直以瞬间序存储,较老的放在内存前面。
Images
的尺
6
寸和帧相关,而不是
field
一个帧的两个
field
分别放在不同
的
buffer,
按照瞬间序,
也就
是说老的一个是第一个。
driver
或者应用指明
field
的奇偶性
(奇偶性:
< br>当前的
field
是
top
还是
bottom
field
)
.
任何两个连续的
p>
field
构成一个
frame
,是否两个
field
是
7
连续的,
不需要
< br>drop
掉他们,
可以通过
v4
l2_buffer
中的
sequence
< br>成员判定。
Images
的尺寸和
frame
而不是
fields
相关
Images
包含
top
和
bottom
field,
每行交替,
top
field
在前面。
top
field
首先传送
V4L2_FIELD_INTERLACED_TB
8
Images
包含
top
和
bottom field,
每行交替,
bottom
V4L2_FIELD_INTERLACED_BT
9
field
在前面。
bottom
field
首先传送
Field Order, Top Field
First Transmitted
V4L2_FIELD_INTERLACED
V4L2_FIELD_SEQ_TB
V4L2_FIELD_SEQ_BT
V4L2_FIELD_ALTERATE
Field Order, Bottom Field
First Transmitted
背景:
阅读新闻
Camera
驱动和编程
[
日期:
2012-12-31] <
/p>
来源:
Linux
社区
< br>
作者:
iibull
[
字体:大
中
小
] <
/p>
/*
一点小小的补充,两篇文章足以掌握摄像头的编程方法
*/
Video4Linux(
简
V4L)
是
Linux
中关于视频设备的内核驱动,它为针对视频设备的应用程序编程提供一系列
接口函数,<
/p>
这些视频设备包括现今市场上流行的
TV
卡、
视频捕捉卡和
USB
摄像头等。<
/p>
对于
USB
口摄像头,
< br>其驱动程序中需要提供基本的
I/O
操作接口函数
open
、
read
、
write
、
close
的实现。
对中断的处理实现,内存映射功能以及对
I/O
通道的控制接口函数
ioct1
的实现等,并把
它们定义在
struct file_operat
ions
中。这样当应用程序对设备文件进行诸如
open
p>
、
close
、
r
ead
、
write
等系统调用操作<
/p>
时,
Linux
内核将通
过
file_operations
结构访问驱动程序提供的函数。例如,当应用程序对设备文件执行
读操作时,内
核将调用
file_operations
结构
中的
read
函数。
在系统平台上对
USB
口数码摄像头驱动,
首先把
US
B
控制器驱动模块静态编译进内核,
使平台中支持
USB
接口,再在需要使用摄像头采集
时,使用
insmod
动态加载其驱动模块,这样
摄像头就可正常工作了,接
着进行了下一步对视频流的采集编程。
程序中定义的数据结构
struct video_capability
grab_cap;
struct video_picture grab_pic;
struct
video_mmap grab_buf;
struct video_mbuf
grab_vm
;
这些数据结构都是由
Video4Linux
支持的,它们的用途如下:
*video_capabili
ty
包含摄像头的基本信息,例如设备名称、支持的最大最小分辨率、信号源信息等,<
/p>
分别对应着结构体中成员变量
name [32]
、
maxwidth
、
max
height
、
minwidth
、<
/p>
minheight
、
channels
(
信号
源个数
)
、
type
等;
*video_picture<
/p>
包含设备采集图像的各种属性,如
brightness(
亮度
)
、
hue(<
/p>
色调
)
、
con
trast(
对比度
)
、
whiteness(
色度
)
、
depth(
深度
)
等;
*video_mmap
用于内存映射;
*video_mbuf
利用
mmap
进行映射的帧信息,
实际上是输入到摄像头存储器缓冲中的帧信息,
包括
size
(帧的大小)、
frames
(最多支持的帧数)、
offsets
(每帧相对基址的偏移)
。
程序中用到的主要系统调用函数有:
open(
、
close(fd)
、
mmap(void *start,size_t length,int
prot,int flags,int fd,off_t
offset)
、
munmap(void
*start,size_tlength)
、
ioctl(int fd,int
cmd,…)
。
前面提到
Linux
系统中把设备看成设备文件,在用户空间可以通过标准的
I/O
系统调用函数操作设备
文件,从而达到与设备通信交互的目的。当然,在设备驱
动中要提供对这些函数的相应支持。
这里说明一下
ioctl(int fd,int cmd,…
)
函数,它在用户程序中用来控制
I/O
通道,其中,
fd
代表设备文件描
述
符,
cmd
代表用户程序对设备的控制命令,省略号一般是一个
表示类型长度的参数,也可没有。
***
采集程序实现过程
***
首先打开视频设备,摄像头在系统
中对应的设备文件为
/dev/video0
,采用系统调用函
数
grab_fd=open(
是设备打开后返回的文件描述符
(打开错误返回
-1
),
以后的系统调
用函数就可使用它来对设备文件进行操作了。
接着,利用
ioctl
(
grab_fd,VIDIOCGCAP,&grab_cap
)函数读取
struct video_capability
中有关摄像
头的信
息。该函数成功返回后,这些信息从内核空间拷贝到用户程序空间
grab_cap
各成员分量中,使用
printf
函数就可得到各成员分量信息,例如
p
rintf(
获得最大垂直分辨率的
大小。
用
ioctl(grab_fd,VIDIOCGPICT,&grab_pic)
p>
函数读取摄像头缓冲中
video_picture
信息。
在用户空间程序中
可以改变这些信息,具体方法
为先给分量赋新值,再调用
VIDIOCSPICT
ioctl
函数,例如:
grab_=3;
if(ioctl(grab_fd,
VIDIOCSPICT, &grab_pic)<0)
{
perror(
return
-1;
};
< br>完成以上初始化设备工作后,就可以对视频图像截取了,有两种方法:
一种是
read()
直接读取;
//
通过内核缓冲
区来读取数据
另外一种
mmap()
内存映射。
/* mmap()
通过把设备文件映射到内存中,绕过了内核
缓冲区,最快的磁盘访问往往还是慢于最慢的内存
访问,所以
m
map()
方式加速了
I/O
访问。
另外,
mmap()
系统调用使得进程之间通过映射同一文件
实现共享内存,
各进程可以像访问普通内存一样对
文件进行访问
,访问时只需要使用指针
而不用调用文件操作函数。因为
p>
mmap()
的以上优点,所以在程序
实现
中采用了内存映射方式,即
mmap()
方式。
*/
利用
mmap()
< br>方式视频裁取具体进行操作如下。
①先使用
ioctl(grab_fd,
VIDIOCGMBUF, &grab_vm)
函数获得摄像头存储缓冲区的帧信息,
之后修改
video_mmap
中的设置,例如重新设置图像
帧的垂直及水平分辨率、彩色显示格式。可利用如下
语句
grab_=240;
grab_=320;
grab_=VIDEO_PALETTE_RGB24;
②接着把摄像头对应的设备文件映射到内存区,具体使用
grab_data=(unsigned char*)mmap(0,
grab_, PROT_READ|PROT_WRITE,
MAP_SHARED, grad_fd, 0)
p>
这样设备文件的内容就映射到内存区,该映射内容区可读可写并且不同进程间可共享。该函数
成功时返回
映像内存区的指针,挫败时返回值为
-1
。
背景:
阅读新闻
Camera
驱动和编程
[
日期:
2012-12-31] <
/p>
来源:
Linux
社区
< br>
作者:
iibull
[
字体:大
中
小
]
下面对单帧采集和连续帧采集进行说明:
*
单帧采集
在上面获取的摄像头存储缓冲区帧信息中,最多可支持的帧数(
frames
的值)一般为两帧。对于单帧采集
只需设置
grab_=0
,
即采集其中的第一帧,
使用
ioctl(grab_fd,VI
DIOCMCAPTURE,&grab_buf)
函
数,若
调用成功,则激活设备真正开始一帧图像的截取,是非阻塞的。
接着使用
ioctl(grab_fd,VIDIOCSYNC,&frame) <
/p>
函数判断该帧图像是否截取完毕,成功返回表示截取完毕,
之后就
可把图像数据保存成文件的形式。
ioctl
(grab_fd, VIDIOCMCAPTURE, &grab_buf)
ioctl (grab_fd, VIDIOCSYNC, &frame)
*
连续帧采集
在单帧的基础上,利用
grab_
值确定采集完毕摄像头帧缓
冲区帧数据进行循环的次数。
在循环语句中,也是使用
VIDIOCMCCAPTURE
ioct1
和
VIDIOCSYNC ioctl
函数完成每帧截取,但要给采集
到的每帧图像赋地址,利用语句
buf=grab_data+grab_s[frame],
然后保存文件
的形式。
若要继续采集可再加一个外循环,在外循环语句只要
给原来的内循环再赋
frame=0
即可。
------------------------------------
--------------------------------------------------
-----------------------------------------
-----
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CLEAR(x) memset (&(x), 0,
sizeof (x))
struct buffer {
void * start;
size_t length;
};
static char * dev_name =
static int fd = -1;
struct buffer * buffers = NULL;
FILE *file_fd;
static
unsigned long file_length;
static
unsigned char *file_name;
int main (int
argc,char ** argv)
{
struct
v4l2_capability cap;
struct
v4l2_format fmt;
file_fd =
fopen(
fd = open (dev_name, O_RDWR /*
required */ | O_NONBLOCK, 0);
ioctl
(fd, VIDIOC_QUERYCAP, &cap);
CLEAR
(fmt);
= V4L2_BUF_TYPE_VIDEO_CAPTURE;
= 640;
= 480;
ormat = V4L2_PIX_FMT_YUYV;
= V4L2_FIELD_INTERLACED;
ioctl (fd,
VIDIOC_S_FMT, &fmt);
file_length =
erline *
buffers = calloc (1, sizeof
(*buffers));
buffers[0].length =
file_length;
buffers[0].start = malloc
(file_length);
for (;;)
{
fd_set fds;
struct timeval
tv;
int r;
FD_ZERO (&fds);
FD_SET (fd, &fds);
/*
Timeout. */
_sec = 3;
_usec
= 0;
r = select (fd + 1, &fds, NULL,
NULL, &tv);
if (-1 == r) {
if (EINTR == errno)
continue;
printf
(
}
if (0 == r) {
fprintf (stderr,
exit
(EXIT_FAILURE);
}
if (read
(fd, buffers[0].start, buffers[0].length))
break;
}
fwrite(buffers[0].start,
buffers[0].length, 1, file_fd);
free
(buffers[0].start);
close (fd);
fclose (file_fd);
exit
(EXIT_SUCCESS);
return 0;
}
linux
下视频设备设置的几个参数
v4l
video4linux v4l2 ioctl
用一系列的
ioctl
发命令控制设备。
v4l
支
持的
ioctl
命令大概有二十几个,为了尽快的编出一个
p>
简单的图象捕捉程序,让我们先来看看几个主要的命令:
1. ioctl(fd,VIDIOCGCAP,&cap);
该命令主要是为了获取电视卡的功能信息。例如电视卡的名称,类型,
channe
l
等。参数
cap
是一个结构,
当
ioctl
命令返回时,结构的各成员就被
赋值了,结构体的定义为:
struct
video_capability
{
char
name[32];
int type;
int
channels; /* Num channels */
int
audios; /* Num audio devices */
int
maxwidth; /* Supported width */
int
maxheight; /* And height */
int
minwidth; /* Supported width */
int
minheight; /* And height */
};
channel
指的是有几个信号输入源,例如
television,composite,s-video
等。
(fd,VIDIOCGCHAN,&vc)
(fd,VIDIOCSCHAN.&vc)
这两个命令用来
取得和设置电视卡的
channel
信息,例如使用那个输入源
,制式等。
vc
是一个
video_channel
结构,其定义为:
struct video_capability
{
char name[32];
int type;
int channels; /* Num channels */
int audios; /* Num audio devices */
int maxwidth; /* Supported width */
int maxheight; /* And height */
int minwidth; /* Supported width */
int minheight; /* And height */
};
struct
video_channel
{
int channel;
char name[32];
int tuners;
//number of tuners for this input
__u32
flags;
__u16 type;
__u16
norm;
};
成员
chann
el
代表输入源,通常,
0:
television 1:composite1 2:s-video
name
表示该输入源的名称。
norm
表示制式,通常,
0:pal
1:ntsc 2:secam 3:auto
4.
ioctl(fd,VIDIOCGMBUF,*mbuf)
获得电视卡缓存的信息,
参数
mbuf
是
video_mbuf
结构。其定义如下:
struct
video_mbuf
{
int size; /*
Total memory to map */
int frames; /*
Frames */
int offsets[VIDEO_MAX_FRAME];
};
size
是缓存的大小,
frames
表明该电视卡的缓存可以容纳
的帧数,数组
offsets
则表明
对应一帧的起始位置,
0
帧对应
offsets[0],1
帧对应
offse
ts[1]....
执行完该命令后,就可以用
mmap
p>
函数将缓存映射到内存中了。大致用法可以参考以下的代
码
struct
video_mbuf mbuf;
unsigned char
*buf1,*buf2;
if(ioctl(fd,VIDIOCGMBUF,&mbuf)<0)
{
perror(
return
-1;
}
printf(
buf1
= (unsigned char*)mmap(0,,PROT_READ|PROT_WRITE,MAP
_SHARED,fd.0);
buf1 = buf1 + [0];
buf2 = buf1 + [1];//
当然,如果
=1,
就不需要下面的了。
......
5.
ioctl(MCAPTURE
,
&mm)
启动硬件去捕捉图象,
mm
是
video_mmap
结构,设置捕捉图象需要设置的信息。结构体
如下定义:
struct
video_mmap
{
unsigned int
frame; /* Frame (0 - n) for double buffer */
int height,width;
unsigned
int format; /* should be VIDEO_PALETTE_* */
};
frame
:
设置当前是第几帧
height,
width:
设置图象的高和宽。
format :
颜色模式
要注意的是,该命令是非阻塞的,也就是说,它仅仅设置了硬件,而不负责是否捕捉到图象。
p>
要确定是否捕捉到图象,要用到下一个命令。
6.
ioctl(fd,VIDIOCSYNC,&frame)
等待捕捉到这一帧图象。
frame
是要等待的图象,它的值应和上一个命令中设置的
frame
相
对应。
好了,说了这么多,读者大概也对视频捕捉有了一个了
解,是不是想亲自动手试一下,那就让我们
开始实际程序的编写吧。
-
-
-
-
-
-
-
-
-
上一篇:使用包嗅探及协议分析软件
下一篇:外贸单证常用英语缩写