Camera基础(Linux之V4L2驱动框架)

摄像头的基本工作原理

如图所示,一个景象的反射光被镜头所捕捉(镜头的光圈可以调节进光量,马达用来调节对焦),最终将聚焦好的图像精准对焦到图片传感器上边(色彩滤波会产生三基色),光信号转化为数字信号,通过模数转换最终得到原始码流数据。
问题:那我们可以直接使用这个包含图像信息和颜色信息的原始码流数据吗?
答案:不能,要根据用户端请求的VC接口携带请求数据流的格式决定。

二、编码
摄像头软件层,一般会提供多种格式和分辨率的参数,供上层选择,常见的格式如:YUYV、MJPEG、H264、NV12等。其中:

YUYV:原始码流,每个像素点占2个字节。
MJPEG:可以将数据压缩7倍左右,可以是NV12也可以是YUYV
H264编码:主要看配置,其中I帧压缩7倍左右,P帧20倍左右,B帧50倍左右,理论上B帧越多,就可能支持的高分辨率高帧率的码流
NV12:原始码流,每个像素点1.5个字节。
三、编码的目的
按照,我们整机常用的camera接口usb 2.0的理论带宽:480Mbps = 60M/s,
无法满足NV12原始码流4K 30HZ的预览要求的,编解码技术,可以有效的压缩数据的体积而不会或较少的影像画质。

四、传输
作为相机的数据传输协议,肯定是要统一的,广泛的,厂家和广大开发者支持的协议。其中USB协议肯定有一席之地。整机方案,基本采用的都是USB Camera方案。
UVC是USB Video Class的简写,也就是USB接口的视频设备。一个UVC设备,需包含1个VC Interface和1个或多个VS Interface

VC Interface进行配置参数的传递,如启动和关闭自动对焦,白平衡等。
VS Interface进行图片数据流的传输。
小结:
在Linux系统中,应用层和USB相机通过UVC协议进行交互。系统为了兼容不同的交互协议。在kernel层抽象了V4L2驱动,方便上层进程和各个协议对接。
V4L2提供了一系列的命令,如图所示,上层进程通过ioctl和底层kernel交互。

————————————————

什么是V4L2框架
V4L2(Video for Linux 2)是Linux操作系统中用于支持摄像头和视频设备的框架。它提供了一组API和驱动程序接口,用于在Linux系统中进行视频采集、视频流处理和视频播放等操作。

V4L2框架具有以下特点和功能:

设备抽象层:V4L2框架提供了一个设备抽象层,使得应用程序可以与各种不同类型的视频设备进行通信,包括摄像头、视频采集卡等。
统一的控制接口:V4L2定义了一套统一的控制接口,可以通过这些接口来配置和调整视频设备的各种参数,比如亮度、对比度、饱和度等。
视频捕获和输出:V4L2支持视频的捕获和输出功能,可以从视频设备中获取原始图像数据,并将其保存到文件或者进行实时显示。
视频流处理:V4L2框架提供了丰富的视频流处理功能,包括图像缩放、色彩空间转换、帧率控制、图像增强等,可以对视频数据进行实时的处理和操作。
内存映射和DMA支持:V4L2支持内存映射和DMA(直接内存访问)技术,可以加快视频数据的传输速度,提高系统性能。
事件和回调机制:V4L2框架支持事件和回调机制,可以实时通知应用程序有关视频设备和视频流的状态变化,比如帧捕获完成、设备断开连接等。
多线程支持:V4L2允许应用程序在多个线程中同时进行视频采集、处理和显示等操作,以实现并发处理和更高的效率。
V4L2框架的使用
在使用V4L2框架时,需要先了解一些基本的概念和接口。

设备文件和设备节点
在Linux系统中,每个设备都被视为一个文件,它们被组织成一个文件系统。每个设备都有一个设备文件名和一个设备节点号,设备文件名通常是/dev目录下的一个文件,而设备节点号则是一个整数值,用于标识设备。

对于V4L2设备,其设备文件名通常以/dev/video开头,后面跟着一个数字,表示设备节点号。例如/dev/video0就是第一个V4L2设备的设备文件名。

V4L2 API
V4L2框架提供了一组API,用于控制和管理视频设备。这些API主要包括以下几个部分:

设备操作:包括打开、关闭、查询设备信息等操作。
参数设置:包括设置视频格式、帧率、曝光时间、白平衡等参数。
缓冲区管理:包括申请/释放缓冲区、查询缓冲区状态等操作。
视频流控制:包括启动/停止视频采集、查询当前视频帧等操作。
V4L2驱动程序接口
V4L2驱动程序接口是驱动程序与用户空间应用程序之间的桥梁。驱动程序需要实现一组特定的函数,以响应应用程序发出的请求。这些函数通常包括以下几个:

open():打开设备。
close():关闭设备。
ioctl():处理应用程序发出的IO请求。
mmap():映射内存缓冲区。
poll():等待设备事件。

我们首先打开了/dev/video0设备文件,然后查询设备信息,并设置了视频格式。接着,我们分配了一个内存缓冲区,并映射到用户空间中,用于存储采集的图像数据。然后,我们启动了视频采集流程,并获取了一帧图像数据,将其保存到文件中。最后,我们停止视频采集,并释放缓冲区。

总结
V4L2框架是Linux操作系统中用于支持摄像头和视频设备的框架,它提供了一组API和驱动程序接口,用于在Linux系统中进行视频采集、视频流处理和视频播放等操作。在使用V4L2框架时,需要了解设备文件和设备节点、V4L2 API以及V4L2驱动程序接口等基本概念和接口。通过这些接口,开发者可以方便地进行视频采集、处理和输出等操作,从而实现各种视频应用和功能。

摄像头驱动原理和开发&&V4L2子系统驱动架构

 二、摄像头数据输出格式

1、USB、VS、MIPI摄像头架构

MIPI接口摄像头支持的分辨率、帧率更高,功率低。
MIPI比USB成本更低,USB摄像头昂贵。
USB摄像头开发工作量少,一般都是免驱的。
2、RAW RGB DATA
RAW RGB是sensor的bayer阵列获取的数据(每种传感器获得对应的颜色亮度),摄像头sensor经过光电转换后输出的数据就是RAW data(RAW RGB)。在Sensor中,每一个感光点只能感光RGB其中的一种颜色。所以,通常所说的30万像素或130万像素等,指的是有30万或130万个感光点,每一个感光点只能感光一种颜色。
RGB:传统的红绿蓝格式。比如RGB565,其16bit数据格式为5bitR+6bitG+5BitB,G多一位,原因是人眼对绿色比较敏感。


3、RAW RGB与RGB的区别

RAW RGB每个像素只有一种颜色(R、G、B中的一种)
RGB每个像素都有三种颜色,每一个值在0-255之间。
由sensor输出的数据RAW DATA(RAW RGB),经过ISP的彩色插值转换就变成了RGB。
4、YUV
Y表示亮度分量(Luma):如果只显示Y的话,图像看起来会是一张黑白照。
U(Cb)表示色度分量:是照片蓝色部分去掉亮度(Y)。
V(Cr)表示色度分量:是照片红色部分去掉亮度(Y)。
①YUV的优点:
与RGB相比,他的优点在于占用更少的空间
②YUV的采样格式
主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0
图像质量:YUV4:4:4>YUV4:2:2>YUV4:2:0 

 

YUV4:4:4采样,每一个Y对应一组UV分量。意思是4个像素里面的数据有4个Y,4个U,4个V。
YUV4:2:2采样,每一个Y对应一组UV分量。意思是4个像素里面的数据有4个Y,2个U,2个V。
YUV4:2:0采样,每一个Y对应一组UV分量。意思是4个像素里面的数据有4个Y,1个U,1个V。
③YUV的存储格式
YUV的存储格式分为打包格式(packet formats)和平面格式(planar formats)。

对于planar的YUV格式,先连续存储所有像素点的Y,随后存储U、V。存储类型表示为采样方式后缀加P,如YUV422P、YUV420P。
对于packet的YUV格式,每个像素点的Y,U,V是连续交替存储的。存储类型表示为采样方式后缀加SP,如YUV422SP、YUV420SP。

一帧YUV420图像中,u和v分量占用的空间大小分别是原来像素数的1/4,占用的总大小就是widthheigth(3/2)
一帧YUV422图像中,u和v分量占用的空间大小分别是原来像素数的一半,占用的总大小就是widthheigth2
5、MJPEG/H264编码格式
有些摄像头sensor支持输出MJPEG/H264编码格式的,是因为其内置了DSP处理器,将YUV数据编码后输出MJPEG/H264码流。
问题:什么情况下需要用到编码?有什么作用?
互联网传输,减少带宽。
视频编码兼容,统一视频编码标准。
三、视频编码原理

 1、视频编码的发展历程

2、视频编码原理
I帧:关键帧,采用帧内压缩技术。
P帧:向前参考帧,在压缩时,只参考前面处理过的帧,采用帧间压缩技术。
B帧:双向参考帧,在压缩时,它既参考前面的帧,又参考它后面的帧,采用帧间压缩技术。
除了I/P/B帧外,还有图像序列GOP。
GOP:两个I帧之间是一个图像序列,在一个图像序列中只有一个帧。在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量。如图:


四、V4L2子系统驱动架构
V4L2:是linux内核中关于视频设备的内核驱动框架,为上层访问底层的视频设备提供了统一的接口。

V4L2驱动核心:主要是构建一个内核中标准视频设备驱动的框架,为视频操作提供统一的接口函数。
平台V4L2设备驱动:在V4L2框架下,根据平台自身的特性实现与平台相关的V4L2驱动部分,包括注册video_device和v4l2_dev
具体的sensor驱动:主要上电、提供工作时钟、视频图像裁剪、流IO开启等,实现各种设备控制方法供上层调用并注册v4l2_subdev。
UVC:是一种usb视频设备驱动。用来支持usb视频设备,凡是usb接口的摄像头都能够支持。

V4L2的核心源码位于drivers/media/v4l2-core,根据功能可以划分为四类:

字符设备模块:由v4l2-dev.c实现,主要作用申请字符主设备号、注册class和提供video device注册、注销等相关函数。
v4l2基础框架L:由v4l2-device.c、v3l2-subdev.c、v3l2-fh.c、v4l2-ctrls.c等文件构建v4l2基础框架。
videobuf管理:由videobuf2-core.c、videobuf2-dma-contig.c、videobuf2-dma-sg.c、videobuf2-memops.c、videobuf2-vmalloc.c、v3l2-mem2mem.c等文件实现,完成videobuffer的分配、管理和注销。
loctl框架:由v4l2-ioctl.c文件实现,构建v4l2 ioctl的框架。
V4L2注册流程:

videobuf管理:

V4L2 ioctl框架
用户空间对V4L2设备的操作基本都是ioctl来实现的,V4L2设备都有大量可操作的功能(配置寄存器),所以V4L2的ioctl也是十分庞大的。

V4L2驱动主要使用的ioctl命令值如下:


五、摄像头视频采集流程


摄像头数据流:

六、常见典型问题
1、摄像头画面卡顿

帧率不足
usb带宽不足
视频采集格式设置出错:YUV、MJPEG或H264格式
编解码问题
CPU占用高
2、摄像头画面旋转90度或180度问题

3、摄像头画面打不开问题

参考:https://blog.csdn.net/qq_43533553/article/details/125409604

 

posted @ 2024-01-23 16:39  konglingbin  阅读(2083)  评论(0编辑  收藏  举报