Android Camera1 open流程分析

 

由于camera 1网上大家分析的文章比较多,这里就截取各处细节在做继续深究.

前段部分流程可以看:Android Camera 流程学习记录(二)—— Camera Open 调用流程,这里分析CameraService.cpp以下部分.

1.C/C++ 层:

1.1 CameraService.cp

  • 位置:frameworks/av/services/camera/libcameraservice/CameraService.cpp
  • connect(): 
    • 注意这里真正实现逻辑是在 connectHelper() 函数中。
    • 获得一个客户端实例并且通过 *device 返回。

上面分析得知,Java 层中会通过 binder 跨进程调用 CameraService::connect(), camera2 会调用到CameraService::connectDevice(),注意里面connectHelper的参数API_1, camera2会对应API_2,

​
Status CameraService::connect(
        const sp<ICameraClient>& cameraClient,
        int cameraId,
        const String16& clientPackageName,
        int clientUid,
        int clientPid,
        /*out*/
        sp<ICamera>* device) {

    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8::format("%d", cameraId);
    sp<Client> client = nullptr;
    ret = connectHelper<ICameraClient,Client>(cameraClient, id,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
            /*out*/client);

    if(!ret.isOk()) {
        logRejected(id, getCallingPid(), String8(clientPackageName),
                ret.toString8());
        return ret;
    }

    *device = client;
    return ret;
}

​

CameraService.h

位置:frameworks/av/services/camera/libcameraservice/CameraService.h
注意这个文件中定义了 CameraService::Client 类,这个类通过它的子类 CameraClient 真正实现了 ICamera 的接口。

connectHelper(): 

  • HAL1 /HAL2 最终也都调用到这个方法
  • 这个函数实现比较长,截取其中的一段。
  • 首先,如果客户端实例已经存在于 MediaRecorder ,则直接将其取出返回。
  • 若不存在,则先获取 deviceVersion,然后再调用 makeClient() 函数创建一个客户端。
  • 创建客户端后,需要调用其 initialize() 函数进行初始化,注意其传入的参数是 mModule,这个参数是连接 Libraries 与 HAL 的关键参数。
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
        apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
        /*out*/sp<CLIENT>& device) {
        ...
        sp<BasicClient> tmp = nullptr;
        ALOGE("%s halVersion = %d , deviceVersion = %d ", __FUNCTION__, halVersion, deviceVersion);
        /* makeClient() 很重要, 后面分析 */
        if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
                clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        client = static_cast<CLIENT*>(tmp.get());

        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                __FUNCTION__);

        err = client->initialize(mCameraProviderManager);
       
        ...
        device = client;
    return ret;
}

makeClent:

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) {
        // Default path: HAL version is unspecified by caller, create CameraClient
        // based on device version reported by the HAL.
        switch(deviceVersion) {
          case CAMERA_DEVICE_API_VERSION_1_0:
            if (effectiveApiLevel == API_1) {  // Camera1 API route
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
                        facing, clientPid, clientUid, getpid(), legacyMode);
            } else { // Camera2 API route
                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:
          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) { // Camera1 API route
            ALOGE("%s luozh test --->",__FUNCTION__);
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),
                        facing, clientPid, clientUid, servicePid, legacyMode);
            } else { // Camera2 API route
                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
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                    "Camera device \"%s\" has unknown HAL version %d",
                    cameraId.string(), deviceVersion);
        }
    } else {
    ...
}

makeClient 主要是根据 API 版本以及 HAL 版本来选择生成具体的 Client 实例。

目前项目走的是hal3 + camera1,即走的Camera2Client函数.

此时client对象实例被返回去,继续看connectHelper函数里面:

err = client->initialize(mCameraProviderManager);

//此client就是我们返回去的Camera2Client实例,实际主要是在initializeImpl里面实现。

1.1.2  Camera2Client.cpp

位置:frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp

  • 从文件位置也可以看得出,我们现在走的都是 Camera API 1 的流程。
  • Camera2Client 继承了 CameraService::Client,头文件里面可以看到
  • Camera2Client::initialize(): 
  • initializeImpl里面调用到了Camera2ClientBase::initialize
//Camera2Client.h
//继承模板类Camera2ClientBase,用CameraService::Client实例化
class Camera2Client :
        public Camera2ClientBase<CameraService::Client>
{
public:
...
}

//Camera2Client.cpp
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
        const sp<hardware::ICameraClient>& cameraClient,
        const String16& clientPackageName,
        int cameraId,
        int cameraFacing,
        int clientPid,
        uid_t clientUid,
        int servicePid,
        bool legacyMode):
        Camera2ClientBase(cameraService, cameraClient, clientPackageName,
                String8::format("%d", cameraId), cameraFacing,
                clientPid, clientUid, servicePid),
        mParameters(cameraId, cameraFacing)
{
    ATRACE_CALL();

    SharedParameters::Lock l(mParameters);
    l.mParameters.state = Parameters::DISCONNECTED;

    mLegacyMode = legacyMode;
}
...

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

template<typename TProviderPtr>
status_t Camera2Client::initializeImpl(TProviderPtr providerPtr)
{
    ATRACE_CALL();
    ALOGE("%s: luozh Initializing client for camera %d", __FUNCTION__, mCameraId);
    status_t res;

    res = Camera2ClientBase::initialize(providerPtr);
    if (res != OK) {
        return res;
    }

    {
        SharedParameters::Lock l(mParameters);

        res = l.mParameters.initialize(&(mDevice->info()), mDeviceVersion);
        if (res != OK) {
            ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
            return NO_INIT;
        }

        l.mParameters.isDeviceZslSupported = isZslEnabledInStillTemplate();
    }

    String8 threadName;

    //preview和recorder 完成各个模块的创建,后续取数据有关系
    mStreamingProcessor = new StreamingProcessor(this);
    threadName = String8::format("C2-%d-StreamProc",
            mCameraId);

    mFrameProcessor = new FrameProcessor(mDevice, this);
    threadName = String8::format("C2-%d-FrameProc",
            mCameraId);
    mFrameProcessor->run(threadName.string());
    ...
}

1.1.3  Camera2ClientBase.cpp

位置:frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp

  • 构造函数里面创建了一个 Camera3Device
  • Camera2Client::initialize()-->Camera2ClientBase::initialize()
  • 初始化 Camera3Device 的实例,注意此处传入了 CameraProviderManager
  • 最后在 Camera3Device 实例中设置 Notify 回调
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
        const sp<CameraService>& cameraService,
        const sp<TCamCallbacks>& remoteCallback,
        const String16& clientPackageName,
        const String8& cameraId,
        int cameraFacing,
        int clientPid,
        uid_t clientUid,
        int servicePid):
        TClientBase(cameraService, remoteCallback, clientPackageName,
                cameraId, cameraFacing, clientPid, clientUid, servicePid),
        mSharedCameraCallbacks(remoteCallback),
        mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
        mDeviceActive(false)
{
    ALOGE("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
            String8(clientPackageName).string(), clientPid, clientUid);

    mInitialClientPid = clientPid;
    mDevice = new Camera3Device(cameraId);
    LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}

...
template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager) {
    return initializeImpl(manager);
}

template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr) {
    ATRACE_CALL();
    ALOGE("%s: luozh Initializing client for camera %s", __FUNCTION__,
          TClientBase::mCameraIdStr.string());
    status_t res;

    // Verify ops permissions
    res = TClientBase::startCameraOps();
    if (res != OK) {
        return res;
    }

    if (mDevice == NULL) {
        ALOGE("%s: Camera %s: No device connected",
                __FUNCTION__, TClientBase::mCameraIdStr.string());
        return NO_INIT;
    }

    res = mDevice->initialize(providerPtr);
    if (res != OK) {
        ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
        return res;
    }

    wp<CameraDeviceBase::NotificationListener> weakThis(this);
    res = mDevice->setNotifyCallback(weakThis);

    return OK;
}

1.1.4 Camera3Device.cpp

位置:frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp

观察构造函数,注意第 18、19 行设定了两个回调接口。

Camera3Device::Camera3Device(const String8 &id):
        mId(id),
        mOperatingMode(NO_MODE),
        mIsConstrainedHighSpeedConfiguration(false),
        mStatus(STATUS_UNINITIALIZED),
        mStatusWaiters(0),
        mUsePartialResult(false),
        mNumPartialResults(1),
        mTimestampOffset(0),
        mNextResultFrameNumber(0),
        mNextReprocessResultFrameNumber(0),
        mNextShutterFrameNumber(0),
        mNextReprocessShutterFrameNumber(0),
        mListener(NULL),
        mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID)
{
    ATRACE_CALL();
    camera3_callback_ops::notify = &sNotify;
    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
    ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
}

其初始化函数篇幅较长,这里省略掉了关于 RequestMetadataQueue 的相关操作。我们需要关注的是,在初始化时,调用了 CameraProviderManager 的 openSession 方法(第 13~21 行),开启了远端的 Session

status_t Camera3Device::initialize(sp<CameraProviderManager> manager) {
    ATRACE_CALL();
    Mutex::Autolock il(mInterfaceLock);
    Mutex::Autolock l(mLock);

    ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
    if (mStatus != STATUS_UNINITIALIZED) {
        CLOGE("Already initialized!");
        return INVALID_OPERATION;
    }
    if (manager == nullptr) return INVALID_OPERATION;

    sp<ICameraDeviceSession> session;
    ATRACE_BEGIN("CameraHal::openSession");
    status_t res = manager->openSession(mId.string(), this,
            /*out*/ &session);
    ATRACE_END();
    if (res != OK) {
        SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
        return res;
    }

    /* Do something in */
    ......
    /* Do something out */

    return initializeCommonLocked();
}

CameraProviderManager.cpp

文件位置:frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp

来看看 openSession 是如何实现的:

第 8~12 行,首先调用 findDeviceInfoLocked,获取 HAL3 相关的 DeviceInfo3,这个东西在服务启动与初始化的时候就已经创建出来,并保存下来了。

NOTE:CameraProviderManager 开机cameraservice初始化的时候已经初始化到,详细可参看在Android 8.0 Camera架构源码分析 - CameraProvider And CameraService启动
第 16~22 行,注意此处,通过远端调用 CameraDevice 的 open 方法,创建 CameraDeviceSession 实例并将其本地调用接口通过入参 session 返回。 (DeviceInfo3 这个类的 mInterface 成员类型是 ICameraDevice,通过它可以调用远端 CameraDevice 中的方法。)

status_t CameraProviderManager::openSession(const std::string &id,
        const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
        /*out*/
        sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {

    std::lock_guard<std::mutex> lock(mInterfaceMutex);

    auto deviceInfo = findDeviceInfoLocked(id,
            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
    if (deviceInfo == nullptr) return NAME_NOT_FOUND;

    auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);

    Status status;
    hardware::Return<void> ret;

     /* mInterface 它实际上是 CameraDevice 对象
     *  所以就是调用 CameraDevice::open()
     */

    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
                status = s;
                if (status == Status::OK) {
                    *session = cameraSession;
                }
            });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
                __FUNCTION__, id.c_str(), ret.description().c_str());
        return DEAD_OBJECT;
    }
    return mapToStatusT(status);
}

CameraDevice.cpp

位置:hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp

CameraDevice在开机CameraProvider启动的时候已经启动,流程参考CameraProvider启动流程(hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp里面有队CameraDevice的操作)

Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb)  {
    Status status = initStatus();
    sp<CameraDeviceSession> session = nullptr;

    if (callback == nullptr) {
        ALOGE("%s: cannot open camera %s. callback is null!",
                __FUNCTION__, mCameraId.c_str());
        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
        return Void();
    }

    if (status != Status::OK) {
        /* Do something in */
        ......
        /* Do something out */
    } else {
        mLock.lock();

        /* Do something in */
        ......
        /* Do something out */

        /** Open HAL device */
        status_t res;
        camera3_device_t *device;

        ATRACE_BEGIN("camera3->open");
        //具体的hal层open函数,此处的open会调用到CameraModule.cpp里面的open函数
        res = mModule->open(mCameraId.c_str(),
                reinterpret_cast<hw_device_t**>(&device));
        ATRACE_END();

        /* Do something in */
        ......
        /* Do something out */

        session = createSession(
                device, info.static_camera_characteristics, callback);

        /* Do something in */
        ......
        /* Do something out */

        mSession = session;

        IF_ALOGV() {
            session->getInterface()->interfaceChain([](
                ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
                    ALOGV("Session interface chain:");
                    for (auto iface : interfaceChain) {
                        ALOGV("  %s", iface.c_str());
                    }
                });
        }
        mLock.unlock();
    }
    _hidl_cb(status, session->getInterface());
    return Void();
}

res = mModule->open(mCameraId.c_str(),
            reinterpret_cast<hw_device_t**>(&device));

此处的open调用的是之前开机已经启动的CameraModule.cpp里面的open函数,之前我们已经分析,CameraModule.cpp链接的是具体的hal层

int CameraModule::open(const char* id, struct hw_device_t** device) {
    int res;
    ATRACE_BEGIN("camera_module->open");
    res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
    ATRACE_END();
    return res;
}
static hw_module_t camera_common = {
    .tag                    = HARDWARE_MODULE_TAG,
    .module_api_version     = CAMERA_MODULE_API_VERSION_2_4,
    .hal_api_version        = HARDWARE_HAL_API_VERSION,
    .id                     = CAMERA_HARDWARE_MODULE_ID,
    .name                   = "Camera Module",
    .author                 = "XXTronix",
    .methods                = &camera::Camera2Factory::mModuleMethods,
    .dso                    = NULL,
    .reserved               = {0}
};

mModuleMethods:

struct hw_module_methods_t Camera2Factory::mModuleMethods = {
    .open = Camera2Factory::camera_device_open,
};

creatSession 中的实现就非常简单了,直接创建了一个 CameraDeviceSession。当然在其构造函数中会调用内部的初始化函数,然后会进入 HAL 接口层 QCamera3HWI 的初始化流程,这里就先不分析了。 
至此,从 CameraService 到 HAL Service 这一部分的打开相机流程就基本走通了。
 

 

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值