当前位置: 技术问答>linux和unix
v4l 视频采集出现错误
来源: 互联网 发布时间:2016-09-03
本文导语: 我在用v4l做视频采集时出现以下错误,望大侠指教: root@xixiao:/workspace/v4l# gcc -o main v4l.c main.c root@xixiao:/workspace/v4l# ./main open success! set_norm success init success! v4l_get_mbuf:: I...
我在用v4l做视频采集时出现以下错误,望大侠指教:
root@xixiao:/workspace/v4l# gcc -o main v4l.c main.c
root@xixiao:/workspace/v4l# ./main
open success!
set_norm success
init success!
v4l_get_mbuf:: Invalid argument
memory map failure
v4l_grab_start: Invalid argument
get picture failure
v4l_grab_sync: Invalid argument
img address 0x7fbb7b14
root@xixiao:/workspace/v4l#
代码如下:
文件 v4l.h
文件v4l.c
文件main.c
root@xixiao:/workspace/v4l# gcc -o main v4l.c main.c
root@xixiao:/workspace/v4l# ./main
open success!
set_norm success
init success!
v4l_get_mbuf:: Invalid argument
memory map failure
v4l_grab_start: Invalid argument
get picture failure
v4l_grab_sync: Invalid argument
img address 0x7fbb7b14
root@xixiao:/workspace/v4l#
代码如下:
文件 v4l.h
#ifndef _V4L_H_
#define _V4L_H_
#include
#include
//PAL CIF NTSC tuner mode
#define PAL_WIDTH 768
#define PAL_HEIGHT 576
#define CIF_WIDTH 352
#define CIF_HEIGHT 288
#define NTSC_WIDTH 80 //璁剧疆鑾峰彇鍥惧儚鐨勫ぇ灏?#define NTSC_HEIGHT 60
#define DEFAULT_PALETTE VIDEO_PALETTE_RGB32
struct _v4l_device
{
int fd;//璁惧鍙? struct video_capability capability;//鎽勫儚澶村睘鎬? struct video_picture picture;//鍥惧儚鐨勫睘鎬э紝浜害銆佽壊搴︺€佸姣斿害銆佺伆搴︺€佺紪鐮佸睘鎬? struct video_window window;//鍖呭惈capture area 鐨勪俊鎭? struct video_channel channel[8];//閲囬泦鐨勯€氶亾
struct video_mbuf mbuf;//鍒╃敤mmap鏄犲皠寰椾睛淇℃伅
struct video_capture capture;
struct video_buffer buffer;
struct video_mmap mmap;
unsigned char *map;
int frame;
int framestat[2];
};
typedef struct _v4l_device v4ldevice;
extern int v4l_open(char *,v4ldevice *);
extern int v4l_set_norm(v4ldevice *, int);
extern int v4l_get_capability(v4ldevice *);
extern int v4l_get_window(v4ldevice *);
extern int v4l_set_window(v4ldevice *);
extern int v4l_get_picture(v4ldevice *);
//浠ヤ笅鍥涗釜鍑芥暟鍒╃敤mmap鍐呭瓨鏄犲皠鏉ヨ幏鍙栧浘鍍?extern int v4l_mmap_init(v4ldevice *);
extern int v4l_grab_init(v4ldevice *,int ,int);
extern int v4l_grab_start(v4ldevice *,int );
extern int v4l_grab_sync(v4ldevice *,int);
extern int v4l_grab_picture(v4ldevice *, int); //浣跨敤鐩存帴鏂瑰紡璇昏澶?extern int v4l_get_capture(v4ldevice *);//,int);
extern int v4l_set_capture(v4ldevice *);//,int);
extern unsigned char *v4l_get_address(v4ldevice *);
extern int v4l_close(v4ldevice *);
extern void set(v4ldevice *);
#endif
文件v4l.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "v4l.h"
#define DEFAULT_DEVICE "/dev/video0"
//打开视频设备
int v4l_open(char *dev,v4ldevice *vd)
{
if (!dev)
dev = DEFAULT_DEVICE;
if((vd->fd=open(dev,O_RDWR,10705))picture))picture.brightness = br;
if(hue) vd->picture.hue = hue;
...
if(ioctl(vd->fd, VIDIOCSPICT, &(vd->picture)) fd, &(vd->map), size) == 0)
return -1;
return 0;
}
int v4l_set_norm(v4ldevice *vd, int norm)
{
int i;
for (i = 0; i capability.channels; i++) {
vd->channel[i].norm = norm;
}
return 0;
}
//该函数完成图像采集前的初始化
int v4l_grab_init(v4ldevice *vd,int width,int height)
{
vd->mmap.width=width;
vd->mmap.height=height;
vd->mmap.format=vd->picture.palette;
vd->frame=0;
vd->framestat[0]=0;
vd->framestat[1]=0;
return 0;
//return v4l_grab_start(vd,0);
}
/*************************************************************************
mmap的函数原型如下
void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )
addr:共享内存的起始地址,一般设为0,表示由系统分配。
len:指定映射内存的大小。在我们这里,该值为摄像头mbuf结构体的size值,即图像数据的总大小。
port:指定共享内存的访问权限 PROT_READ(可读),PROT_WRITE(可写)
flags:一般设置为MAP_SHARED
fd:同享文件的文件描述符。
**************************************************************************/
//该函数把摄像头图像数据映射到进程内存中
int v4l_mmap_init(v4ldevice *vd)
{
if(v4l_get_mbuf(vd)map=mmap(0,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,0))fd,VIDIOCGMBUF,&(vd->mbuf))mbuf.size);
return 0;
}
int v4l_grab_start(v4ldevice *vd,int frame)
{
//////////////////
if(vd->framestat[frame]) {
printf("v4l_grab_start: frame %d is already used.n", frame);
return -1;
}
vd->mmap.frame=frame;
if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))framestat[frame]=1;
return 0;
}
//该函数用来完成截取图像的同步工作,在截取一帧图像后调用,返回表示一帧截取结束
int v4l_grab_sync(v4ldevice *vd,int frame)
{
if(ioctl(vd->fd,VIDIOCSYNC,&frame)framestat[frame]=0;
return 0;
}
unsigned char * v4l_get_address(v4ldevice *vd)
{
return (vd->map+vd->mbuf.offsets[vd->frame]);
}
//关闭视频设备
int v4l_close(v4ldevice *vd)
{
close(vd->fd);
return 0;
}
文件main.c
#include "v4l.h"
#include
#include
#include
#include
#include
#include
#define norm VIDEO_MODE_NTSC
#define DEFAULT_FILE_NAME "picture"
int main()
{
char *buffer=NULL;
v4ldevice VD;
v4ldevice *vd=&VD;
int frame=0;
int f_d;
f_d=open(DEFAULT_FILE_NAME,O_RDWR|O_CREAT,0666);//鑾峰彇鏂囦欢鐨勬弿杩扮
if(0==v4l_open("/dev/video0",vd)) //鎵撳紑璁惧
printf("open success!n");
else
printf("open failuren");
// set (vd);
if(0==v4l_set_norm(vd,norm))
printf("set_norm successn");
else
printf("set_norm failuren");
if(0==v4l_grab_init(vd,NTSC_WIDTH,NTSC_HEIGHT))//鍒濆鍖栬澶囷紝瀹氫箟鑾峰彇鍥惧儚鐨勫ぇ灏? printf("init success!n");
else
printf("init failuren");
if(0==v4l_mmap_init(vd))//鍐呭瓨鏄犲皠
printf("memory map success!n");
else
printf("memory map failuren");
if(0==v4l_grab_start(vd,frame))//寮€濮嬭幏鍙栧浘鍍? printf("get picture success!n");
else
printf("get picture failuren");
v4l_grab_sync(vd,frame);//绛夊緟浼犲畬涓€甯?
buffer=(char *)v4l_get_address(vd);//寰楀埌杩欎竴甯х殑鍦板潃
printf("img address %pn",buffer);
write(f_d,buffer,NTSC_WIDTH*3*NTSC_HEIGHT);//鎶ュ瓨鍒版枃浠朵腑
v4l_close(vd);
return 0;
}
|
搜了一下,找到几个网页也提到这个问题,貌似都没有解决。
其中有一个说是换摄像头解决的
其中有一个说是换摄像头解决的