今天是周五了,时间过得真快,通常这个时候,我都还沉醉了上班的状态中,说到上班,我是认真的,我非常喜欢上班,特别是今天,我会听到一声优美的声音,我的银行卡会多出一些钱,而这些最粗鲁的奖励也是我最讨厌的,我认为,上班就上班嘛,为什么要发工资呢。哈哈~提前祝大家周末愉快。这篇文章跟摄像头有关,是我一个做摄像头工作很久的同学总结的,如果在摄像头方面想有所建树,我可以帮忙引荐认识一下,或者在工作上遇到影像方面的难题,也可以请教一下,就这样。
前言摘要
随着技术的发展,摄像头在手机中是非常重要的模块,也是目前主流手机品牌主打的一个功能模块。例如oppo 手机广告语 「照亮你的美,柔光自拍」,小米手机「有你拍照会更加美」华为手机更是采用高端的莱卡摄像头,mate系列拍照简直是逆天表现,这些产品的买点和打造,没有能够离开摄像头这个重要的功能角色。所以对在校学生,还是即将走向工作岗位或者在工作岗位想从事影像技术开发的爱好者,从现在开始,我将带领你们走入camera开发,通过阅读这些文档,掌握camera开发技术,对于毕业生来讲,是谋职一个热门的专业领域,对工作的工程师,可以拓宽你们camera模块的专业技能,如果你们通过阅读我写的文档,能够有收获,那么我的付出会感到欣慰。
camera软件整体架构图
我们来先看camera软件整体架构
App应用端
APP代码位置:packages/apps/Camera2
代码功能:
主要对 android.hardware.Camera(在Framework中) 类的调用,并且实现Camera 应用的业务逻辑和UI 显示。Camera 的应用层在Android 上表现为直接调用SDK API 开发的一个Camera 应用APK包。一个Android 应用中若要使用这个android.hardware.Camera类,需要在Manifest 文件声明Camera的权限,另外还 需要添加一些<uses-feature> 元素来声明应用中的Camera 特性,如自动对焦等。
framework层
framework
代码位置:
frameworks/base/core/java/android/hardware/Camera.java
编译调试:
mmm frameworks/base,代码编译成framework.jar。
代码功能:
AP端必须包含android.hardware.Camera类,才可以调用framework接口函数。
JNI层
Jni
代码路劲:
frameworks/base/core/jni/android_hardware_Camera.cpp。
编译调试:
mmm frameworks/base/core/jni,代码编译成libandroid_runtime.so
代码功能:
这是是Android提供给app层调用的java接口。这个类用来连接或断开一个Camera服务,设置拍摄参数,开始、停止预览,拍照等。android.hardware.Camera这个类是和JNI中定义的类是一个,有些方法通过Jni的方式调用本地代码得到,有些方法自己实现。
camera client
代码位置:
frameworks/av/camera/
qinyuanyi@sz-ubuntu-01:~/work/qcom$ ls
frameworks/av/camera/
include //头文件
ICameraClient.cpp
CameraBase.cpp
CameraParameters2.cpp
CameraUtils.cpp
ICamera.cpp
Camera.cpp
CameraParameters.cpp
CaptureResult.cpp
ICameraRecordingProxy.cpp
编译调试:
mmm frameworks/av/camera/ ,被编译成库libcamera_client.so。
代码功能:
frameworks/av/camera/目录下,主要功能部分的代码为Camera.cpp、ICameraService.cpp、ICamera.cpp、ICameraClient.cpp、CameraBase.cpp在Camera模块的各个库中,libcamera_client.so 位于核心的位置,作为Camera框架的 Client客户端部分,与另外一部分内容服务端libcameraservice.so通过进程间通讯(即Binder机制)的方式进行通讯。其中Camera.cpp是主要的核心部分,它提供了对上层的主要功能接口。ICameraClient 类继承IInterface,并定义了Camera客户端的接口,BnCameraClient 继承BnInterface,这是为基于Android的基础类Binder机制实现在进程通讯而构建的。
camera service
代码位置:
frameworks/av/services/camera/libcameraservice/
qinyuanyi@sz-ubuntu-01:~/work/qcom$ ls frameworks/av/services/camera/libcameraservice/ Android.mk api1 api2 device1 device3 CameraFlashlight.h CameraService.h CameraService.cpp CameraFlashlight.cpp common
编译调试:
mmm frameworks/av/services/camera/libcameraservice/,被编译成库libcameraservice.so。
代码功能:
libcameraservice.so是Camera 框架的中间层,Camera服务器程序,它实现了Camera服务端的功能,并且与libcamera_client.so通过进程间通讯(即 Binder机制)的方式进行通讯。然后通过调用实际的Camera 硬件接口来实现功能,即下层HAL层。
CameraService里面主要实现了两个类: CameraService---->BnCameraService---->ICameraService CameraService::Client---->BnCamera---->ICamera CameraService::Client通过调用CameraHAL层控制具体的硬件操作流程来实现具体的功能。
libcameraservice的启动:
vim frameworks/av/media/mediaserver/main_mediaserver.cp
libcameraservice调用CameraHAL层关键代码:
frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h CameraClient.cpp是CameraService::Client类的实现,该类提供了给ICamera调用的startPreview等相关功能接口,在CameraClient的各函数中,通过初始化CameraHardwareInterface类并调用它提供的操作接口连接到Hal层。
CameraHardwareInterface.h是libcameraservice与cameraHal的接口。在它的initialize函数中调用了从module的open函数返回了mDevice,mDevice提供了上层的一系列的操作函数集合,通过调用mDevice->ops的相应的相应指针进行调用,比如下边的startPreview函数。
hal层
代码位置:
hardware/qcom/camera/QCamera2/
x@sz-ubuntu-01:~/work/qcom$ ls hardware/qcom/camera/QCamera2/ Android.mk
HAL HAL3 stack util QCamera2Factory.cpp QCamera2Factory.h QCamera2Hal.cpp QCameraFormat.h
HAL 和 HAL3:分别是camera hal1和hal3架构,目前主流趋势是hal3.不过hal1架构目前比较稳定。
QCamera2Factory.cpp:qcom和mtk厂商定制的接口
QCamera2Hal.cpp:实现函数映射,通过QCamera2Hal.cpp去访问QCamera2Factory.cpp
编译调试:mmm hardware/qcom/camera/QCamera2/
生成平台“camera.xxx平台.so”。
代码功能:厂商的定制hal层都在这个目录,我们算法的接入也是在这个目录。所以hal是framework和kernel底层通信的桥梁。Qcom对hal层数据流的管理采用channel和stream方式,其中包括对内存的申请和分配都在其中进行。
vendor层
代码位置:
vendor/qcom/proprietary/mm-camera
qinyuanyi@sz-ubuntu-01:~/work/qcom$ls
vendor/qcom/proprietary/mm-camera/mm-camera2/ Android.mk
includes
log_debug
media-controller
server-imaging
server-tuning
services tests
编译调试:mmm vendor/qcom/proprietary/mm-camera,不同目录下面生成平台xxx.so。然后根据每个目录下面的mk文件,查找对应so库。
代码功能:Qcom这里采用mct demon进程控制,hal和mct通信是通过socket通信方式进行传输的,那么从底层拿到数据以后,通过mct方式进行传输,然后抛给hal层。
kernel层
代码位置:kernel/drivers/media/platform/msm/camera_v2/
@sz-ubuntu-01:~/work/qcom$ ls
kernel/drivers/media/platform/msm/camera_v2/
camera
common
fd
isp
ispif
jpeg_10
jpeg_dma
Kconfig
Makefile
msm_buf_mgr
msm.c
msm.h
msm_sd.h
msm_vb2
pproc
sensor
编译调试:make -j16 使用正常的编译kernel的命令即可,不同平台对于kernel的编译可能稍微有差异。
代码功能:Kernel下面底层的kernel逻辑代码功能模块都在这里。Sensor驱动的probe和AF flash驱动都在这里实现。
小结
上面是对camera模块框架的初步分析和认识,大家对整个框架先有个初步的了解,随着学习的深入,我们会逐步的深入到某一层进行剖析,结合实际的开发,让大家知道实际开发中需要做的工作。并对学习的知识点进行深入的理解和思考,那么会随着水平的提高,重构出性能更加完美的架构和系统,期待这个指引能够激发你们的学习热情,并且成为未来影像技术的专家。
参考:
参考的文章是我很久之前写的,如果当时我是在MTK平台上分析的,希望对大家有所帮助
https://linus.blog.csdn.net/article/details/49943289