一、摄像头的基本工作原理
如图所示,一个景象的反射光被镜头所捕捉(镜头的光圈可以调节进光量,马达用来调节对焦),最终将聚焦好的图像精准对焦到图片传感器上边(色彩滤波会产生三基色),光信号转化为数字信号,通过模数转换最终得到原始码流数据。
问题:那我们可以直接使用这个包含图像信息和颜色信息的原始码流数据吗?
答案:不能,要根据用户端请求的VC接口携带请求数据流的格式决定。
二、编码
摄像头软件层,一般会提供多种格式和分辨率的参数,供上层选择,常见的格式如:YUYV、MJPEG、H264、NV12等。其中:
- YUYV:原始码流,每个像素点占2个字节。
- MJPEG:可以将数据压缩7倍左右,可以是NV12也可以是YUYV
- H264编码:主要看配置,其中I帧压缩7倍左右,P帧20倍左右,B帧50倍左右,理论上B帧越多,就可能支持的高分辨率高帧率的码流
- NV12:原始码流,每个像素点1.5个字节。
三、编码的目的
如果没有编码,我们计算一下1s请求NV12 4K 30HZ的码流需要多大的带宽? 答案:(3840*2160*1.5*30)字节 = 373248000字节=356M
按照,我们整机常用的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进行图片数据流的传输。
USB协议
UVC协议:
UVC模型:
UVC软件架构
小结:
在Linux系统中,应用层和USB相机通过UVC协议进行交互。系统为了兼容不同的交互协议。在kernel层抽象了V4L2驱动,方便上层进程和各个协议对接。
V4L2提供了一系列的命令,如图所示,上层进程通过ioctl和底层kernel交互。
如此,上层应用就能拿到相机设备给出的编码后的码流了。但是如果整机方案是Android系统,那和linux还是有着一定的不同的。Android系统可以向下,可以使V4l2通过ioctl和kernel交互。
五、Android系统的camera架构
Android APSP系统作为开源的系统,需要考虑很多因素,既要考虑下游硬件设备厂商,也要考虑应用开发者,还要考虑用户隐私安全。所以,Google对Android下的Camera的架构,分了3层设计。
- CameraProvider hal层的进程,init rc启动时启动。
- CameraServer Framework层进程,主要用于维护上层apk都可能访问Camera服务
- Camera的Runtime层,为上层apk提供服务,并封装了一系列的api,方便广大开发者调用和快速开发。
Android camera架构图:
小结:
android系统通过分层设计,给到每个上层应用独立访问相机设备的能力,上层应用可以通过简单的api调用就可以实现相机的预览和拍照功能。
原始码流数据通过编码,把数据进行压缩通过USB送到kernel,kernel通过UVC协议Hal层进行交互,HAL层拿到数据后,CamerServer会通过hwbinder与Hal层进行交互,然后进行显示。