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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zimu_2080/article/details/86629235

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的点亮、上电、元数据处理等等。

猜你喜欢

转载自blog.csdn.net/zimu_2080/article/details/86629235