📄 v4l2video.c
字号:
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 + -