v4l2采集视频和图片源码

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <assert.h>#include <fcntl.h>#include <unistd.h> 10 #include <errno.h> 11 #include <sys/stat.h> 12 #include <sys/types.h> 13 #include <sys/time.h> 14 #include <sys/mman.h> 15 #include <sys/ioctl.h> 16 17 #include <linux/videodev2.h>FORCED_WIDTH 640 20 #define FORCED_HEIGHT 480 21 #define FORCED_FORMAT V4L2_PIX_FMT_YUYV 22 #define FORCED_FIELD V4L2_FIELD_ANYverbose = 0; 25 #define pr_debug(fmt, arg…) \ 26if (verbose) fprintf(stderr, fmt, ##arg)CLEAR(x) memset(&(x), 0, sizeof(x)) io_method { IO_METHOD_READ, 32 IO_METHOD_MMAP, 33 IO_METHOD_USERPTR, 34 }; buffer { 37void *start;};*dev_name;io_method io = IO_METHOD_MMAP;fd = -1; 44 struct buffer*buffers; 45 static unsigned intn_buffers;out_buf;force_format;frame_count = 100;*video_name=;errno_exit(const char *s) 54 {, s, errno, strerror(errno)); 56 exit(EXIT_FAILURE); 57 }xioctl(int fh, int request, void *arg) 60 { 61int r; { 64r = ioctl(fh, request, arg); 65} while (-1 == r && EINTR == errno); r; 68 }process_image(const void *p, int size) 71 {, __func__);fwrite(p,size,1,fp);//如果要查看采集视频的格式,在linux下可以通过安装v4l-utils,然后执行v4l2-ctl –all来查看视频采集的相关信息FILE *fp; 77 static int num = 1; 78 char picture_name[20]; 79 80 sprintf(picture_name,”picture%d.jpg”,num ++); 81 82 if((fp = fopen(picture_name,”w”)) == NULL) 83 { 84 perror(“Fail to fopen”); 85 exit(EXIT_FAILURE); 86 } 87 88 fwrite(p,size,1,fp); 89 usleep(500); 90 91 fclose(fp); if (out_buf) 96 fwrite(p, size, 1, stdout); 97 98 fflush(stderr); 99 fprintf(stderr, “.”);100 fflush(stdout);}read_frame(void)107 {108struct v4l2_buffer buf;109unsigned int i;, __func__); (io) {114case IO_METHOD_READ:; IO_METHOD_MMAP:119 CLEAR(buf);120 121buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;122buf.memory = V4L2_MEMORY_MMAP;(-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {125switch (errno) {126case EAGAIN:; EIO::);136 }137 }138 139assert(buf.index < n_buffers);140 141 process_image(buffers[buf.index].start, buf.bytesused);(-1 == xioctl(fd, VIDIOC_QBUF, &buf)));145break; IO_METHOD_USERPTR:;150 };153 }mainloop(void)156 {157unsigned int count;, __func__);160 161count = frame_count;(count– > 0) {164for (;;) {165 fd_set fds;166struct timeval tv;167int r;168 169FD_ZERO(&fds);170FD_SET(fd, &fds);tv.tv_sec = 2;174tv.tv_usec = 0;175 176r = select(fd + 1, &fds, NULL, NULL, &tv);(-1 == r) {179if (EINTR == errno)180continue;);182 }(0 == r) {);186 exit(EXIT_FAILURE);187 } (read_frame())190break;}193 }194 }stop_capturing(void)197 {198enum v4l2_buf_type type;, __func__); (io) {203case IO_METHOD_READ:;IO_METHOD_MMAP: IO_METHOD_USERPTR:209type = V4L2_BUF_TYPE_VIDEO_CAPTURE;210if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)));212break;213 }214 }start_capturing(void) 217 {218unsigned int i;219enum v4l2_buf_type type;220int err;, __func__);, n_buffers); (io) {227case IO_METHOD_READ:; IO_METHOD_MMAP:232for (i = 0; i < n_buffers; ++i) {233struct v4l2_buffer buf;, i);236 237 CLEAR(buf);238buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;239buf.memory = V4L2_MEMORY_MMAP;240buf.index = i;, buf.index);243 244err == xioctl(fd, VIDIOC_QBUF, &buf);, err);(-1 == err)););251 });254type = V4L2_BUF_TYPE_VIDEO_CAPTURE;255if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))););258break; IO_METHOD_USERPTR:;263 }264 }uninit_device(void)267 {268unsigned int i;, __func__); (io) {273case IO_METHOD_READ:274free(buffers[0].start);275break; IO_METHOD_MMAP:278for (i = 0; i < n_buffers; ++i)279if (-1 == munmap(buffers[i].start, buffers[i].length)));281break; IO_METHOD_USERPTR:284for (i = 0; i < n_buffers; ++i)285 free(buffers[i].start);286break;287 }288 289 free(buffers);290 }init_read(unsigned int buffer_size)293 {, __func__);295 296buffers = calloc(1, sizeof(*buffers));(!buffers) {);300 exit(EXIT_FAILURE);301 }302 303buffers[0].length = buffer_size;304buffers[0].start = malloc(buffer_size);(!buffers[0].start) {);308 exit(EXIT_FAILURE);309 }310 }init_mmap({314struct v4l2_requestbuffers req;, __func__);317 318 CLEAR(req);319 320req.count = 4;321req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;322req.memory = V4L2_MEMORY_MMAP;(-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {325if (EINVAL == errno) {, dev_name);328 exit(EXIT_FAILURE);329} else {);331 }332 }, req.count);, req.type);, req.memory););(req.count < 2) {,341 dev_name);342 exit(EXIT_FAILURE);343 }344 345buffers = calloc(req.count, sizeof(*buffers));(!buffers) {);349 exit(EXIT_FAILURE);350 }(n_buffers = 0; n_buffers < req.count; ++n_buffers) {353struct v4l2_buffer buf;354 355 CLEAR(buf);356 357buf.type= V4L2_BUF_TYPE_VIDEO_CAPTURE;358buf.memory= V4L2_MEMORY_MMAP;359buf.index= n_buffers;(-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)));, buf.index);, buf.type);, buf.bytesused);, buf.flags);, buf.field);, (long) buf.timestamp.tv_sec);, (long) buf.timestamp.tv_usec);, buf.timecode.type);, buf.timecode.flags);, buf.timecode.frames);, buf.timecode.seconds);, buf.timecode.minutes);, buf.timecode.hours);,378buf.timecode.userbits[0],379buf.timecode.userbits[1],380buf.timecode.userbits[2],381buf.timecode.userbits[3]);, buf.sequence);, buf.memory);, buf.m.offset);, buf.length);, buf.input););388 389buffers[n_buffers].length = buf.length;390buffers[n_buffers].start =,392 buf.length,,,395 fd, buf.m.offset);(MAP_FAILED == buffers[n_buffers].start));399 }400 }init_device({405struct v4l2_capability cap;406struct v4l2_cropcap cropcap;407struct v4l2_crop crop;408struct v4l2_format fmt;409unsigned int min;, __func__);(-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {414if (EINVAL == errno) {,416 dev_name);417 exit(EXIT_FAILURE);418} else {);420 }421 },426 cap.driver, cap.card, cap.bus_info);,428(cap.version >> 16) & 0xFF,429(cap.version >> 8) & 0xFF,430cap.version & 0xFF);, cap.capabilities);(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {,435 dev_name);436 exit(EXIT_FAILURE);437 } CLEAR(cropcap);446 447cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;(0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {, cropcap.type);, cropcap.bounds.left);, cropcap.bounds.top);, cropcap.bounds.width);, cropcap.bounds.height);, cropcap.defrect.left);, cropcap.defrect.top);, cropcap.defrect.width);, cropcap.defrect.height);, cropcap.pixelaspect.numerator);, cropcap.pixelaspect.denominator););464465 CLEAR(crop);466crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;(-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {470switch (errno) {471case EINVAL:;474default:pr_debug();477break;478 }479 }480} else { } CLEAR(fmt);486 487fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;488if (force_format) {489fmt.fmt.pix.width= FORCED_WIDTH;490fmt.fmt.pix.height= FORCED_HEIGHT; 491fmt.fmt.pix.pixelformat = FORCED_FORMAT;492fmt.fmt.pix.field= FORCED_FIELD;,495fmt.fmt.pix.pixelformat & 0xFF,496(fmt.fmt.pix.pixelformat >> 8) & 0xFF,497(fmt.fmt.pix.pixelformat >> 16) & 0xFF,498(fmt.fmt.pix.pixelformat >> 24) & 0xFF499 ););(-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)));} else {(-1 == xioctl(fd, VIDIOC_G_FMT, &fmt)));510 511fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;,513fmt.fmt.pix.pixelformat & 0xFF,514(fmt.fmt.pix.pixelformat >> 8) & 0xFF,515(fmt.fmt.pix.pixelformat >> 16) & 0xFF,516(fmt.fmt.pix.pixelformat >> 24) & 0xFF517 );518 519 }min = fmt.fmt.pix.width * 2;523if (fmt.fmt.pix.bytesperline < min)524fmt.fmt.pix.bytesperline = min;525min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;526if (fmt.fmt.pix.sizeimage < min)527fmt.fmt.pix.sizeimage = min; (io) {530case IO_METHOD_READ:531 init_read(fmt.fmt.pix.sizeimage);532break; IO_METHOD_MMAP:535 init_mmap();536break; IO_METHOD_USERPTR:;541 }542 }close_device(void)545 {, __func__);(-errno_exit();550 551fd = -1;552 }open_device(void)//555 {556struct stat st;, __func__);(-fprintf(stderr, ,562 dev_name, errno, strerror(errno)); }(!S_ISCHR(st.st_mode)) {, dev_name);568 exit(EXIT_FAILURE);569 }| O_NONBLOCK, (-1 == fd) {,575 dev_name, errno, strerror(errno));576 exit(EXIT_FAILURE);577 }578 }usage(FILE *fp, int argc, char **argv)581 {582 fprintf(fp,,596argv[0], dev_name, frame_count);597 }short_options[] = ;option long_options[] = {, required_argument, NULL, },, no_argument,NULL, },, no_argument,NULL, },, no_argument,NULL, },, no_argument,NULL, },, no_argument,NULL, },, no_argument,NULL, },, required_argument, NULL, },, no_argument,NULL, },612{ 0, 0, 0, 0 }613 };main(int argc, char **argv)616 {; (;;) {620int idx;621int c;622 623c = getopt_long(argc, argv,624short_options, long_options, &idx);(-1 == c)627break; (c) {: ;:634dev_name = optarg;635break;:638 usage(stdout, argc, argv);639 exit(EXIT_SUCCESS);:642io = IO_METHOD_MMAP;643break;:646io = IO_METHOD_READ;647break;:650io = IO_METHOD_USERPTR;651break;:654out_buf++;655break;:658force_format++;659break;:662errno = 0;663frame_count = strtol(optarg, NULL, 0);664if (errno)665 errno_exit(optarg);666break;:669verbose = 1;670break;:673 usage(stderr, argc, argv);674 exit(EXIT_FAILURE);675 }676 }((fp = fopen(video_name,)) == NULL)679 {);681 exit(EXIT_FAILURE);682 }683684 open_device();685 init_device();686 start_capturing();687 mainloop();688 stop_capturing();689 uninit_device();690 close_device(););;693 },无论身处何处,只要有一颗放松而美好的心态,生活便是美好!

v4l2采集视频和图片源码

相关文章:

你感兴趣的文章:

标签云: