利用V4L读取摄像头显示错误--- v4l_grab_sync: Inappropriate ioctl for device?
利用V4L编程,获取USB摄像头信息,运行后显示错误如下:v4l_grab_frame: Inappropriate ioctl for device
v4l_grab_sync: Inappropriate ioctl for device
具体的源代码如下:求高手指导,多谢,QQ:962519705
/*******v4l.h******/
#ifndef _V4L_H_
#define _V4L_H_
#define DEFAULT_DEVICE "/dev/video0"
#define TRUE 1
#define FALSE 0
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/videodev2.h>
#include <linux/videodev.h>
struct _v4l_struct
{
int fd; //保存打开视频文件的设备描述符
struct v4l2_capability capability;
struct video_picture picture;
struct video_mmap mmap;
struct video_mbuf mbuf;
unsigned char *map; //用于指向图像数据的指针
int frame_current;
int frame_using ;//VIDEO_MAX_FRAME 为videodev2.h中的宏定义,值为32
};
typedef struct _v4l_struct v4l_device;
extern int v4l_open(char* ,v4l_device *);
extern int v4l_close(v4l_device *);
extern int v4l_get_capability(v4l_device*);
extern int v4l_get_picture(v4l_device *);
extern int v4l_get_mbuf(v4l_device *);
extern int v4l_set_picture(v4l_device* ,int,int,int,int,int);
extern int v4l_grab_picture(v4l_device*,unsigned int);
extern int v4l_mmap_init(v4l_device*);
extern int v4l_grab_init(v4l_device*, int,int);
extern int v4l_grab_frame(v4l_device*, int);
extern int v4l_grab_sync(v4l_device*);
//使用流程
//1、打开视频设备;
//2、获得设备信息;
//3、根据需要更改设备的相关设置;
//4、获得采集到的图像数据(在这里v4l提供了两种方式,直接通过打开的设备读取数据,使用mmap内存映射的方式获取数据);
//5、对采集到的数据进行操作(如显示到屏幕,图像处理,存储成图片文件);
//6、关闭视频设备;
int v4l_open(char *dev,v4l_device *vd)
{
if(!dev) dev=DEFAULT_DEVICE;
if((vd->fd=open(dev,O_RDWR))<0)
{
perror("v4l_open:");
return -1;
}
if(v4l_get_capability(vd))
return -1;
if(v4l_get_picture(vd))
return -1;
return 0;
}
int v4l_close(v4l_device *vd)
{
close(vd->fd);
return 0;
}
int v4l_get_capability(v4l_device *vd)
{
if(ioctl(vd->fd, VIDIOC_QUERYCAP,&(vd->capability))<0)
{
perror("v4l_get_capability:");
return -1;
}
return 0;
}
int v4l_get_picture(v4l_device *vd)
{
if(ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))<0)
{
perror("v4l_get_picture:");
return -1;
}
return 0;
}
int v4l_get_mbuf(v4l_device *vd)
{
if(ioctl(vd->fd,VIDIOCGMBUF,&(vd->mbuf))<0)
{
perror("v4l_get_mbuf:");
return -1;
}
return 0;
}
int v4l_set_picture(v4l_device *vd,int br,int hue,int col,int cont,int white)
{
if(br) vd->picture.brightness=br;
if(hue) vd->picture.hue=hue; //video_picture存在于videodev.h中
if(col) vd->picture.colour=col;
if(cont) vd->picture.contrast=cont;
if(white) vd->picture.whiteness=white;
if(ioctl(vd->fd,VIDIOCSPICT,&(vd->picture))<0)
{perror("v4l_set_picture:");
return -1;
}
return 0;
}
/* 获得采集到的图像数据,两种方法,介绍第一种,一般用第二种
extern int v4l_grab_picture(v4l_device* ,unsigned int);
int v4l_grab_picture(v4l_device* vd, unsigned int size)
{
if(read(vd->fd,&(vd->map),size)==0)
return -1;
return 0;
}
*/
int v4l_mmap_init(v4l_device *vd)
{
if(v4l_get_mbuf(vd)<0)
return -1;
if((vd->map=mmap(0,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,0))<0)//mbuf.size==total memory to map
{
perror("v4l_mmap_init:mmap");
return -1;
}
return 0;
}
int v4l_grab_init(v4l_device *vd,int width,int height)
{
vd->mmap.width=width;
vd->mmap.height=height;
vd->mmap.format=vd->picture.palette;
vd->frame_current=0;
vd->frame_using=FALSE;
vd->frame_using=FALSE;
return v4l_grab_frame(vd,0);
}
int v4l_grab_frame(v4l_device *vd,int frame)
{
vd->frame_current=0; //添加的,测试无法读取摄像头信息缘由
if(vd->frame_using)
{
fprintf(stderr,"v4l_grab_frame:frame %d is already used.\n",frame);
return -1;
}
vd->mmap.frame=frame;
if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))<0)
{
perror("v4l_grab_frame");
return -1;
}
vd->frame_using=TRUE;
vd->frame_current=frame;
return 0;
}
int v4l_grab_sync(v4l_device *vd)
{
if(ioctl(vd->fd,VIDIOCSYNC,&(vd->frame_current))<0) //sync with map grabing
{
perror("v4l_grab_sync");
return -1;
}
vd->frame_using=FALSE;
return 0;
}
#endif
/*********v4l.c*********/
#include "v4l.h"
v4l_device vd;
void main()
{
vd.frame_current=0; //添加测试用
v4l_open(DEFAULT_DEVICE,&vd);
v4l_mmap_init(&vd);
v4l_grab_init(&vd,320,240);
v4l_grab_sync(&vd);//此时就已经获得了一帧图片,存在vd.map中
while(1)
{
vd.frame_current^=1;
v4l_grab_frame(&vd,vd.frame_current);
v4l_grab_sync(&vd);
}
v4l_close(&vd);
} 对这个不熟,但是看报错信息是ioctl报的,可以确认下用法是否正确。
页:
[1]