• c 摄像头生成yuv未压缩图片


    播发yuv格式图片:ffplay -f rawvideo -video_size 1920X1080 -pixel_format  yuyv422  my.yuv

    此图片是没有进行过任何压缩处理的图片,是摄像头最高分辨率的图片。

    1. #include <stdio.h>
    2. #include <sys/types.h>
    3. #include <sys/stat.h>
    4. #include <fcntl.h>
    5. #include <stdlib.h>
    6. #include <unistd.h>
    7. #include <sys/ioctl.h>
    8. #include <linux/videodev2.h> //v4l2 头文件
    9. #include <string.h>
    10. #include <sys/mman.h>
    11. int main(void)
    12. {
    13. //1.打开设备
    14. int fd = open("/dev/video0", O_RDWR);
    15. if(fd < 0)
    16. {
    17. perror("打开设备失败");
    18. return -1;
    19. }
    20. //设置采集格式
    21. struct v4l2_format {
    22. enum v4l2_buf_type {
    23. V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
    24. V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
    25. V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
    26. }type;
    27. union {
    28. // struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
    29. struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
    30. struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
    31. struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
    32. __u8 raw_data[200]; /* user-defined */
    33. struct v4l2_pix_format {
    34. __u32 width;
    35. __u32 height;
    36. __u32 pixelformat;
    37. __u32 field; /* enum v4l2_field */
    38. __u32 bytesperline; /* for padding, zero if unused */
    39. __u32 sizeimage;
    40. __u32 colorspace; /* enum v4l2_colorspace */
    41. __u32 priv; /* private data, depends on pixelformat */
    42. __u32 flags; /* format flags (V4L2_PIX_FMT_FLAG_*) */
    43. union {
    44. /* enum v4l2_ycbcr_encoding */
    45. __u32 ycbcr_enc;
    46. /* enum v4l2_hsv_encoding */
    47. __u32 hsv_enc;
    48. };
    49. __u32 quantization; /* enum v4l2_quantization */
    50. __u32 xfer_func; /* enum v4l2_xfer_func */
    51. }pix;
    52. } fmt;
    53. }vfmt;
    54. vfmt.type=1;
    55. vfmt.fmt.pix.width=1920; //720p=1280*720 1080p=1920*1080
    56. vfmt.fmt.pix.pixelformat=v4l2_fourcc('Y','U','Y','V'); //生成不压缩的图片
    57. //播发yuv格式图片:ffplay -f rawvideo -video_size 1920X1080 -pixel_format yuyv422 my.yuv
    58. int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);
    59. if(ret < 0)
    60. {
    61. perror("设置格式失败");
    62. }
    63. //4.申请内核缓冲区个数
    64. struct v4l2_requestbuffers {
    65. __u32 count; //申请个数
    66. __u32 type; /* enum v4l2_buf_type */
    67. __u32 memory; /* enum v4l2_memory */
    68. __u32 capabilities;
    69. __u32 reserved[1];
    70. }reqbuffer;
    71. reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    72. reqbuffer.count = 1; //申请4个缓冲区
    73. reqbuffer.memory=V4L2_BUF_CAP_SUPPORTS_MMAP; //映射方式
    74. ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuffer);
    75. if(ret < 0)
    76. {
    77. perror("申请队列空间失败");
    78. }
    79. //设置 设备映射到内存的选项
    80. struct v4l2_buffer {
    81. __u32 index;
    82. __u32 type;
    83. __u32 bytesused;
    84. __u32 flags;
    85. __u32 field;
    86. struct timeval timestamp;
    87. struct v4l2_timecode timecode;
    88. __u32 sequence;
    89. /* memory location */
    90. __u32 memory;
    91. union {
    92. __u32 offset;
    93. unsigned long userptr;
    94. struct v4l2_plane *planes;
    95. __s32 fd;
    96. } m;
    97. __u32 length;
    98. __u32 reserved2;
    99. union {
    100. __s32 request_fd;
    101. __u32 reserved;
    102. };
    103. }mapbuffer;
    104. unsigned char *mptr;
    105. unsigned int size;
    106. mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    107. mapbuffer.index = 0;
    108. ret = ioctl(fd, VIDIOC_QUERYBUF, &mapbuffer);//查询缓冲区状态
    109. if(ret < 0)
    110. {
    111. perror("查询内核空间队列失败");
    112. }
    113. int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    114. ret = ioctl(fd, VIDIOC_STREAMON, &type); //启动流
    115. if(ret < 0)
    116. {
    117. perror("开启失败");
    118. }
    119. mptr= (unsigned char *)mmap(NULL, mapbuffer.length, PROT_READ|PROT_WRITE,
    120. MAP_SHARED, fd, mapbuffer.m.offset); //设备映射到缓冲区内存
    121. size=mapbuffer.length;
    122. ret = ioctl(fd, VIDIOC_QBUF, &mapbuffer); //把缓冲区数据放入读队列中
    123. if(ret < 0)
    124. {
    125. perror("放回失败");
    126. }
    127. ret = ioctl(fd, VIDIOC_DQBUF, &mapbuffer); //读当前队列缓冲区的数据
    128. if(ret < 0)
    129. {
    130. perror("提取数据失败");
    131. }
    132. FILE *file=fopen("my.yuv", "w+");
    133. fwrite(mptr,mapbuffer.length, 1, file);
    134. fclose(file);
    135. munmap(mptr, size);
    136. close(fd);
    137. return 0;
    138. }

     

     

  • 相关阅读:
    Android 14 系统启动流程 之 启动init进程、启动Zygote进程
    【Java面试】谈谈你对HashMap的理解(Map接口)
    C++ 多路音频pcm混音算法
    Java基础面试题精选:深入探讨哈希表、链表和接口等
    10-Django项目--Ajax请求
    Jmeter接口测试简易步骤
    医院电子病历编辑器,EMRE(EMR Editor)源码
    Java项目:音乐专辑商城系统(java+SSM+JSP+jQuery+Mysql)
    理清Spring事务的核心关键类
    Spring高手之路16——解析XML配置映射为BeanDefinition的源码
  • 原文地址:https://blog.csdn.net/m0_59802969/article/details/134408540