Android8.0 Camera系統架構(二)

上一篇咱們從最新的Camera架構來分析Camera子系統,今天咱們將從全局的視角從舊版本到新版本架構總體通覽一遍,從Framework層的API(1和2)到硬件抽象層的HAL(1和3)。廢話少說一塊兒來看一下總體架構:java

從總體架構圖來看,上層API相互獨立,中間Camera庫耦合度低,HAL層構建合理;APIv1對應HAL1和HAL2。先後兩套API耦合度低,APIv2幾乎是重寫了整個結構。廢話少說咱們直接上代碼。android

1. Camera和JNICameraContext
frameworks\base\core\java\android\hardware\Camera.java
frameworks\base\core\jni\android_hardware_Camera.cppapi

建立相機時,執行相機初始化架構

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層ide

 private native final void native_takePicture(int msgType);
1
調用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實例ui

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.hthis

 typedef CameraBase<TCam>         CameraBaseT; // what ? 哪來的 TCam
1
TCam來自於模板類聲明.net

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 { ...... }
1
Client繼承了BnCamera,如此一來如架構圖所述,Camera和CameraClient經過ICameraClient和ICamera跨進程通信

 class Client : public hardware::BnCamera, public BasicClient { ...... }
1
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 { ...... }
1
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系統還有不少東西,不可能一蹴而就。在之後分析其餘子系統或情景時再回過頭來穿插,會理解得更深一點。 ———————————————— 版權聲明:本文爲CSDN博主「SherlockCharlie」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/u013928208/article/details/82181786

相關文章
相關標籤/搜索