嵌入式Linux--从用户空间调用 V4L2 接口2

视频设备的启停与属性管控

应用若要与视频设备对接,首先要向 /dev/videoX 发起调用,借助 open() 拿到文件描述符,借此打通后续指令的传输通道。

若想让读取流程不被阻塞,只需在打开时传入 O_NONBLOCK,这样即便没有就绪缓冲区,接口也不会停滞,只会返回 EAGAIN。待业务结束,再以 close() 善后即可。

设备开启后,探明其能力底细是首要功课,调用 VIDIOC_QUERYCAP 即可。使用前务必将 struct v4l2_capability 清零,避免历史数据干扰。驱动填好 .capabilities 后,应用需仔细查验:能代表采集设备的 V4L2_CAP_VIDEO_CAPTURE、支撑流式传输的 V4L2_CAP_STREAMING 以及兼容读写模式的 V4L2_CAP_READWRITE 皆属关键标志,多平面设备还附带对应专属标识,一切核对无误,方能为后续操作夯实根基。

缓冲区的统筹调度

V4L2 借助双队列机制维系数据流转:驱动端维护输入队列,用户端坐拥输出队列。应用可通过 VIDIOC_QBUF 将空缓冲区送入驱动队列,驱动依序填充,一旦满载便转存入用户队列;随后应用以 VIDIOC_DQBUF 取出数据,处理完结再让缓冲区重返队列,整套循环井然有序。若输出队列空虚,出队动作会陷入阻塞,唯有非阻塞模式能抛出 EAGAIN 化解僵局。想要正常运转,应用需依循请求缓冲区、排队、启动流传输的标准流程。

图像格式的精准协商

缓冲区的视觉规格,全靠 struct v4l2_format 描摹。采集类设备选用 V4L2_BUF_TYPE_VIDEO_CAPTURE,将像素、宽高等细节写入 .fmt.pix。应用既可用 VIDIOC_G_FMT 摸清当前状态,也能调整宽高、像素格式、色彩空间、行字节数等参数,再以 VIDIOC_S_FMT 敲定配置,常见的格式有 YUYV、NV12 等。若对格式适配性心存疑虑,VIDIOC_TRY_FMT 可充当试金石。

毕竟 VIDIOC_S_FMT 未必全盘接纳请求,驱动常以最贴近的方案代偿,应用必须核查实际下发的参数,顺势调整策略。

帧率的调控同样不容忽视,借由 VIDIOC_G_PARM 可查询流参数,只要确认具备 V4L2_CAP_TIMEPERFRAME 标志,便能通过枚举帧间隔、调用 VIDIOC_S_PARM 达成设置,同时要对驱动调整后的结果做好复核。

缓冲区的多元化请求
VIDIOC_REQBUFS 是索取视频帧内存的核心入口,借助 struct v4l2_requestbuffers 设定缓冲区数量、设备类型与内存模式。常规情形下,申请三到四个缓冲区足以规避丢帧隐患。内存模式涵盖 MMAP、USERPTR、DMABUF 三大流派,驱动发放的数量或许不及预期,必须严查是否贴合应用底线,这也是探明驱动兼容何种流式传输的唯一良方。

若走 USERPTR 路线,应用需自行开辟内存,随后将地址与大小如实告知;选用 MMAP 模式,则是向驱动讨要缓冲区,用 VIDIOC_QUERYBUF 摸清偏移量,再借 mmap() 打通内存映射;DMABUF 模式则通过 VIDIOC_EXPBUF 将缓冲区化作文件描述符,专为跨设备共享而生,完美适配内存到内存的应用场景。至于读写 I/O 模式最为简便,无需请求缓冲区,只需备好内存,直接读取即可,非阻塞状态下亦能从容应对空载情形。

流转调度与收尾

缓冲区一旦入队,其内存页便被牢牢锁死,以防被换出,这种锁定状态唯有出队、停止流传输、重新申请缓冲区或关闭设备时方能解除。在启动采集前,提前排入适量空缓冲区,既能提升画面流畅度,又能杜绝无数据可取的尴尬。

启动流传输须靠 VIDIOC_STREAMON 下达指令,唯有如此,后续的出队操作才算名正言顺。出队时若遇缓冲区空缺,程序便会受阻,非阻塞模式成为破局之法,一旦出队成功,必须迅速将缓冲区重新入队,让采集循环生生不息。

采集固定帧数时,只需循环演绎出队、处理、入队即可。待任务终结,VIDIOC_STREAMOFF 负责叫停传输、清空队列,随后关闭设备、释放内存,便是完整的收尾流程。

掌握这套用户空间的开发逻辑后,借助 v4l-utils 等现成工具,无需逐行雕琢代码,也能迅速搭建起相机系统原型,让开发工作事半功倍。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容