Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30104216
  • 博文数量: 230
  • 博客积分: 2868
  • 博客等级: 少校
  • 技术积分: 2223
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-08 21:48
个人简介

Live & Learn

文章分类

全部博文(230)

文章存档

2022年(2)

2019年(5)

2018年(15)

2017年(42)

2016年(24)

2015年(13)

2014年(1)

2012年(5)

2011年(58)

2010年(56)

2009年(9)

我的朋友

分类: 嵌入式

2010-09-02 10:28:56

Ubuntu 9.04 v4l USB摄像头驱动测试程序
2009-11-09 01:18
系统 :
Distributor ID:    Ubuntu
Description:    Ubuntu 9.04
Release:    9.04
Codename:    jaunty
2.6.28-15-generic

gcc版本: 4.3.2 

首先要说一下 代码所参考网上人的  感谢~
花了一天一夜  在过程中学会了很多东西 得出的感触:自己还很菜  站在一个角度 看 才明白linux的世界博大精深  埋下头。。。。。
一:
我用的 USB 摄像头 就所市面上很普通 这种的 
图:



然后插上电脑 在 终端输入 lsusb
root@haozi-desktop:/home/haozi/gc/v4l_test# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 014: ID 0ac8:307b Z-Star Microelectronics Corp. USB 1.1 WebCam//这一行
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
0ac8:307b Z-Star Microelectronics Corp. USB 1.1 WebCam 为设备信息 厂家以及芯片ID等

源代码文件为2个 
一个是 v4l.h
一个是 main.c
当然还有个很重要的头文件 linux自带的v4l头文件 位于 /usr/include/linux/videodev.h 这个在main.c下已经包含进去了 
这个头文件里面定义了相关的结构体 以及对应的 控制函数的钩子
下面是3个源码文件  其中我自己加了中文备注 测试程序 不包括 videodev.h
只需要 main.c 和v4l.h 放在同一个文件夹下 然后make 就可以了  Makefile 也在最后给出 

文件1:说明 源文件 可自行去 该目录下阅读 在此没修改任何内容 仅给出了一些中文备注信息
/usr/include/linux/videodev.h

/*
*    Video for Linux version 1 - OBSOLETE
*
*    Header file for v4l1 drivers and applications, for
*    Linux kernels 2.2.x or 2.4.x.
*
*    Provides header for legacy drivers and applications
*
*    See for more info
*
*/
#ifndef __LINUX_VIDEODEV_H
#define __LINUX_VIDEODEV_H

#include
#include

#if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)

#define VID_TYPE_CAPTURE    1    /* Can capture */
#define VID_TYPE_TUNER        2    /* Can tune */
#define VID_TYPE_TELETEXT    4    /* Does teletext */
#define VID_TYPE_OVERLAY    8    /* Overlay onto frame buffer */
#define VID_TYPE_CHROMAKEY    16    /* Overlay by chromakey */
#define VID_TYPE_CLIPPING    32    /* Can clip */
#define VID_TYPE_FRAMERAM    64    /* Uses the frame buffer memory */
#define VID_TYPE_SCALES        128    /* Scalable */
#define VID_TYPE_MONOCHROME    256    /* Monochrome only */
#define VID_TYPE_SUBCAPTURE    512    /* Can capture subareas of the image */
#define VID_TYPE_MPEG_DECODER    1024    /* Can decode MPEG streams */
#define VID_TYPE_MPEG_ENCODER    2048    /* Can encode MPEG streams */
#define VID_TYPE_MJPEG_DECODER    4096    /* Can decode MJPEG streams */
#define VID_TYPE_MJPEG_ENCODER    8192    /* Can encode MJPEG streams */

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;
__u32  flags;
#define VIDEO_VC_TUNER        1    /* Channel has a tuner */
#define VIDEO_VC_AUDIO        2    /* Channel has audio */
__u16  type;
#define VIDEO_TYPE_TV        1
#define VIDEO_TYPE_CAMERA    2
__u16 norm;            /* Norm set by channel */
};

struct video_tuner
{
int tuner;
char name[32];
unsigned long rangelow, rangehigh;    /* Tuner range */
__u32 flags;
#define VIDEO_TUNER_PAL        1
#define VIDEO_TUNER_NTSC    2
#define VIDEO_TUNER_SECAM    4
#define VIDEO_TUNER_LOW        8    /* Uses KHz not MHz */
#define VIDEO_TUNER_NORM    16    /* Tuner can set norm */
#define VIDEO_TUNER_STEREO_ON    128    /* Tuner is seeing stereo */
#define VIDEO_TUNER_RDS_ON      256     /* Tuner is seeing an RDS datastream */
#define VIDEO_TUNER_MBS_ON      512     /* Tuner is seeing an MBS datastream */
__u16 mode;            /* PAL/NTSC/SECAM/OTHER */
#define VIDEO_MODE_PAL        0
#define VIDEO_MODE_NTSC        1
#define VIDEO_MODE_SECAM    2
#define VIDEO_MODE_AUTO        3
__u16 signal;            /* Signal strength 16bit scale */
};

struct video_picture
{
__u16    brightness;   /*  亮度  */
__u16    hue;              /*  色调  */
__u16    colour;
__u16    contrast;         /*  对比度  */
__u16    whiteness;    /* Black and white only 色度*/
__u16    depth;        /* Capture depth 深度*/
__u16   palette;    /* Palette in use */
#define VIDEO_PALETTE_GREY    1    /* Linear greyscale */
#define VIDEO_PALETTE_HI240    2    /* High 240 cube (BT848) */
#define VIDEO_PALETTE_RGB565    3    /* 565 16 bit RGB */
#define VIDEO_PALETTE_RGB24    4    /* 24bit RGB */
#define VIDEO_PALETTE_RGB32    5    /* 32bit RGB */
#define VIDEO_PALETTE_RGB555    6    /* 555 15bit RGB */
#define VIDEO_PALETTE_YUV422    7    /* YUV422 capture */
#define VIDEO_PALETTE_YUYV    8
#define VIDEO_PALETTE_UYVY    9    /* The great thing about standards is ... */
#define VIDEO_PALETTE_YUV420    10
#define VIDEO_PALETTE_YUV411    11    /* YUV411 capture */
#define VIDEO_PALETTE_RAW    12    /* RAW capture (BT848) */
#define VIDEO_PALETTE_YUV422P    13    /* YUV 4:2:2 Planar */
#define VIDEO_PALETTE_YUV411P    14    /* YUV 4:1:1 Planar */
#define VIDEO_PALETTE_YUV420P    15    /* YUV 4:2:0 Planar */
#define VIDEO_PALETTE_YUV410P    16    /* YUV 4:1:0 Planar */
#define VIDEO_PALETTE_PLANAR    13    /* start of planar entries */
#define VIDEO_PALETTE_COMPONENT 7    /* start of component entries */
};

struct video_audio
{
int    audio;        /* Audio channel */
__u16    volume;        /* If settable */
__u16    bass, treble;
__u32    flags;
#define VIDEO_AUDIO_MUTE    1
#define VIDEO_AUDIO_MUTABLE    2
#define VIDEO_AUDIO_VOLUME    4
#define VIDEO_AUDIO_BASS    8
#define VIDEO_AUDIO_TREBLE    16
#define VIDEO_AUDIO_BALANCE    32
char    name[16];
#define VIDEO_SOUND_MONO    1
#define VIDEO_SOUND_STEREO    2
#define VIDEO_SOUND_LANG1    4
#define VIDEO_SOUND_LANG2    8
__u16   mode;
__u16    balance;    /* Stereo balance */
__u16    step;        /* Step actual volume uses */
};

struct video_clip
{
__s32    x,y;
__s32    width, height;
struct    video_clip *next;    /* For user use/driver use only */
};

struct video_window
{
__u32    x,y;            /* Position of window */
__u32    width,height;        /* Its size */
__u32    chromakey;
__u32    flags;
struct    video_clip *clips;    /* Set only */
int    clipcount;
#define VIDEO_WINDOW_INTERLACE    1
#define VIDEO_WINDOW_CHROMAKEY    16    /* Overlay by chromakey */
#define VIDEO_CLIP_BITMAP    -1
/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
#define VIDEO_CLIPMAP_SIZE    (128 * 625)
};

struct video_capture
{
__u32     x,y;            /* Offsets into image */
__u32    width, height;        /* Area to capture */
__u16    decimation;        /* Decimation divider */
__u16    flags;            /* Flags for capture */
#define VIDEO_CAPTURE_ODD        0    /* Temporal */
#define VIDEO_CAPTURE_EVEN        1
};

struct video_buffer
{
void    *base;
int    height,width;
int    depth;
int    bytesperline;
};

struct video_mmap                           /*  内存映射  */
{
unsigned    int frame;        /* Frame (0 - n) for double buffer */
int        height,width;
unsigned    int format;        /* should be VIDEO_PALETTE_* */
};

struct video_key
{
__u8    key[8];
__u32    flags;
};

struct video_mbuf            /*  映射的祯信息  */
{
int    size;        /* Total memory to map 祯的大小*/
int    frames;        /* Frames最多支持的桢数 */
int    offsets[VIDEO_MAX_FRAME];  /*  每针相对于基地址的偏移  */
};

#define     VIDEO_NO_UNIT    (-1)

struct video_unit
{
int     video;        /* Video minor */
int    vbi;        /* VBI minor */
int    radio;        /* Radio minor */
int    audio;        /* Audio minor */
int    teletext;    /* Teletext minor */
};

struct vbi_format {
__u32    sampling_rate;    /* in Hz */
__u32    samples_per_line;
__u32    sample_format;    /* VIDEO_PALETTE_RAW only (1 byte) */
__s32    start[2];    /* starting line for each frame */
__u32    count[2];    /* count of lines for each frame */
__u32    flags;
#define    VBI_UNSYNC    1    /* can distingues between top/bottom field */
#define    VBI_INTERLACED    2    /* lines are interlaced */
};

/* video_info is biased towards hardware mpeg encode/decode */
/* but it could apply generically to any hardware compressor/decompressor */
struct video_info
{
__u32    frame_count;    /* frames output since decode/encode began */
__u32    h_size;        /* current unscaled horizontal size */
__u32    v_size;        /* current unscaled veritcal size */
__u32    smpte_timecode;    /* current SMPTE timecode (for current GOP) */
__u32    picture_type;    /* current picture type */
__u32    temporal_reference;    /* current temporal reference */
__u8    user_data[256];    /* user data last found in compressed stream */
/* user_data[0] contains user data flags, user_data[1] has count */
};

/* generic structure for setting playback modes */
struct video_play_mode
{
int    mode;
int    p1;
int    p2;
};

/* for loading microcode / fpga programming */
struct video_code
{
char    loadwhat[16];    /* name or tag of file being passed */
int    datasize;
__u8    *data;
};

#define VIDIOCGCAP        _IOR('v',1,struct video_capability)    /* Get capabilities */
#define VIDIOCGCHAN        _IOWR('v',2,struct video_channel)    /* Get channel info (sources) */
#define VIDIOCSCHAN        _IOW('v',3,struct video_channel)    /* Set channel     */
#define VIDIOCGTUNER        _IOWR('v',4,struct video_tuner)        /* Get tuner abilities */
#define VIDIOCSTUNER        _IOW('v',5,struct video_tuner)        /* Tune the tuner for the current channel */
#define VIDIOCGPICT        _IOR('v',6,struct video_picture)    /* Get picture properties */
#define VIDIOCSPICT        _IOW('v',7,struct video_picture)    /* Set picture properties */
#define VIDIOCCAPTURE        _IOW('v',8,int)                /* Start, end capture */
#define VIDIOCGWIN        _IOR('v',9, struct video_window)    /* Get the video overlay window */
#define VIDIOCSWIN        _IOW('v',10, struct video_window)    /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
#define VIDIOCGFBUF        _IOR('v',11, struct video_buffer)    /* Get frame buffer */
#define VIDIOCSFBUF        _IOW('v',12, struct video_buffer)    /* Set frame buffer - root only */
#define VIDIOCKEY        _IOR('v',13, struct video_key)        /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
#define VIDIOCGFREQ        _IOR('v',14, unsigned long)        /* Set tuner */
#define VIDIOCSFREQ        _IOW('v',15, unsigned long)        /* Set tuner */
#define VIDIOCGAUDIO        _IOR('v',16, struct video_audio)    /* Get audio info */
#define VIDIOCSAUDIO        _IOW('v',17, struct video_audio)    /* Audio source, mute etc */
#define VIDIOCSYNC        _IOW('v',18, int)            /* Sync with mmap grabbing */
#define VIDIOCMCAPTURE        _IOW('v',19, struct video_mmap)        /* Grab frames */
#define VIDIOCGMBUF        _IOR('v',20, struct video_mbuf)        /* Memory map buffer info */
#define VIDIOCGUNIT        _IOR('v',21, struct video_unit)        /* Get attached units */
#define VIDIOCGCAPTURE        _IOR('v',22, struct video_capture)    /* Get subcapture */
#define VIDIOCSCAPTURE        _IOW('v',23, struct video_capture)    /* Set subcapture */
#define VIDIOCSPLAYMODE        _IOW('v',24, struct video_play_mode)    /* Set output video mode/feature */
#define VIDIOCSWRITEMODE    _IOW('v',25, int)            /* Set write mode */
#define VIDIOCGPLAYINFO        _IOR('v',26, struct video_info)        /* Get current playback info from hardware */
#define VIDIOCSMICROCODE    _IOW('v',27, struct video_code)        /* Load microcode into hardware */
#define    VIDIOCGVBIFMT        _IOR('v',28, struct vbi_format)        /* Get VBI information */
#define    VIDIOCSVBIFMT        _IOW('v',29, struct vbi_format)        /* Set VBI information */


#define BASE_VIDIOCPRIVATE    192        /* 192-255 are private */

/* VIDIOCSWRITEMODE */
#define VID_WRITE_MPEG_AUD        0
#define VID_WRITE_MPEG_VID        1
#define VID_WRITE_OSD            2
#define VID_WRITE_TTX            3
#define VID_WRITE_CC            4
#define VID_WRITE_MJPEG            5

/* VIDIOCSPLAYMODE */
#define VID_PLAY_VID_OUT_MODE        0
/* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
#define VID_PLAY_GENLOCK        1
/* p1: 0 = OFF, 1 = ON */
/* p2: GENLOCK FINE DELAY value */
#define VID_PLAY_NORMAL            2
#define VID_PLAY_PAUSE            3
#define VID_PLAY_SINGLE_FRAME        4
#define VID_PLAY_FAST_FORWARD        5
#define VID_PLAY_SLOW_MOTION        6
#define VID_PLAY_IMMEDIATE_NORMAL    7
#define VID_PLAY_SWITCH_CHANNELS    8
#define VID_PLAY_FREEZE_FRAME        9
#define VID_PLAY_STILL_MODE        10
#define VID_PLAY_MASTER_MODE        11
/* p1: see below */
#define        VID_PLAY_MASTER_NONE    1
#define        VID_PLAY_MASTER_VIDEO    2
#define        VID_PLAY_MASTER_AUDIO    3
#define VID_PLAY_ACTIVE_SCANLINES    12
/* p1 = first active; p2 = last active */
#define VID_PLAY_RESET            13
#define VID_PLAY_END_MARK        14

#endif /* CONFIG_VIDEO_V4L1_COMPAT */

#endif /* __LINUX_VIDEODEV_H */

/*
* Local variables:
* c-basic-offset: 8
* End:
*/

文件2:v4l.h 说明:自定义的头文件 主要是根据 /usr/include/linux/videodev.h  中的一些结构体给自定义的结构体

/*****************************

name :v4l.h

date:2009-11-9

Haozi

Ubuntu 9.04  2.6.28-15-generic

gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)

copyright:all is reserved

email:187357458@163.com

**************************/

#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

date:2009-11-9

Haozi

Ubuntu 9.04  2.6.28-15-generic

gcc: 4.3.3 (Ubuntu 4.3.3-5ubuntu4)

copyright:all is reserved
email:187357458@163.com

************************************/
#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))<0)  //非阻塞方式打开
{
return -1;
}else{
printf("open success!!!!\n");
}

if(v4l_get_capability(vd)<0)
{return -1;}else{
printf("\n===========Get struct video_capability==============\n");
printf(vd->capability.name);printf(", Type:%d\n",vd->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)<0)
{return -1;}else{
printf("\n==============Get struct video_picture1===============\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;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))<0)
{  
perror("v4l_get_capability:");   //not a video4linux device   比较所否支持该设备   在这里让我很是郁闷了很久 我把我们实验室的摄像头都测试了下 
//有几是 Invalid argument 就所在这一步 获取不到它的数据 我在google上查了下
//未果。。。最后的结果就是换。

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 norm) //我的设备获取的信息就一个channel  备注了此段
{
int i;

for (i = 0; i < vd->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;
}

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;
}



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

#********************************************************#
CROSS=arm-softfloat-linux-gnu-
all: arm-main x86-main

arm-main   :
$(CROSS)gcc  -o arm-main -static main.c

x86-main:
gcc  -o x86-main  main.c
clean   :
@rm -vf *-main  *~ *.o *.i *.s
#********************************************************#

结束 :把mian.c   v4l.h  Makefile 3个文件放在一个文件夹下编译即可  如果交叉编译链 不一样 更改 Makefile 中CROSS 即可 。
抓取的效果图如下 :



先写到这 中间遇到了很多问题 。以后有空再来总结 明儿还上班。。。。。
阅读(2469) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~