重构V4L2流程(解决传统read/write,采用内存映射mmap)

📅 2026/6/29 19:59:36
重构V4L2流程(解决传统read/write,采用内存映射mmap)
在用户空间申请内存对应内核空间缓存MJPEG运动静止图像压缩技术原理视频每一帧单独压缩成一张 JPG 图片连续播放无帧间压缩req.memory V4L2_MEMORY_MMAP驱动在内核空间申请一组 DMA 物理连续帧缓存用户态调用mmap()把内核缓存直接映射到进程虚拟地址摄像头硬件 DMA 直接写入共享内存无需内核→用户态 CPU 拷贝低延迟、高性能。// 2. 使用mmap映射缓冲区到用户空间// mmap参数说明// - NULL: 让系统自动选择映射地址// - buf.length: 映射长度缓冲区大小// - PROT_READ | PROT_WRITE: 可读可写权限// - MAP_SHARED: 共享映射与内核共享内存// - fd: 设备文件描述符// - buf.m.offset: 缓冲区在设备文件中的偏移量buffers[i].start mmap(NULL, buf.length,PROT_READ | PROT_WRITE,MAP_SHARED, fd, buf.m.offset);DMA 缓冲区内存映射内核把摄像头硬件 DMA 物理内存映射到用户进程虚拟地址空间实现零拷贝采集物理地址硬件 / 驱动视角DMA 缓冲区真实物理内存地址只有内核、摄像头硬件能直接访问。用户虚拟地址你的程序指针 buffers [i].startmmap 在你进程的虚拟地址空间分配一段虚拟地址映射绑定到那块物理内存。MMAP 流程open → S_FMT → REQBUFS → QUERYBUF mmap → QBUF 全部缓存 → STREAMON → DQBUF 循环取帧READ 流程open → S_FMT →直接 read 循环取帧无缓存申请、映射、入队操作#### 1.3.1 基本开发步骤1. **检查设备**确认 /dev/video0 存在且可访问2. **打开设备**使用 open() 打开设备文件3. **查询能力**使用 VIDIOC_QUERYCAP 获取设备信息4. **枚举格式**使用 VIDIOC_ENUM_FMT 查看支持的格式5. **设置格式**使用 VIDIOC_S_FMT 设置视频格式6. **申请缓冲区**使用 VIDIOC_REQBUFS 申请缓冲区7. **映射缓冲区**使用 mmap() 映射缓冲区8. **启动采集**使用 VIDIOC_STREAMON 开始采集9. **循环采集**使用 VIDIOC_QBUF 和 VIDIOC_DQBUF 循环获取帧10. **停止采集**使用 VIDIOC_STREAMOFF 停止采集11. **清理资源**释放缓冲区关闭设备