文件2:v4l.h 说明:自定义的头文件 主要是根据 /usr/include/linux/videodev.h 中的一些结构体给自定义的结构体
/*****************************
name :v4l.h
Ubuntu10.04 2.6.32
gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
copyright:all is reserved
**************************/
#ifndef _V4L_H_
#define _V4L_H_
#include
#include
//PAL CIF NTSC tuner mode
#define PAL_WIDTH 768 //3种分辨率
#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 //此处设置 并未使用 因为在测试时 得到的数据 是黑图 怀疑格式问题 在main.c中的 62行对这一直进行了频繁的修改
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; //main.c中要用到的函数声明
extern int v4l_open(char *,v4ldevice *); //关键字extern 函数在别的文件中定义
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 *);
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_get_capture(v4ldevice *);
extern int v4l_set_capture(v4ldevice *);
extern unsigned char *v4l_get_address(v4ldevice *);
extern int v4l_close(v4ldevice *);
extern void set(v4ldevice *);
#endif
文件3:main.c 说明 :定义了v4l.h中声明的函数 然后一个 主函数调用。
/******************************************
name :main.c
Ubuntu 10.04 2.6.32-
gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
copyright:all is reserved
************************************/
#include
#include "v4l.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define norm VIDEO_MODE_NTSC
#define DEFAULT_FILE_NAME "picture"
#define DEFAULT_DEVICE "/dev/video0"
int v4l_open(char *dev,v4ldevice *vd)
{
if (!dev)
dev = DEFAULT_DEVICE;
if((vd->fd=open(dev,O_RDWR | O_NONBLOCK,10705))capability.type);
printf("Maxwidth:%d,Maxheight:%d\n",vd->capability.maxwidth ,vd->capability.maxheight);
printf("Minwidth:%d,Minheight:%d\n",vd->capability.minwidth,vd->capability.minheight);
printf("Channels:%d,Audios:%d\n",vd->capability.channels,vd->capability.audios);}
if(v4l_get_picture(vd)picture.brightness,vd->picture.hue,vd->picture.colour);
printf("Contrast:%d,Whiteness:%d(Black and white only)\n",
vd->picture.contrast,vd->picture.whiteness);
printf("Capture depth:%d,Palette:%d\n",vd->picture.depth,vd->picture.palette);
}
//return 0;gcc版本: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
printf("\n===============Set vpic.palette to VIDEO_PALETTE_YUV420P,and picture.depth to 16.========\n");
vd->picture.palette=VIDEO_PALETTE_YUV420P; // 设置调色板 设置图像格式 对应 videodev.h 中107行
vd->picture.depth=14; // 设置象素深度
//vd->picture.hue = 25854 ; // 色调
// vd->picture.colour= 25854 ; //
//vd->picture.brightness = 22869 ; //亮度
// vd->picture.contrast = 22768 ; //对比度
// vd->picture.whiteness= 29321 ; //色度
if(ioctl(vd->fd, VIDIOCSPICT, &vd->picture)==-1) // 设置图像特性
{ fprintf(stderr, "Unable to find a supported capture format.\n");
close(vd->fd);
exit(1);
}else{
printf("\n==============Get struct video_picture2===============\n");//修改后获得的信息
printf("Brightness:%d,Hue:%d,Colour:%d\n",vd->picture.brightness,vd->picture.hue,vd->picture.colour);
printf("Contrast:%d,Whiteness:%d(Black and white only)\n",
vd->picture.contrast,vd->picture.whiteness);
printf("Capture depth:%d,Palette:%d\n",vd->picture.depth,vd->picture.palette);
}
return 0;
}
int v4l_get_capability(v4ldevice *vd)
{
if(ioctl(vd->fd,VIDIOCGCAP,&(vd->capability))fd,VIDIOCGPICT,&(vd->picture))capability.channels; i++) {
vd->channel.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;
}
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) //开始
{
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;
}
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);//获取文件的描述符 打开piture 文件 返回其描述符 DEFAULT_FILE_NAME 在前面开始定义
if(0==v4l_open("/dev/video0",vd)) //打开设备
printf("open success!\n");
else
printf("open failure\n");
// set (vd);
/* if(0==v4l_set_norm(vd,norm))
printf("set_norm success\n");
else
printf("set_norm failure\n"); */
if(0==v4l_grab_init(vd,CIF_WIDTH,CIF_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,CIF_WIDTH*3*CIF_HEIGHT);//报存到文件中 写入piture 文件中
v4l_close(vd);
return 0;
}
文件4:Makefile 说明:自己写的 Makefile 同时生成X86 和ARM 下的可执行文件 交叉编译链为
arm-softfloat-linux-gnu-gcc gcc version 3.4.5
#********************************************************#
#注意啊,以下这两行命令要以tab键开头,不可为空格!
main :
gcc -o arm-main -static main.c
clean :
@rm -vf main* *~ *.o *.i *.s
#********************************************************#
结束 :把mian.c v4l.h Makefile 3个文件放在一个文件夹下编译即可