本文共 5936 字,大约阅读时间需要 19 分钟。
#include#include //#include //#include #include /* getopt_long() */#include /* low-level i/o */#include #include #include #include #include #include #include #include #include /* for videodev2.h */#include
int device_open(const char* device_name){ FUNCTION_NAME int fd = -1; fd = open(device_name,O_RDWR|O_NONBLOCK,0); if (fd) { fprintf(stderr,"camera open success~ fd:(%d)\n",fd); /* code */ }else{ fprintf(stderr,"camera open faild~ fd:(%d)\n",fd); } return fd;}
struct v4l2_capability cap; device_ioctl(fd, VIDIOC_QUERYCAP, &cap); fprintf(stderr, "version:%d device info:%s\n", cap.version,cap.driver); if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { fprintf(stderr, "%s support capture!\n",dev_name); } if (cap.capabilities & V4L2_CAP_STREAMING) { fprintf(stderr, "%s support steaming capture!\n",dev_name); }
struct v4l2_fmtdesc fmtdesc; fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; int flag = -1; while((flag=ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc))!=-1){ fprintf(stderr, "%s fmtdesc %s!\n",dev_name,fmtdesc.description); fmtdesc.index++; }
struct v4l2_fmtdesc fmtdesc; fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; int flag = -1; struct v4l2_frmsizeenum supportSizes; while((flag=ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc))!=-1) { supportSizes.pixel_format = fmtdesc.pixelformat; supportSizes.index = 0; while((ioctl(fd,VIDIOC_ENUM_FRAMESIZES,&supportSizes))!=-1) { fprintf(stderr, "line:%d %sformat: %s!size with:%d height:%d\n",__LINE__,dev_name,fmtdesc.description,supportSizes.discrete.width,supportSizes.discrete.height); supportSizes.index++; } //fprintf(stderr, "%s support fmt: fmtdesc %s!\n",dev_name,fmtdesc.description); fmtdesc.index++; }
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; } } }
struct v4l2_format fmt; CLEAR(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = 640; fmt.fmt.pix.height = 480; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (device_ioctl(fd,VIDIOC_S_FMT,&fmt) == -1) { fprintf(stderr, "dev:%sErrors happens in set format!\n",dev_name); }
void device_buf_mmap(int fd){ struct v4l2_requestbuffers req; CLEAR(req); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 内存映射的方式 req.memory = V4L2_MEMORY_MMAP; if (device_ioctl(fd,VIDIOC_REQBUFS,&req) == -1) { fprintf(stderr, "request buf error!\n"); return; } if (buffers == NULL) { buffers = calloc(req.count, sizeof(*buffers)); }else{ free(buffers); } if(req.count < 2) { fprintf(stderr, "Insufficient buffer memory on %s/n", dev_name); exit(EXIT_FAILURE); } fprintf(stderr, "sizeof buffers is:%d\n", sizeof(*buffers)); for (int i = 0; i < req.count; ++i) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (device_ioctl(fd,VIDIOC_QUERYBUF,&buf) != -1) { buffers[i].length = buf.length; buffers[i].start = mmap(NULL,buf.length,PROT_READ | PROT_WRITE, MAP_SHARED,fd,buf.m.offset); } if (buffers[i].start == MAP_FAILED) { error_exit("mmap"); } }}
void startCapture(int fd){ FUNCTION_NAME; for (int i = 0; i < buff_index; i++) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (device_ioctl(fd,VIDIOC_QBUF,&buf) == -1) { error_exit("queue buf~"); } } enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (device_ioctl(fd,VIDIOC_STREAMON,&type) == -1) { error_exit("VIDIOC_STREAMON"); }}
fd_set fds; struct timeval tv; int r; FD_ZERO(&fds); FD_SET(fd, &fds); /* Timeout. */ tv.tv_sec = 2; tv.tv_usec = 0; r = select(fd + 1, &fds, NULL, NULL, &tv); if(-1 == r) { if(EINTR == errno) continue; error_exit("select"); } if(0 == r) { fprintf(stderr, "select timeout/n"); exit(EXIT_FAILURE); } if (getFrame(fd)) { break; }
void startCapture(int fd){ FUNCTION_NAME; for (int i = 0; i < buff_index; i++) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (device_ioctl(fd,VIDIOC_QBUF,&buf) == -1) { error_exit("queue buf~"); } } enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (device_ioctl(fd,VIDIOC_STREAMON,&type) == -1) { error_exit("VIDIOC_STREAMON"); }}
static void stopCapture(int fd){ FUNCTION_NAME; enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(-1 == device_ioctl(fd, VIDIOC_STREAMOFF, &type)){ error_exit("VIDIOC_STREAMOFF"); }}static void uninit_device(void){ FUNCTION_NAME; unsigned int i; for(i = 0; i < n_buffers; ++i) { if(-1 == munmap(buffers[i].start, buffers[i].length)) { error_exit("munmap"); } } free(buffers);}
转载地址:http://lhoin.baihongyu.com/