V4L2的开发手册
在做v4l2的开发的时候, 可以使用v4l2-ctl
命令协助调试和软件开发。 关于linux多媒体开发可以参考链接:https://www.linuxtv.org/wiki/index.php/Main_Page
关于v4l2的api接口开发可以参考:https://linuxtv.org/docs.php
在linux下开发,可以借助ffmplay命令或者YUViewer软件进行读取显示。
基于V4l2进行图像读取
进行图像格式配置
请求缓冲
配置mmap内存映射
填写缓冲下标并加入缓冲队列
启动视频流
弹出队列里就绪的缓冲
v4l2 中会将申请的缓冲加入到缓冲列表里面,通过下标来指示当前的缓冲标识, 将缓冲加入队列的时候, 必须要注明下标的值。 将缓冲弹出队列的时候, 下标会通过驱动赋值传递给用户。 v4l2 有mmap,pointer, dma buf等方法进行读取图像加速。 比如内存映射就可以有效地避免代码在用户态和内核态来回切换, 直接将设备文件的句柄偏移映射到用户态的地址。 v4l2 支持mplane 多图层开发, 常见的YUV格式, 通过uv的不同组合方式,可以分为nv12,nv21等多种图像格式, Y表示亮度层, U表示色度层, V表示浓度层。 在V4l2下进行多图层开发的时候, 务必要重点学习struct v4l2_plane
, 其中, v4l2_plane.m.planes
指针的内存, 需要由用户进行开辟和释放。 在调试v4l2的时候, 可以通过打印errno
变量来获取当前V4L2的api接口执行失败的返回值。 在调用芯片厂商的算子IP时, 需要理解Stride的概念, 即跨距, 该值大于等于图像的原有宽度, 用户加速内存读取和算子计算。 用算子IP进行加速的时候, 会涉及虚拟地址和真实地址的概念。 操作系统里面代码能访问的,基本就是虚拟地址, 可以有效防止内存崩溃。 但是, 当我们需要传递数据给硬件IP, 如IVE,NPU等核心的时候, 就必须得传递真实地址给硬件。
v4l2常用的指令
v4l2-ctl -d /dev/video11 --stream-mmap //fps
v4l2-ctl -d /dev/video11 --set-fmt-video=width=352,height=288,pixelformat=NV12 --stream-mmap=3 --stream-skip=3 --stream-to=./output.yuv --stream-count=10 --stream-poll
v4l2-ctl --list-formats-ext --device /dev/video11v4l2-ctl --list-devicesbuild.sh clean media && build.sh media.v4l2-ctl -d /dev/video12 --infov4l2-ctl -d /dev/video12 --get-fmt-video --verbose
v4l2-ctl -d /dev/video11 --set-fmt-video=width=352,height=289,pixelformat=NV12 --verbose//配置摄像头参数,比如帧率和曝光时间,但是瑞芯微的仅能在ISP中通过3A server配置。
v4l2-ctl -d /dev/video11 --list-ctrlspixelformat = v4l2_fourcc
ffplay -f rawvideo -pixel_format nv12 -video_size 320x240 ./output.yuv # gray 播放灰度视频
YUView
media-ctl -p -d /dev/media1 //列出所有设备entity name和node name(char device)。
entity name: mainpath
node name: /dev/video11* |--mainpath----[wrap]--------->enc(or ddr)* | |->mainpath_4x4sampling--->ddr*output->|->bypasspath----------------->ddr* | |->bypasspath_4x4sampling->ddr* |->selfpath------------------->ddr* |->lumapath------------------->ddr------------------------
insmod ./oem/usr/ko/rve.ko
rk_rve_sample_test 1