Advertisement

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/o */

  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",

version的各字段提取如下:
driver = version >> 16 & 0xfff
card = version >> 8 & 0xfff
bus_info = version & 0xfff

  1. return 1;

  2. }

  3. int get_frame_fmt(int fd)

  4. {

  5. struct v4l2_fmtdesc fmtdesc;

  6. fmtdesc.index=0;

  7. fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;

  8. printf("info:Support format:");

  9. while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)

  10. {

  11. printf("\t%d.%s",fmtdesc.index+1,fmtdesc.description);

  12. fmtdesc.index++;

  13. }

  14. printf("\n");

  15. return 1;

  16. }

  17. int get_current_frame_info(int fd)

  18. {

  19. struct v4l2_format fmt;

  20. fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;

  21. ioctl(fd,VIDIOC_G_FMT,&fmt);

  22. printf("info:Current version data formats information:\n\t宽度(px):%d\n\t高度(px):%d\n",fmt.fmt.pix.width,fmt.fmt.pix.height);

  23. struct v4l2_fmtdesc fmtdesc;

  24. fmtdesc.index=0;

  25. fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;

  26. while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)

  27. {

  28. if(fmtdesc.pixelformat & fmt.fmt.pix.pixelformat)

  29. {

  30. printf("\tformat:%s\n",fmtdesc.description);

  31. break;

  32. }

  33. fmtdesc.index++;

  34. }

  35. return 1;

  36. }

  37. int try_format_support(int fd)

  38. {

  39. struct v4l2_format fmt;

  40. fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;

  41. //fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_RGB32;

  42. fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;

  43. if(ioctl(fd,VIDIOC_TRY_FMT,&fmt)==-1)

  44. if(errno==EINVAL)

  45. printf("info:not support format RGB32!\n");

  46. return 1;

  47. }

  48. int set_frame_format(int fd)

  49. {

  50. struct v4l2_format fmt;

  51. fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;

  52. fmt.fmt.pix.width=640;

  53. fmt.fmt.pix.height=480;

  54. fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

  55. fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

  56. if(ioctl(fd,VIDIOC_S_FMT,&fmt)==-1)

  57. if(errno==EINVAL)

  58. printf("info:set frame format error!\n");

  59. return 1;

  60. }

  61. int apply_memory_buf(int fd)

  62. {

  63. //struct v4l2_requestbuffers req;

  64. req.count=4;

  65. req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;

  66. req.memory=V4L2_MEMORY_MMAP;

  67. if(-1==ioctl(fd,VIDIOC_REQBUFS,&req))

  68. printf("info:VIDIOC_REQBUFS FAILED\n");

  69. else

  70. printf("info:VIDIOC_REQBUFS SUCCESS\n");

  71. return 1;

  72. }

  73. int memory_mapping(int fd)

  74. {

  75. unsigned int n_buffers;

  76. buffers = (struct buffer*)calloc(req.count,sizeof(struct buffer));

  77. if (!buffers) {

  78. fprintf (stderr, "Out of memory\n");

  79. exit (EXIT_FAILURE);

  80. }

  81. // 映射

  82. for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {

  83. //struct v4l2_buffer buf;

  84. memset(&buf,0,sizeof(buf));

  85. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  86. buf.memory = V4L2_MEMORY_MMAP;

  87. buf.index = n_buffers;

  88. // 查询序号为n_buffers 的缓冲区,得到其起始物理地址和大小

  89. if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buf))

  90. exit(-1);

  91. buffers[n_buffers].length = buf.length;

  92. // 映射内存

编号为126的缓冲区[buffers[n_buffers]]在其起始位置[.start]处调用内存映射函数[mmap](null, buffer长度[buf.length]、可读性和可写性 flags [PROT_READ | PROT_WRITE]、共享模式[MAP_SHARED]、文件描述符[fd]以及偏移量[buf.m.offset])。

  1. if (MAP_FAILED == buffers[n_buffers].start)

  2. exit(-1);

  3. }

  4. printf("info:memory mapping success\n");

  5. return 1;

  6. }

  7. int buffer_enqueue(int fd)

  8. {

  9. unsigned int i;

  10. enum v4l2_buf_type type;

  11. // 将缓冲帧放入队列

  12. for (i = 0; i < 4; ++i)

  13. {

  14. struct v4l2_buffer buf;

  15. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  16. buf.memory = V4L2_MEMORY_MMAP;

  17. buf.index = i;

  18. if(-1==ioctl (fd, VIDIOC_QBUF, &buf))

  19. printf("buffer enqueue failed\n");

  20. }

  21. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  22. //open stream

  23. if(-1==ioctl (fd, VIDIOC_STREAMON, &type))

  24. printf("info:open stream failed\n");

  25. else

  26. printf("info:open stream success\n");

  27. return 1;

  28. }

全部评论 (0)

还没有任何评论哟~