linux下usb camera图像采集(V4l2)

head.h
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <fcntl.h> /* low-level i/*/
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <malloc.h>
  8. #include <sys/stat.h>
  9. #include <sys/types.h>
  10. #include <sys/time.h>
  11. #include <sys/mman.h>
  12. #include <sys/ioctl.h>
  13. #include <linux/videodev2.h>
  14. #define DEVICE "/dev/video"
  15. static struct v4l2_requestbuffers req;
  16. struct buffer
  17. {
  18.     void* start;
  19.     unsigned int length;
  20. }; 
  21. static struct buffer *buffers;
  22. static struct v4l2_buffer buf;

usb_camera.c
  1. #include "head.h"
  2. int main()
  3. {
  4.     int fd;
  5.     fd=open_device();
  6.     get_device_info(fd);
  7.     get_frame_fmt(fd);
  8.     get_current_frame_info(fd);
  9.     try_format_support(fd);
  10.     set_frame_format(fd);
  11.     apply_memory_buf(fd);
  12.     memory_mapping(fd);
  13.     buffer_enqueue(fd);
  14.     close(fd);
  15.     return 0;
  16. }
  17. int open_device()
  18. {
  19.     int fd;
  20.     if(-1==(fd=open(DEVICE,O_RDWR)))
  21.         printf("info:Can't open video device\n");
  22.     else
  23.         printf("info:Open the device :%d\n",fd);
  24.     return fd;
  25. }
  26. int get_device_info(int fd)
  27. {
  28.     struct v4l2_capability cap;
  29.     if(-1==ioctl(fd,VIDIOC_QUERYCAP,&cap))
  30.         printf("info:VIDIOC_QUERYCAP ERROR\n");
  31.     else
  32.         printf("info:Driver Name:%s....Card Name:%s....Bus info:%s....Driver Version:%u.%u.%u\n",
  33.         cap.driver,cap.card,cap.bus_info,(cap.version>>16)&0XFF,(cap.version>>8)&0XFF,cap.version&0XFF);
  34.     return 1;
  35. }
  36. int get_frame_fmt(int fd)
  37. {
  38.     struct v4l2_fmtdesc fmtdesc;
  39.     fmtdesc.index=0;
  40.     fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  41.     printf("info:Support format:");
  42.     while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
  43.     {
  44.         printf("\t%d.%s",fmtdesc.index+1,fmtdesc.description);
  45.         fmtdesc.index++;
  46.     }
  47.     printf("\n");
  48.     return 1;
  49. }
  50. int get_current_frame_info(int fd)
  51. {
  52.     struct v4l2_format fmt;
  53.     fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  54.     ioctl(fd,VIDIOC_G_FMT,&fmt);
  55.     printf("info:Current data format information:\n\twidth:%d\n\theight:%d\n",fmt.fmt.pix.width,fmt.fmt.pix.height);
  56.     struct v4l2_fmtdesc fmtdesc;
  57.     fmtdesc.index=0;
  58.     fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  59.     while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
  60.     {
  61.         if(fmtdesc.pixelformat & fmt.fmt.pix.pixelformat)
  62.         {
  63.             printf("\tformat:%s\n",fmtdesc.description);
  64.             break;
  65.         }
  66.         fmtdesc.index++;
  67.     } 
  68.     return 1;
  69. }
  70. int try_format_support(int fd)
  71. {
  72.     struct v4l2_format fmt;
  73.     fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74.     //fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_RGB32;
  75.     fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;
  76.     if(ioctl(fd,VIDIOC_TRY_FMT,&fmt)==-1)
  77.     if(errno==EINVAL)
  78.     printf("info:not support format RGB32!\n"); 
  79.     return 1;
  80. }
  81. int set_frame_format(int fd)
  82. {
  83.     struct v4l2_format fmt;
  84.     fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  85.     fmt.fmt.pix.width=640;
  86.     fmt.fmt.pix.height=480;
  87.     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  88.     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 
  89.     if(ioctl(fd,VIDIOC_S_FMT,&fmt)==-1)
  90.     if(errno==EINVAL)
  91.     printf("info:set frame format error!\n");
  92.     return 1;
  93. }
  94. int apply_memory_buf(int fd)
  95. {
  96.     //struct v4l2_requestbuffers req;
  97.     req.count=4;
  98.     req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  99.     req.memory=V4L2_MEMORY_MMAP;
  100.     if(-1==ioctl(fd,VIDIOC_REQBUFS,&req))
  101.         printf("info:VIDIOC_REQBUFS FAILED\n");
  102.     else
  103.         printf("info:VIDIOC_REQBUFS SUCCESS\n");
  104.     return 1;
  105. }
  106. int memory_mapping(int fd)
  107. {
  108.     unsigned int n_buffers;
  109.     buffers = (struct buffer*)calloc(req.count,sizeof(struct buffer));
  110.     if (!buffers) {
  111.         fprintf (stderr, "Out of memory\n");
  112.         exit (EXIT_FAILURE);
  113.     }
  114.     // 映射
  115.     for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
  116.         //struct v4l2_buffer buf;
  117.         memset(&buf,0,sizeof(buf));
  118.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  119.         buf.memory = V4L2_MEMORY_MMAP;
  120.         buf.index = n_buffers;
  121.         // 查询序号为n_buffers 的缓冲区,得到其起始物理地址和大小
  122.         if (-== ioctl (fd, VIDIOC_QUERYBUF, &buf))
  123.             exit(-1);
  124.         buffers[n_buffers].length = buf.length;
  125.         // 映射内存
  126.         buffers[n_buffers].start =mmap (NULL,buf.length,PROT_READ | PROT_WRITE,MAP_SHARED,fd, buf.m.offset);
  127.         if (MAP_FAILED == buffers[n_buffers].start)
  128.             exit(-1);
  129.     } 
  130.     printf("info:memory mapping success\n");
  131.     return 1;
  132. }
  133. int buffer_enqueue(int fd)
  134. {
  135.     unsigned int i;
  136.     enum v4l2_buf_type type;
  137.     // 将缓冲帧放入队列
  138.     for (= 0; i < 4; ++i)
  139.     {
  140.         struct v4l2_buffer buf;
  141.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  142.         buf.memory = V4L2_MEMORY_MMAP;
  143.         buf.index = i;
  144.         if(-1==ioctl (fd, VIDIOC_QBUF, &buf))
  145.             printf("buffer enqueue failed\n");
  146.     }
  147.     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  148.     //open stream 
  149.     if(-1==ioctl (fd, VIDIOC_STREAMON, &type))
  150.         printf("info:open stream failed\n");
  151.     else
  152.         printf("info:open stream success\n");
  153.     return 1;
  154. }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值