Android8.0 Camera系统架构(二)

版权声明:未经本人同意,不得转载 https://blog.csdn.net/u013928208/article/details/82181786

上一篇我们从最新的Camera架构来分析Camera子系统,今天我们将从全局的视角从旧版本到新版本架构整体通览一遍,从Framework层的API(1和2)到硬件抽象层的HAL(1和3)。废话少说一起来看一下整体架构:

这里写图片描述

从整体架构图来看,上层API相互独立,中间Camera库耦合度低,HAL层构建合理;APIv1对应HAL1和HAL2。前后两套API耦合度低,APIv2几乎是重写了整个结构。废话少说我们直接上代码。

1. Camera和JNICameraContext

frameworks\base\core\java\android\hardware\Camera.java
frameworks\base\core\jni\android_hardware_Camera.cpp

创建相机时,执行相机初始化

private native final int native_setup(Object camera_this, int cameraId, int halVersion, String packageName);

frameworks\base\core\jni\android_hardware_Camera.cpp
执行初始化时会进行,HAL版本判断

// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
    //
    sp<Camera> camera;
    if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) { //不关心HAL版本
        // Default path: hal version is don't care, do normal camera connect.
        camera = Camera::connect(cameraId, clientName,
                Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
    } else {
        jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
                Camera::USE_CALLING_UID, camera);
    }
    sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);//存副本
    context->incStrong((void*)android_hardware_Camera_native_setup);
    camera->setListener(context);
    env->SetLongField(thiz, fields.context, (jlong)context.get()); //存上下文
    CameraInfo cameraInfo;
    status_t rc = Camera::getCameraInfo(cameraId, &cameraInfo); //获取相机信息
    return NO_ERROR;
}

从拍照调用看JNI层

 private native final void native_takePicture(int msgType);

调用Camera拍照

static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz, jint msgType)
{
    JNICameraContext* context;
    sp<Camera> camera = get_native_camera(env, thiz, &context); //获取C++层的Camera
    if (camera == 0) return;
    if (camera->takePicture(msgType) != NO_ERROR) {//进行拍照
        return;
    }
}

2. Camera与CameraClient

不关心HAL版本,返回一个Camera实例

sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
        int clientUid, int clientPid)
{   //CameraBaseT来自哪
    return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}

frameworks\av\camera\include\camera\CameraBase.h

 typedef CameraBase<TCam>         CameraBaseT; // what ? 哪来的 TCam

TCam来自于模板类声明

template <typename TCam>
struct CameraTraits { //啥都没有的结构体
};
template <typename TCam, typename TCamTraits = CameraTraits<TCam> >
class CameraBase : public IBinder::DeathRecipient { ...... }

frameworks\av\camera\include\camera\Camera.h
在Camera的头文件中,可以看出 TCam = Camera

template <>
struct CameraTraits<Camera>
{
    typedef CameraListener                     TCamListener;
    typedef ::android::hardware::ICamera       TCamUser;
    typedef ::android::hardware::ICameraClient TCamCallbacks;
    typedef ::android::binder::Status(::android::hardware::ICameraService::*TCamConnectService)
        (const sp<::android::hardware::ICameraClient>&,
        int, const String16&, int, int,
        /*out*/
        sp<::android::hardware::ICamera>*);
    static TCamConnectService     fnConnectService;
};

class Camera :
    public CameraBase<Camera>,
    public ::android::hardware::BnCameraClient { ...... } //CameraClient的服务端

frameworks\av\camera\CameraBase.cpp
Camera的connect函数调用

template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
                                               const String16& clientPackageName,
                                               int clientUid, int clientPid)
{
    sp<TCam> c = new TCam(cameraId);
    sp<TCamCallbacks> cl = c;
    const sp<::android::hardware::ICameraService> cs = getCameraService(); //获取CameraService

    binder::Status ret;
    if (cs != nullptr) {
        TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
                                               clientPid, /*out*/ &c->mCamera);
    }
    ......
    return c;
}

frameworks\av\camera\Camera.cpp
我的天,我看到了什么,直接调用了CameraService的connect函数

CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
        &::android::hardware::ICameraService::connect;

上一篇在CameraService执行connect函数时会执行makeclient(),此时会根据各参数返回不同类型的camera实例,让我们重温一下:

Status CameraService::makeClient(const sp<CameraService>& cameraService,
        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
        int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
        int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
        /*out*/sp<BasicClient>* client) {

    if (halVersion < 0 || halVersion == deviceVersion) { //未指定特殊硬件抽象层版本
        switch(deviceVersion) {
          case CAMERA_DEVICE_API_VERSION_1_0: //版本 HAL v1.0
            if (effectiveApiLevel == API_1) {  //版本 API v1.0
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                //创建CameraClient实例
                *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
                        facing, clientPid, clientUid, getpid(), legacyMode);
            }else { //版本 API v2.0
                ALOGW("Camera using old HAL version: %d", deviceVersion);
                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
                        "Camera device \"%s\" HAL version %d does not support camera2 API",
                        cameraId.string(), deviceVersion);
            }
            break;
          case CAMERA_DEVICE_API_VERSION_3_0: //版本 HAL3
          case CAMERA_DEVICE_API_VERSION_3_1:
          case CAMERA_DEVICE_API_VERSION_3_2:
          case CAMERA_DEVICE_API_VERSION_3_3:
          case CAMERA_DEVICE_API_VERSION_3_4:
            if (effectiveApiLevel == API_1) { // 版本API1
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),
                        facing, clientPid, clientUid, servicePid, legacyMode);
            } else {  // 版本API2 最新版本
                sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
                        static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
                *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
                        facing, clientPid, clientUid, servicePid);
            }
            break;
          default:
            // Should not be reachable ......
        }
    } else { //指定了特殊硬件抽象层版本
        // A particular HAL version is requested by caller. Create CameraClient
        // based on the requested HAL version.
        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
            // Only support higher HAL version device opened as HAL1.0 device.
            sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
            *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
                    facing, clientPid, clientUid, servicePid, legacyMode);
        } else {
            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
                    " opened as HAL %x device", halVersion, deviceVersion,
                    CAMERA_DEVICE_API_VERSION_1_0);
            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
                    "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
                    cameraId.string(), deviceVersion, halVersion);
        }
    }
    return Status::ok();
}

根据判断我们来看 API v1.0和/版本HAL v1.0下的CameraClient

class CameraClient : public CameraService::Client { ...... }

Client继承了BnCamera,如此一来如架构图所述,Camera和CameraClient通过ICameraClient和ICamera跨进程通讯

 class Client : public hardware::BnCamera, public BasicClient { ...... }

frameworks\av\services\camera\libcameraservice\api1\Camera2Client.h
那么在API v1.0和/版本HAL v3的Camera2Client 又是咋样的呢

class Camera2Client :
        public Camera2ClientBase<CameraService::Client>
{

果不其然 Camera2Client 继承自 Camera2ClientBase 间接继承自 CameraService::Client

template <typename TClientBase>
class Camera2ClientBase :
        public TClientBase,
        public CameraDeviceBase::NotificationListener { ...... }

3. Camera硬件抽象层

frameworks\av\camera\Camera.cpp

// take a picture
status_t Camera::takePicture(int msgType)
{
    ALOGV("takePicture: 0x%x", msgType);
    sp <::android::hardware::ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->takePicture(msgType);
}

frameworks\av\services\camera\libcameraservice\api1\CameraClient

// take a picture - image is returned in callback
status_t CameraClient::takePicture(int msgType) {
    ......
    return mHardware->takePicture();
}

sp<CameraHardwareInterface>     mHardware;       // cleared after disconnect()

在makeclient的时候也进行了initialize

status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
    //mHidlDevice将代表硬件Binder远程引用
    status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
    ......
    return ret;
}
//在头文件中存在申明 ICameraDevice 类型
sp<hardware::camera::device::V1_0::ICameraDevice> mHidlDevice;

hardware\interfaces\camera\device\1.0\default\CameraDevice_1_0.h
新Treble架构下的HAL顶层调用接口

struct CameraDevice : public ICameraDevice { ...... }

frameworks\av\services\camera\libcameraservice\api1\Camera2Client.cpp
我们来看看Camera2Client

status_t Camera2Client::initialize(sp<CameraProviderManager> manager) {
    return initializeImpl(manager);
}

初始化StreamingProcessor

template<typename TProviderPtr>
status_t Camera2Client::initializeImpl(TProviderPtr providerPtr)
{
    res = Camera2ClientBase::initialize(providerPtr);
    ......
    mStreamingProcessor = new StreamingProcessor(this);
    ......
    return OK;
}

frameworks\av\services\camera\libcameraservice\api1\client2\StreamingProcessor.cpp
mDevice被初始化

StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
        mClient(client),
        mDevice(client->getCameraDevice()), //初始化备
        mId(client->getCameraId()),
        mActiveRequest(NONE),
        mPaused(false),
        mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
        mPreviewStreamId(NO_STREAM),
        mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
        mRecordingStreamId(NO_STREAM){ ...... }

从父类 Camera2ClientBase 中调用

template <typename TClientBase>
const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
    return mDevice;
}

那么 mDevice 哪里来的呢

template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase( ...... )
{
    mInitialClientPid = clientPid;
    mDevice = new Camera3Device(cameraId); //新建HAL3 Device
    LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}

至此,Camera子系统整体框架分析到此结束,新老框架的交汇点是在CameraService的makeclient函数,在这里会根据传入的参数决定创建具体的硬件抽象层,可以说实现得十分精巧。关于Camera系统还有很多东西,不可能一蹴而就。在以后分析其他子系统或情景时再回过头来穿插,会理解得更深一点。

猜你喜欢

转载自blog.csdn.net/u013928208/article/details/82181786