Linux下V4L2拍照



一、源码test.c

  1. #include <fcntl.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <linux/videodev2.h>
  5. int main(){
  6. //////
  7. int fd = open( "/dev/video0",O_RDWR);
  8. printf( "TK------->>>fd is %d\n",fd);
  9. //////
  10. struct v4l2_capability cap;
  11. ioctl(fd,VIDIOC_QUERYCAP,&cap);
  12. printf( "TK---------->>>>>Driver Name:%s\nCard Name:%s\nBus info:%s\n",cap.driver,cap.card,cap.bus_info);
  13. //////
  14. struct v4l2_fmtdesc fmtdesc;
  15. fmtdesc.index = 0; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  16. while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) != -1){
  17. printf( "TK-------->>>>>fmtdesc.description is %s\n",fmtdesc.description);
  18. fmtdesc.index ++;
  19. }
  20. //////
  21. struct v4l2_format fmt;
  22. fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  23. ioctl(fd,VIDIOC_G_FMT,&fmt);
  24. printf( "TK----------->>>>>fmt.fmt.width is %d\nfmt.fmt.pix.height is %d\nfmt.fmt.pix.colorspace is %d\n",fmt.fmt.pix.width,fmt.fmt.pix.height,fmt.fmt.pix.colorspace);
  25. //////
  26. struct v4l2_requestbuffers req;
  27. req.count = 4;
  28. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  29. req.memory = V4L2_MEMORY_MMAP;
  30. ioctl(fd,VIDIOC_REQBUFS,&req);
  31. struct buffer{
  32. void *start;
  33. unsigned int length;
  34. }*buffers;
  35. buffers = (struct buffer*) calloc (req.count, sizeof(*buffers));
  36. unsigned int n_buffers = 0;
  37. for(n_buffers = 0; n_buffers < req.count; ++n_buffers){
  38. struct v4l2_buffer buf;
  39. memset(&buf, 0, sizeof(buf));
  40. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  41. buf.memory = V4L2_MEMORY_MMAP;
  42. buf.index = n_buffers;
  43. if(ioctl(fd,VIDIOC_QUERYBUF,&buf) == -1){
  44. printf( "TK---------_>>>>>>error\n");
  45. close(fd);
  46. exit( -1);
  47. }
  48. buffers[n_buffers].length = buf.length;
  49. buffers[n_buffers].start = mmap( NULL,buf.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,buf.m.offset);
  50. if(MAP_FAILED == buffers[n_buffers].start){
  51. printf( "TK--------__>>>>>error 2\n");
  52. close(fd);
  53. exit( -1);
  54. }
  55. }
  56. ////
  57. unsigned int i;
  58. enum v4l2_buf_type type;
  59. for(i = 0; i < 4; i++){
  60. struct v4l2_buffer buf;
  61. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  62. buf.memory = V4L2_MEMORY_MMAP;
  63. buf.index = i;
  64. ioctl(fd,VIDIOC_QBUF,&buf);
  65. }
  66. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67. ioctl(fd,VIDIOC_STREAMON,&type);
  68. ////
  69. struct v4l2_buffer buf;
  70. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  71. buf.memory = V4L2_MEMORY_MMAP;
  72. ioctl(fd,VIDIOC_DQBUF,&buf);
  73. char path[ 20];
  74. snprintf(path, sizeof(path), "./yuyv%d",buf.index);
  75. int fdyuyv = open(path,O_WRONLY|O_CREAT, 00700);
  76. printf( "TK--------->>>>fdyuyv is %d\n",fdyuyv);
  77. int resultyuyv = write(fdyuyv,buffers[buf.index].start, 1280* 720* 2);
  78. printf( "TK--------->>>resultyuyv is %d\n",resultyuyv);
  79. close(fdyuyv);
  80. ////
  81. close(fd);
  82. return 0;
  83. }
二、编译运行

gcc test.c -o rest

./test

三、结果

在本目录下生成yuyv0这样一个文件,是jpeg编码后的文件。

四、极力推荐一款window下的图像查看工具YUVviewerPlus

  该工具可以将原始yuyv(如yuv422选择yuy2,需要后缀改为.yuv),rgb(rgb24选择gbmp24,需要后缀改为.bmp)等数据文件显示出来。

  另外说明:yuyv和jpeg数据大小为width*height*2;rgb为width*height*3;单位为Bytes。

猜你喜欢

转载自blog.csdn.net/zhouxinlin2009/article/details/81063689