Video4linux(v4l)摄像头采集jpeg图片

1、Video4linux下视频编程的流程
(1)打开视频设备:
(2) 读取设备信息
(3)更改设备当前设置(没必要的话可以不做)
(4)进行视频采集,两种方法:
        a.内存映射
        b.直接从设备读取
(5)对采集的视频进行处理
(6)关闭视频设备。

2、为程序定义的数据结构

typedef struct v4l_struct 
{
   int fd;
   struct video_capability capability;
   struct video_channel channel[4]; 
   struct video_picture picture;  
   struct video_window window; 
   struct video_capture capture; 
   struct video_buffer buffer; 
   struct video_mmap mmap; 
   struct video_mbuf mbuf;    
   unsigned char *map;
   int frame;
   int framestat[2]; 
}vd;

3、Video4linux支持的数据结构及其用途

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_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_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_* */
};
#define VIDEO_MAX_FRAME  32
struct video_mbuf
{
 int size;  /* Total memory to map */
 int frames;  /* Frames */
 int offsets[VIDEO_MAX_FRAME];
};

这些struct都来自videodev.h

4、安装libjpeg
官方网站:http://www.ijg.org/
下载地址:http://www.ijg.org/files/

5、使用v4l的摄像头采集jpeg图像的代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/videodev.h>
#include <jpeglib.h>
#define WIDTH  320
#define HEIGHT 240
#define V4L_DEVICE "/dev/video0"
int write_jpeg(char *filename,unsigned char *buf,int quality,int width, int height, int gray)
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE *fp;
    int i;
    unsigned char *line;
    int line_length;
    if (NULL == (fp = fopen(filename,"w")))
    {
          fprintf(stderr,"grab: can't open %s: %s\n", filename, strerror(errno));
          return -1;
    }
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, fp);
    cinfo.image_width  = width;
    cinfo.image_height = height;
    cinfo.input_components = gray ? 1: 3;
    cinfo.in_color_space = gray ? JCS_GRAYSCALE: JCS_RGB;
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);
    line_length = gray ? width : width * 3;
    for (i = 0, line = buf; i < height; i++, line += line_length)
        jpeg_write_scanlines(&cinfo, &line, 1);
    jpeg_finish_compress(&(cinfo));
    jpeg_destroy_compress(&(cinfo));
    fclose(fp);
    return 0;
}
int main()
{
   unsigned char* buf;
   int i,j;
   int fd;
   int re;
   struct video_capability vcap;
   struct video_channel   vc;
   struct video_mbuf     mbuf;
   struct video_mmap    map;
   fd = open(V4L_DEVICE, O_RDWR);
   if(fd<=0)
   {
       perror("open");
       exit(1);
   }
   if(ioctl(fd, VIDIOCGCAP, &vcap)<0)
   {
       perror("VIDIOCGCAP");
       exit(1);
   }
   printf("Video Capture Device Name : %s\n",vcap.name);
   for(i=0;i<vcap.channels;i++)
   {
       vc.channel = i;
       if(ioctl(fd, VIDIOCGCHAN, &vc)<0)
       {
           perror("VIDIOCGCHAN");
           exit(1);
       }
       printf("Video Source (%d) Name : %s\n",i, vc.name);
   }
   vc.channel=0;
   if(ioctl(fd, VIDIOCSCHAN, &vc) < 0)
   {
       perror("VIDIOCSCHAN");
       exit(1);
   }
   if(ioctl(fd, VIDIOCGMBUF, &mbuf) < 0)
   {
       perror("VIDIOCGMBUF");
       exit(1);
   }
   buf=(unsigned char *)mmap(0,mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
   if((int)buf < 0)
   {
       perror("mmap");
       exit(1);
   }
   
   map.frame  = 0;
   map.height = HEIGHT;
   map.width  = WIDTH;
   map.format = VIDEO_PALETTE_RGB24;
   if(ioctl(fd, VIDIOCMCAPTURE, &map)<0)
   {
       perror("VIDIOCMCAPTURE");
       exit(1);
   }
   if(ioctl(fd, VIDIOCSYNC, &map.frame)<0)
   {
       perror("VIDIOCSYNC");
       exit(1);
   }
   if(-1==(write_jpeg("./pic001.jpeg",buf,75,WIDTH,HEIGHT,0)))
   {
        printf("write_jpeg error\n");
        exit(1);
   }
   munmap(buf,mbuf.size);
   close(fd);
   return 0;
}

v4l编程的详细介绍:http://blog.csdn.net/luxiaoxun/archive/2011/05/27/6450783.aspx


你可能感兴趣的:(数据结构,linux,struct,video,buffer,Standards)