程序来自网络上具体来源未知。程序已经在 mini2440上测试过,运行编译的执行文件会在当前目录下保存一张图片。
摄像头型号 -zp301.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <error.h>
#include <fcntl.h>
#include <sys/types.h>
#include <linux/videodev.h>
//#include "v4l.h"
#include <linux/videodev.h>
#include <sys/types.h>
#define DEFAULT_DEVICE "/dev/video0"
#include <string.h>
#define norm VIDEO_MODE_NTSC
#define DEFAULT_FILE_NAME "picture"
//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;
struct video_channel channel[8];
struct video_mbuf mbuf;
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;
int v4l_open(char *dev,v4ldevice *vd)
{
if (!dev){dev = DEFAULT_DEVICE;} ;
if((vd->fd=open(dev,O_RDWR,10705))<0)
{
return -1;
};
if(v4l_get_capability(vd)<0)
return -1;
if(v4l_get_picture(vd)<0)
return -1;
return 0;
}
int v4l_get_capability(v4ldevice *vd)
{
if(ioctl(vd->fd,VIDIOCGCAP,&(vd->capability))<0)
{
perror("v4l_get_capability:");
return -1;
};
return 0;
}
int v4l_get_picture(v4ldevice *vd)
{
if(ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))<0)
{
perror("v4l_get_picture");
return -1;
};
return 0;
}
int v4l_set_norm(v4ldevice *vd, int nrm)
{
int i;
for(i=0;i< vd->capability.channels ; i++){
// vd->channel=nrm ;
};
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;
}
int v4l_mmap_init(v4ldevice *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)
{
return -1;
}
return 0;
}
int v4l_get_mbuf(v4ldevice *vd)
{
if(ioctl(vd->fd,VIDIOCGMBUF,&(vd->mbuf))<0)
{
perror("v4l_get_mbuf:");
return -1;
}
printf("size=%d\n",vd->mbuf.size);
return 0;
}
int v4l_grab_start(v4ldevice *vd,int frame)
{
vd->mmap.frame=frame;
if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))<0)
{
exit(-1);
return -1;
}
vd->framestat[frame]=1;
return 0;
}
int v4l_grab_sync(v4ldevice *vd,int frame)
{
if(ioctl(vd->fd,VIDIOCSYNC,&frame)<0)
{
return -1;
}
vd->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************************/
/*name :main.c
date:2009-5-20
author:kevin
copyright:all is reserved
************************************/
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 failure\n");
if(0==v4l_set_norm(vd,norm))
printf("set_norm success\n");
else
printf("set_norm failure\n");
if(0==v4l_grab_init(vd,NTSC_WIDTH,NTSC_HEIGHT))
printf("init success!\n");
else
printf("init failure\n");
if(0==v4l_mmap_init(vd))
printf("memory map success!\n");
else
printf("memory map failure\n");
if(0==v4l_grab_start(vd,frame))
printf("get picture success!\n");
else
printf("get picture failure\n");
v4l_grab_sync(vd,frame);
buffer=(char *)v4l_get_address(vd);
printf("img address %p\n",buffer);
write(f_d,buffer,NTSC_WIDTH*3*NTSC_HEIGHT);
v4l_close(vd);
return 0;
}