⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v4l2video.c

📁 网上大多数linux/unix视频采集程序都是基于video4linux的.而基于V4L2的程序比较少. 本人自己写的基于video4linux2(V4L2)的视频采集程序.已经测试成功.编译请用G
💻 C
📖 第 1 页 / 共 2 页
字号:
/*head files:*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include <assert.h>#include <getopt.h>

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h>

#include <linux/videodev2.h>//////////////////////////////////////////declarations://state reset:#define CLEAR(x)  memset(&(x),0,sizeof(x))//devices:#define V4L2_DEVICE     "/dev/video0"
#define FBVID_DEVICE    "/dev/fb/3"#define OUTPUTFILE      "/mnt/gjf/vidrecord.uyvy"///////////////////////////////////////////////////////////////////////////////////////////#define SCREEN_BPP          16#define D1_WIDTH            352#define D1_HEIGHT           288#define D1_LINE_WIDTH       (D1_WIDTH * SCREEN_BPP / 8)#define D1_FRAME_SIZE       (D1_LINE_WIDTH * D1_HEIGHT)////////////////////////////////////////////////////////////////////////////////////////////typedef enum{    IO_METHOD_READ,    IO_METHOD_MMAP,    IO_METHOD_USERPTR}io_method;struct buffer{     void*  start;      size_t length;};static char* video_device=NULL;static char* output_device=NULL;static io_method io=IO_METHOD_MMAP;struct buffer* buffers=NULL;static unsigned int n_buffers=0;static int   videofd = -1 ;    //device discription for video device;static int   outputfd  = -1 ;  //device discprition for output device; static int   captureSize = 0 ;     //picture sizestatic unsigned int imagewidth = 0 ;  //image widthstatic unsigned int imageheight = 0 ; //image heightstatic unsigned int timelimit = 1 ;   //capturing timestatic unsigned int totalframes = 0 ; //catpturing frames#define FRAME 0#define TIME  1static int flag = FRAME;////////////////////////////////////////////////////////typedef enum{YUYV=0,UYVY}imageType;static imageType format=YUYV;/////////////////////////////////////////////////////////command line:static const char short_options[]="d:pmruw:h:t:f:o:";static const struct option long_options[] ={     {"device",required_argument,NULL,'d'},     {"help",no_argument,NULL,'p'},     {"mmap",no_argument,NULL,'m'},     {"read",no_argument,NULL,'r'},     {"usrptr",no_argument,NULL,'u'},     {"width",required_argument,NULL,'w'},     {"height",required_argument,NULL,'h'},     {"time",required_argument,NULL,'t'},     {"frame",required_argument,NULL,'f'},      {"format",required_argument,NULL,'o'},      { 0 , 0 , 0 , 0 }};static void usage(FILE* fp,int argc,char **argv){  fprintf (fp,"Usage: %s [options]\n\n"              "Options:\n"              "-d | --device name Video device name [/dev/video]\n"              "-p | --help Print this message\n"              "-m | --mmap Use memory mapped buffers\n"              "-r | --read Use read() calls\n"              "-u | --userp Use application allocated buffers\n"              "-w | --image width\n"              "-h | --image height\n"              "-t | --capture time\n"              "-f | --number of frames\n"              "-o | --image format\n"                "",             argv[0]);}void process_command(int argc,char **argv){     int index ;     int next_option ;     int f = -1;     video_device = V4L2_DEVICE ;     output_device = FBVID_DEVICE ;     imagewidth  = D1_WIDTH ;     imageheight = D1_HEIGHT ;     timelimit = 1 ;     totalframes = 0 ;     format = UYVY ;      flag = FRAME ;         do{         next_option = getopt_long(argc,argv,short_options,long_options,&index) ;         switch(next_option) {             case 'd' :                  video_device=optarg ;                  break;             case 'p' :                  usage(stdout,argc,argv) ;                                                           exit(EXIT_FAILURE) ;             case 'm':                  io = IO_METHOD_MMAP ;                  break ;             case 'r':                  io = IO_METHOD_READ ;                  break ;             case 'u':                  io = IO_METHOD_USERPTR ;                  break ;             case 'w':                  imagewidth = atoi(optarg);                  break;             case 'h':                  imageheight = atoi(optarg);                  break;             case 't':                  flag = TIME;                  timelimit = atoi( optarg ) ;                  break;                case 'f':                   flag = FRAME;                  totalframes = atoi( optarg ) ;                    break;                  case 'o':                  f = atoi(optarg);                  format = ( f >= YUYV && f <= UYVY )? f : UYVY;                  break;                     case -1:                  break ;             default:                   usage(stdout,argc,argv) ;                   exit(EXIT_FAILURE) ;                                 }      }while(next_option!=-1);}///////////////////videoCapture:void open_device(){     struct stat st;      if (-1 == stat (video_device, &st)) {         fprintf (stderr, "Cannot identify ’%s’: %d, %s\n",video_device, errno, strerror (errno));         exit (EXIT_FAILURE);      }     if (!S_ISCHR (st.st_mode)) {         fprintf (stderr, "%s is no device\n", video_device);         exit (EXIT_FAILURE);      }     videofd = open (video_device, O_RDWR | O_NONBLOCK, 0);     if (videofd == -1) {         fprintf ( stderr, "Cannot open ’%s’: %d, %s\n", video_device , errno , strerror (errno) );         exit (EXIT_FAILURE);      }}static void init_read(unsigned int bufSize)  //directly read{   buffers = calloc (1, sizeof (*buffers));   if (!buffers) {       fprintf (stderr, "Out of memory\n");       exit (EXIT_FAILURE);    }    buffers[0].length = bufSize ;    buffers[0].start = malloc (bufSize);    if (!buffers[0].start) {          fprintf (stderr, "Out of memory\n");          exit (EXIT_FAILURE);    }}static void init_mmap() //map the driver's buffer to application buffer{   struct v4l2_requestbuffers req;   CLEAR (req);   req.count = 4;   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;   req.memory = V4L2_MEMORY_MMAP;   if (ioctl(videofd, VIDIOC_REQBUFS, &req) == -1) { //allocate buffer in the driver memory space      if (EINVAL == errno) {          fprintf (stderr, "%s does not support ""memory mapping\n", video_device);          exit (EXIT_FAILURE);      } else {          fprintf(stderr,"Failed:VIDIOC_REQBUFS");          exit (EXIT_FAILURE);       }    }     if (req.count < 2) {    //double buffers      fprintf (stderr, "Insufficient buffer memory on %s\n", video_device);      exit (EXIT_FAILURE);    }   buffers = calloc (req.count, sizeof (*buffers));   if (!buffers) {       fprintf (stderr, "Out of memory\n");       exit (EXIT_FAILURE);    }   for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {       struct v4l2_buffer buf;       CLEAR (buf);       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;       buf.memory = V4L2_MEMORY_MMAP;       buf.index = n_buffers;       if (-1 == ioctl (videofd, VIDIOC_QUERYBUF, &buf)) {  //query the state of one of the  buffers in driver space            fprintf(stderr,"Failed:VIDIOC_QUERYBUF ");             exit(EXIT_FAILURE);              }       buffers[n_buffers].length = buf.length;              buffers[n_buffers].start = mmap (	NULL /* start anywhere */,							buf.length,							PROT_READ | PROT_WRITE /* required */,							MAP_SHARED /* recommended */,							videofd, buf.m.offset);	if (buffers[n_buffers].start == MAP_FAILED ) {            fprintf(stderr,"Failed:when MMAP");            exit(EXIT_FAILURE);         }     }}static void init_usrptr(unsigned int bufSize)  //{   struct v4l2_requestbuffers req;   CLEAR (req);   req.count = 4;   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;   req.memory = V4L2_MEMORY_USERPTR;   if (-1 == ioctl (videofd, VIDIOC_REQBUFS, &req)) {       if (EINVAL == errno) {            fprintf (stderr, "%s does not support ""user pointer i/o\n", video_device);            exit (EXIT_FAILURE);        }        else {            fprintf(stderr,"Failed:VIDIOC_REQBUFS\n");        }    }   buffers = calloc (4, sizeof (*buffers));   if (!buffers) {       fprintf (stderr, "Out of memory\n");       exit (EXIT_FAILURE);    }   for (n_buffers = 0; n_buffers < 4; ++n_buffers) {       buffers[n_buffers].length = bufSize;       buffers[n_buffers].start = malloc (bufSize);  //allocate buffers in user space       if (!buffers[n_buffers].start) {            fprintf (stderr, "Out of memory\n");            exit (EXIT_FAILURE);        }    } }static int xioctl( int fd,int request,void * arg){    int r;    do{         r = ioctl (fd, request, arg);     }    while (-1 == r && EINTR == errno);    return r;}#define VPFE_STD_AUTO ((v4l2_std_id)(0x1000000000000000ULL))void init_device(){    struct v4l2_capability      cap;
    struct v4l2_cropcap         cropCap;
    struct v4l2_crop            crop;
    struct v4l2_format          fmt;     unsigned int min;
     //get  the capture device's capabilities    if (ioctl(videofd, VIDIOC_QUERYCAP, &cap) == -1) {
       if (errno == EINVAL) {
            fprintf ( stderr, "%s is no V4L2 device\n",video_device);
            exit(EXIT_FAILURE);
        }
       fprintf(stderr,"Failed VIDIOC_QUERYCAP on %s (%s)\n", video_device,strerror(errno));
       exit(EXIT_FAILURE);
    }   if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
       fprintf(stderr,"%s is no video capture device\n", video_device);
       exit(EXIT_FAILURE);
    }
                   switch (io) {      case IO_METHOD_READ:      	   if (!(cap.capabilities & V4L2_CAP_READWRITE)) {              fprintf (stderr, "%s does not support read i/o\n",video_device);               exit (EXIT_FAILURE);       	    }	   break;      case IO_METHOD_MMAP:      case IO_METHOD_USERPTR:	   if (!(cap.capabilities & V4L2_CAP_STREAMING)) {	        fprintf (stderr, "%s does not support streaming i/o\n",video_device);	        exit (EXIT_FAILURE);            }    }    //set croping and scaling attribure    CLEAR(cropCap);    cropCap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    if (0 == ioctl (videofd, VIDIOC_CROPCAP, &cropCap)) {         crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;         crop.c = cropCap.defrect; /* reset to default */         if (-1 == ioctl (videofd, VIDIOC_S_CROP, &crop)) {              switch (errno) {                 case EINVAL:                    fprintf(stderr,"Cropping not supported\n");                    //exit (EXIT_FAILURE);                 default:                    fprintf(stderr, "Failed:VIDIOC_S_CROP");                   // exit (EXIT_FAILURE);                 }           }     }     else {         fprintf(stderr,"Failed:VIDIOC_CROPCAP");         //exit(EXIT_FAILURE);    }           //set picture format    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    fmt.fmt.pix.width  = D1_WIDTH;    //720    fmt.fmt.pix.height = D1_HEIGHT;   //480       switch(format) {        case YUYV :             fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;             break;        case UYVY :             fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;             break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -