Linux下V4L2拍照

本文介绍了一段使用V4L2接口从视频设备读取数据并保存为YUYV格式的C语言代码示例。通过open、ioctl、mmap等系统调用,实现了视频设备的初始化、格式获取、缓冲区分配、数据读取等功能,并详细展示了如何将读取的数据写入文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



一、源码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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值