欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 8.1 MTK Camera(api1)源码框架分析

程序员文章站 2022-05-08 19:29:20
...

Android 8.1 MTK Camera(api1)框架

Android Camera框架从整体看是一个c/s的架构,有两个进程:

一个是client进程,属于AP端用户的行为,是为应用程序进程,主要包括java代码与一些native c/c++代码;
另一个是service进程,属于服务端,是native c/c++代码,主要负责和linux kernel中的camera driver交互,搜集linux kernel中camera driver传上来的数据,并交给显示系统(surface)显示。

client进程与service进程通过IPC Binder机制通信,client端通过调用service端的接口实现各个具体的功能。(客户端进程承载用户的需求,由Binder进程间通信送往服务端实现设备的功能,服务端由回调函数和消息机制反馈数据返还给用户。)

Android中Camera的调用流程可分为以下几个层次:
1.AP
2.Framework
3.JNI
4.Camera client
5.binder
6.Camera service
7.Camera HAL
8.Camera Driver

1.Ap调用

android.hardware.Camera(在Framework中) 类的调用,实现相关接口,完成业务逻辑。

\vendor\mediatek\proprietary\packages\apps\Camera
\vendor\mediatek\proprietary\packages\apps\Camera2

mtk camera app有两套文件,分别是Camera和Camera2,Camera是针对api1来做的,同mtk android 6.0及之前的camera ap架构一致;而Camera2是针对兼容api1和api2来做的,但是实际查看修改代码时才发现,只是适配了api2的接口,但是实际使用的还是Camera api1,这应该是为之后的架构变化所做的修改。
两套代码结构都很不同。对于api2的真正使用,mtk放在了Android P上。

区分使用的那套,通过ap目录下的mk文件:
如Camera2目录中mk文件宏判断:

ifneq ($(filter 2 3, $(MTK_CAMERA_APP_VERSION)),)

Camera目录中mk文件宏判断:

ifeq ($(MTK_CAMERA_APP_VERSION), 1)

宏MTK_CAMERA_APP_VERSION定义在系统device目录中,通过project名去查找即可。

2.Framework

api路径:/android/frameworks/base/core/java/android/hardware/Camera.java
定义公开接口、变量、函数等api给ap层相机使用者,调用jni函数,来实现预览、参数设置、拍照、录像等功能。JAVA 代码到C++ 代码的桥梁。

内部类

Camera.CameraInfo 获取camera特性,如方向、id、摄像头数目等
Camera.Face 人脸数据的矩阵
Camera.Parameters 参数设置类
Camera.Size
Camera.Area

内部接口回调

Camera.AutoFocusCallback  自动对焦回调
Camera.AutoFocusMoveCallback  连续对焦回调
Camera.ErrorCallback      camera open或使用过程中出现的error回调
Camera.FaceDetectionListener  人脸检测回调
Camera.OnZoomChangeListener  焦距变化回调
Camera.PictureCallback  拍照数据回调
Camera.PreviewCallback  预览实时数据回调
Camera.ShutterCallback	  拍照快门回调

3.JNI

Camera的java native调用部分(JNI):/android/frameworks/base/core/jni/android_hardware_Camera.cpp。

该文件中的register_android_hardware_Camera(JNIEnv *env) 函数会将native函数注册到虚拟机中,以供Framework层的java代码调用,通过该入口,可以获取到framework层用于创建android.hardware.Camera对象的相关数据。这些native函数通过调用libcamera_client.so中的Camera类实现具体的功能。

// Get all the required offsets in java class and register native functions
int register_android_hardware_Camera(JNIEnv *env)
{
.......

    jclass clazz = FindClassOrDie(env, "android/hardware/Camera");
    fields.post_event = GetStaticMethodIDOrDie(env, clazz, "postEventFromNative",
                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");

    clazz = FindClassOrDie(env, "android/graphics/Rect");
    fields.rect_constructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");

    clazz = FindClassOrDie(env, "android/hardware/Camera$Face");
    fields.face_constructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");

    clazz = env->FindClass("android/graphics/Point");
    fields.point_constructor = env->GetMethodID(clazz, "<init>", "()V");
    if (fields.point_constructor == NULL) {
        ALOGE("Can't find android/graphics/Point()");
        return -1;
    }

    // Register native functions
    return RegisterMethodsOrDie(env, "android/hardware/Camera", camMethods, NELEM(camMethods));
    //camMethods就是需要注册的函数,这里封装了一下。
}

4.Camera client

Camera client层的定义位于frameworks/av/camera/Camera.cpp 这个类通过调用IPC binder代理来获取camera service的访问接口。
主要文件如下,client打包生成libcamera_client.so

Camera.cpp/Camera.h
CameraParameters.cpp/CameraParameters.h
ICamera.cpp/ICamera.h
ICameraClient.cpp/ICameraClient.h
CameraBase.cpp/CameraBase.h
ICameraService.aidl/

5.binder

IPC binder代理来实现camera client和service的进程间通信。
在frameworks/av/camera目录下有三个camera binder类的定义。ICameraService是cameraservice的接口,ICamera是被打开的camera设备的接口,ICameraClient是camera设备返回给application framework层的接口。

6.Camera service

Camera service层的定义位于frameworks/av/services/camera/libcameraservice/CameraService.cpp中。它是与camera HAL交互的实际代码。Service模块打包生成libcameraservice库文件。

CameraService 是Camera 服务,Camera 框架的中间层,用于向下连接CameraHardwareInterface 和向上连接Client部分,它通过调用实际的Camera hal硬件抽象层接口来实现相关功能。

frameworks\av\media\mediaserver\main_mediaserver.cpp中对camera service进行初始化的服务注册。

int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

    sp<ProcessState> proc(ProcessState::self());
    ////////具体封装在defaultServiceManager()函数中
    sp<IServiceManager> sm(defaultServiceManager());
    ALOGI("ServiceManager: %p", sm.get());
    InitializeIcuOrDie();
    MediaPlayerService::instantiate();
    ResourceManagerService::instantiate();
    registerExtensions();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

Main_MediaServer主函数由init.rc在启动是调用,所以在设备开机的时候Camera就会注册一个服务,用作binder通信,提供给client随时使用。

7.Camera HAL

camera硬件抽象层接口实现,在camera service调用到CameraHardwareInterface.cpp/CameraHardwareInterface.h来进行连接。

具体路径:\frameworks\av\services\camera\libcameraservice\device1

hal层代码位置:vendor/mediatek/proprietary/hardware/mtkcam

8.Camera Driver

这一层主要是基于Linux的设备驱动。驱动进行camera的点亮、上电、元数据处理等等。

相关标签: camera