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

📄 v4l2video.c

📁 网上大多数linux/unix视频采集程序都是基于video4linux的.而基于V4L2的程序比较少. 本人自己写的基于video4linux2(V4L2)的视频采集程序.已经测试成功.编译请用G
💻 C
📖 第 1 页 / 共 2 页
字号:
        default :             fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;    }    //fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;    if (-1 == ioctl (videofd, VIDIOC_S_FMT, &fmt)){       fprintf(stderr,"Failed: VIDIOC_S_FMT");       exit(EXIT_FAILURE);     }        captureSize = fmt.fmt.pix.sizeimage;/*   min = fmt.fmt.pix.width * 2;   if (fmt.fmt.pix.bytesperline < min)      fmt.fmt.pix.bytesperline = min;   min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;   if (fmt.fmt.pix.sizeimage < min)       fmt.fmt.pix.sizeimage=min;    fprintf(stderr,"fmt size : %u \n",fmt.fmt.pix.sizeimage); */ //   printf("%width:%u,height:%u,sizeimage:%u\n",fmt.fmt.pix.width,fmt.fmt.pix.height,fmt.fmt.pix.sizeimage);   //allocate  buffer:   switch(io){        case IO_METHOD_READ:             init_read(fmt.fmt.pix.sizeimage);             break;        case IO_METHOD_MMAP:             init_mmap();             break;        case IO_METHOD_USERPTR:             init_usrptr(fmt.fmt.pix.sizeimage);             break;        default:              fprintf(stderr,"IO_METHOD : No such method\n");             break;     }}void startCapturing(void){    unsigned int i;    enum v4l2_buf_type type;    switch (io) {        case IO_METHOD_READ:             /* Nothing to do. */             break;        case IO_METHOD_MMAP:             for (i = 0; i < n_buffers; ++i) {                 struct v4l2_buffer buf;                 CLEAR (buf);                 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                buf.memory = V4L2_MEMORY_MMAP;                buf.index = i;                if (-1 == xioctl (videofd, VIDIOC_QBUF, &buf))  {  //enqueue an empty capturing buffer allocated in                                                                    //driver space                      fprintf(stderr,"Failed(MMAP):VIDIOC_QBUF\n");                      exit(EXIT_FAILURE);                }              }              type = V4L2_BUF_TYPE_VIDEO_CAPTURE;              if (-1 == ioctl (videofd, VIDIOC_STREAMON, &type)){ //start capturing                       fprintf(stderr,"Failed(MMAP):VIDIOC_STREAMON\n");                       exit(EXIT_FAILURE);              }              break;        case IO_METHOD_USERPTR:             for (i = 0; i < n_buffers; ++i) {                 struct v4l2_buffer buf;                 CLEAR (buf);                 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                 buf.memory = V4L2_MEMORY_USERPTR;                 buf.m.userptr = (unsigned long) buffers[i].start;                 buf.length = buffers[i].length;                 if (-1 == ioctl (videofd, VIDIOC_QBUF, &buf)) {  //encode an empty buffer allocated in usr space                                                                   // in the capturing queue                     fprintf(stderr,"Failed(USERPTR):VIDIOC_QBUF\n");                     exit(EXIT_FAILURE);                 }              }              type = V4L2_BUF_TYPE_VIDEO_CAPTURE;              if (-1 == ioctl (videofd, VIDIOC_STREAMON, &type)) {  //start capturing                     fprintf(stderr,"Failed(USERPTR):VIDIOC_STREAMON\n");                     exit(EXIT_FAILURE);              }     }}static int process_image(const void *p){                 return 0;}static int read_frame (void){    struct v4l2_buffer buf;    unsigned int i;    switch (io) {        case IO_METHOD_READ:           if (-1 == read (videofd, buffers[0].start, buffers[0].length)) {  //read data into the usr buffer,                                                                             //note there is only one buffer              switch (errno) {                 case EAGAIN:                    return 0;                 case EIO:                   /* Could ignore EIO, see spec. */                   /* fall through */                 default:                    {                    fprintf(stderr,"Failed : read");                    exit(EXIT_FAILURE);                                     }                }             }        // if (write(outputfd, buffers[buf.index].start , captureSize ) == -1)    //write to the output file
        //       fprintf(stderr,"Error writing the data to output file\n");            process_image (buffers[0].start);              //process this buffer           break;       case IO_METHOD_MMAP:           CLEAR (buf);           buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;           buf.memory = V4L2_MEMORY_MMAP;           if (-1 == xioctl (videofd, VIDIOC_DQBUF, &buf)) {    //dequeue a buffer               switch (errno) {                   case EAGAIN:                        return 0;                   case EIO:                   /* Could ignore EIO, see spec. */                   /* fall through */                   default:                      {                       fprintf(stderr,"Failed : VIDIOC_DQBUF");                       exit(EXIT_FAILURE);                      }                }            }           assert (buf.index < n_buffers);                //    if (write(outputfd, buffers[buf.index].start , captureSize ) == -1);
           process_image (buffers[buf.index].start);      //process this buffer           if (-1 == xioctl (videofd, VIDIOC_QBUF, &buf)) {    //enqueue this buffer in order to reuse it                   fprintf(stderr,"Failed : VIDIOC_QBUF\n");                   exit(EXIT_FAILURE);           }           break;        case IO_METHOD_USERPTR:           CLEAR (buf);           buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                  buf.memory = V4L2_MEMORY_USERPTR;           if (-1 == xioctl (videofd, VIDIOC_DQBUF, &buf)) {                 switch (errno) {                  case EAGAIN:                     return 0;                  case EIO:                  /* Could ignore EIO, see spec. */                  /* fall through */                  default:                     {                       fprintf(stderr,"Failed : VIDIOC_DQBUF");                      exit(EXIT_FAILURE);                     }                 }              }            for (i = 0; i < n_buffers; ++i)            //find the dequeued buffer in usr space               if (buf.m.userptr == (unsigned long) buffers[i].start && buf.length == buffers[i].length)                    break;                                   assert (i < n_buffers);  //        if (write(outputfd, buffers[i].start , captureSize ) == -1)    //write to the output file
   //              fprintf(stderr,"Error writing the data to output file\n");             process_image ((void *) buf.m.userptr);            if (-1 == xioctl (videofd, VIDIOC_QBUF, &buf)) { //reuse                  fprintf(stderr,"Failed : VIDIOC_QBUF");                  exit(EXIT_FAILURE);              }             break;    }   return 0;}///////////////////////////////////////////////////////////////////////////////////////////////////////void timehandle(int signo) {    fprintf(stderr,"EXIT : time over !--->%u\n",timelimit);   exit(0); } void init_sigaction(void) {   struct sigaction act;   act.sa_handler=timehandle;   act.sa_flags=0;   sigemptyset(&act.sa_mask);   sigaction(SIGPROF,&act,NULL); } void init_time() {   struct itimerval value;   value.it_value.tv_sec= 1;   value.it_value.tv_usec=0;   value.it_interval=value.it_value;   setitimer(ITIMER_PROF,&value,NULL); }///////////////////////////////////////////////////////////////////////////////////////////////////////void mainloop (void){   static  int framecount=0;       outputfd = open(OUTPUTFILE , O_WRONLY | O_CREAT | O_TRUNC, 00644);   if (outputfd == -1) {
        fprintf(stderr,"Failed to open %s for writing\n", OUTPUTFILE);        exit(EXIT_FAILURE);
    }       if(flag == TIME)     {       //init_sigaction( ) ;       //init_time( ) ;       while( 1 ){          fd_set fds;          struct timeval tv;          int r;          FD_ZERO (&fds);          FD_SET (videofd, &fds);          /* Timeout. */          tv.tv_sec = 2;          tv.tv_usec = 0;          r = select (videofd + 1, &fds, NULL, NULL, &tv);  //wait for a new frame          if (-1 == r) {             if (EINTR == errno)                 continue;             fprintf(stderr,"select");             exit(EXIT_FAILURE);           }          if (0 == r) {             fprintf (stderr, "select timeout\n");             exit (EXIT_FAILURE);           }          if (read_frame ())              break;          printf("capturing frame %d \n",framecount);          framecount++;          /* EAGAIN - continue select loop. */        }    }   else        while( framecount < totalframes ){          fd_set fds;          struct timeval tv;          int r;          FD_ZERO (&fds);          FD_SET (videofd, &fds);          /* Timeout. */          tv.tv_sec = 2;          tv.tv_usec = 0;         // fprintf(stderr,"wait for a new frame\n");          r = select (videofd + 1, &fds, NULL, NULL, &tv);  //wait for a new frame          if (-1 == r) {             if (EINTR == errno)                 continue;             fprintf(stderr,"select");             exit(EXIT_FAILURE);           }          if (0 == r) {             fprintf (stderr, "select timeout\n");             exit (EXIT_FAILURE);           }          //fprintf(stderr,"Read next frame :\n");          if (read_frame ())              break;          printf("capturing frame %d \n",framecount);          framecount++;          /* EAGAIN - continue select loop. */       }   if( outputfd != -1 )      close(outputfd);}//---------------------------------------------void stop_capturing (void)     //stop catpureing pictures{  enum v4l2_buf_type type;  switch (io) {     case IO_METHOD_READ:      /* Nothing to do. */           break;     case IO_METHOD_MMAP:     case IO_METHOD_USERPTR:         type = V4L2_BUF_TYPE_VIDEO_CAPTURE;         if (-1 == xioctl (videofd, VIDIOC_STREAMOFF, &type)){             fprintf (stderr,"VIDIOC_STREAMOFF");             exit(EXIT_FAILURE);                   }          break; }void uninit(void){     unsigned int i;     switch (io) {        case IO_METHOD_READ:           free (buffers[0].start);           break;        case IO_METHOD_MMAP:           for (i = 0; i < n_buffers; ++i)               if (-1 == munmap (buffers[i].start, buffers[i].length)){                  fprintf(stderr,"munmap");                  exit(EXIT_FAILURE);                 }           break;        case IO_METHOD_USERPTR:           for (i = 0; i < n_buffers; ++i)               free (buffers[i].start);           break;          }        free (buffers);     }}void close_device (void){    if (-1 == close (videofd))     {       fprintf(stderr,"close");       exit(EXIT_FAILURE);     }    videofd = -1;}///////////////////////////////////////////////////////////////////////////entry:int main(int argc,char **argv){  process_command(argc,argv);  open_device();  fprintf(stderr,"SUCCESS : open_device \n");   init_device();  fprintf(stderr,"SUCCESS : Init_device \n");  startCapturing();  fprintf(stderr,"SUCCESS : startCapturing\n");   mainloop();  fprintf(stderr,"SUCCESS : stopCapturing\n");  stop_capturing() ;   fprintf(stderr,"SUCCUSS : closeDevice\n");  close_device();   return 0;}

⌨️ 快捷键说明

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