void Function::deviceInit(void) { struct v4l2_capability cap; struct v4l2_cropcap cropcap; struct v4l2_crop crop; struct v4l2_format fmt; unsigned int min; if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { QMessageBox::about(NULL,"Information"," no V4L2 device"); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_QUERYCAP"); } } // else // { // /// 2016/2/22 add // printf("Driver Name:%s\nCard Name:%s\nBus info:%s\nDriver Version:%u.%u.%u\n", cap.driver, cap.card, cap.bus_info, (cap.version>>16)&0XFF, (cap.version>>8)&0XFF, cap.version&0XFF); // } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { QMessageBox::about(NULL,"Information"," no video capture device"); exit(EXIT_FAILURE); } struct v4l2_input input; input.index = 0; if ( ioctl(fd, VIDIOC_ENUMINPUT, &input) != 0) { QMessageBox::about(NULL,"Information","set input error"); exit(0); } if ((ioctl(fd, VIDIOC_S_INPUT, &input)) < 0) { QMessageBox::about(NULL,"Information","set s_input error"); exit(0); } CLEAR(cropcap); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) { crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; /* reset to default */ if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) { switch (errno) { case EINVAL: break; default: break; } } } CLEAR (fmt); // v4l2_format fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; // RGB32 and MJPEG can use fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32; // fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; // fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_ANY; if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) errno_exit("VIDIOC_S_FMT"); /* Note VIDIOC_S_FMT may change width and height.*/ if (width != fmt.fmt.pix.width) { width = fmt.fmt.pix.width; //fprintf(stderr,"Image width set to %i by device %s.\n",width,deviceName); } if (height != fmt.fmt.pix.height) { height = fmt.fmt.pix.height; //fprintf(stderr,"Image height set to %i by device %s.\n",height,deviceName); } /*Buggy driver paranoia. */ 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; /***** 2016/2/22 add ***************************** ioctl(fd, VIDIOC_G_FMT, &fmt); printf("Current data format information:\n\twidth:%d\n\theight:%d\n", fmt.fmt.pix.width,fmt.fmt.pix.height); struct v4l2_fmtdesc fmtdesc; fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1) { if(fmtdesc.pixelformat & fmt.fmt.pix.pixelformat) { printf("\tformat:%s\n",fmtdesc.description); // break; } fmtdesc.index++; } *****************************/ mmapInit(); }
/** initialize device */ static void deviceInit(void) { struct v4l2_capability cap; struct v4l2_cropcap cropcap; struct v4l2_crop crop; struct v4l2_format fmt; struct v4l2_streamparm frameint; unsigned int min; if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { fprintf(stderr, "%s is no V4L2 device\n",deviceName); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_QUERYCAP"); } } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { fprintf(stderr, "%s is no video capture device\n",deviceName); exit(EXIT_FAILURE); } switch (io) { #ifdef IO_READ case IO_METHOD_READ: if (!(cap.capabilities & V4L2_CAP_READWRITE)) { fprintf(stderr, "%s does not support read i/o\n",deviceName); exit(EXIT_FAILURE); } break; #endif #ifdef IO_MMAP case IO_METHOD_MMAP: #endif #ifdef IO_USERPTR case IO_METHOD_USERPTR: #endif #if defined(IO_MMAP) || defined(IO_USERPTR) if (!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf(stderr, "%s does not support streaming i/o\n",deviceName); exit(EXIT_FAILURE); } break; #endif } /* Select video input, video standard and tune here. */ CLEAR(cropcap); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) { crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; /* reset to default */ if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) { switch (errno) { case EINVAL: /* Cropping not supported. */ break; default: /* Errors ignored. */ break; } } } else { /* Errors ignored. */ } CLEAR(fmt); // v4l2_format fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) errno_exit("VIDIOC_S_FMT"); if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_YUV420) { fprintf(stderr,"Libv4l didn't accept YUV420 format. Can't proceed.\n"); exit(EXIT_FAILURE); } /* Note VIDIOC_S_FMT may change width and height. */ if (width != fmt.fmt.pix.width) { width = fmt.fmt.pix.width; fprintf(stderr,"Image width set to %i by device %s.\n", width, deviceName); } if (height != fmt.fmt.pix.height) { height = fmt.fmt.pix.height; fprintf(stderr,"Image height set to %i by device %s.\n", height, deviceName); } /* If the user has set the fps to -1, don't try to set the frame interval */ if (fps != -1) { CLEAR(frameint); /* Attempt to set the frame interval. */ frameint.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; frameint.parm.capture.timeperframe.numerator = 1; frameint.parm.capture.timeperframe.denominator = fps; if (-1 == xioctl(fd, VIDIOC_S_PARM, &frameint)) fprintf(stderr,"Unable to set frame interval.\n"); } /* Buggy driver paranoia. */ 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; switch (io) { #ifdef IO_READ case IO_METHOD_READ: readInit(fmt.fmt.pix.sizeimage); break; #endif #ifdef IO_MMAP case IO_METHOD_MMAP: mmapInit(); break; #endif #ifdef IO_USERPTR case IO_METHOD_USERPTR: userptrInit(fmt.fmt.pix.sizeimage); break; #endif } }