camera open流程

camera open流程,第1张

1、Java 层
  • frameworks/base/core/java/android/hardware/camera2/CameraManager.java
  • frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
/* CameraManager.java */
public void openCamera(@NonNull String cameraId,
        @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
        throws CameraAccessException {
    openCameraForUid(cameraId, callback, handler, USE_CALLING_UID);
}
/*最初的入口就是CameraManager的openCamera方法,通过代码可以看到,仅仅调用openCameraForUid方法,最终主要调用openCameraDeviceUserAsync方法。 */
/* CameraManager.java */
public void openCameraForUid(@NonNull String cameraId,
        @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler,
        int clientUid)
        throws CameraAccessException {

    if (handler == null) {
         /* Looper:消息的遍历者,从MessageQueue中循环取出Message进行处理,一个线程最多只有一个。Looper作为Handler消息机制的“动力引擎”,不断从MessageQueue中获取消息,然后交给Handler去处理。Looper的使用前需要先初始化当前线程的Looper对象,再调用loop方法来启动它。同时Handler也是实现切换的核心,因为不同的Looper运行在不同的线程,他所调用的dispatchMessage方法则运行在不同的线程,所以Message的处理就被切换到Looper所在的线程了。当looper不再使用时,可调用不同的退出方法来退出他,注意Looper一旦退出,线程则会直接结束。*/
        if (Looper.myLooper() != null) {
            handler = new Handler();
        } else {
            throw new IllegalArgumentException(
                    "Handler argument is null, but no looper exists in the calling thread");
        }
    }
    openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);
}

/* CameraManager.java */
private CameraDevice openCameraDeviceUserAsync(String cameraId,
        CameraDevice.StateCallback callback, Handler handler, final int uid)
        throws CameraAccessException {
    /* 获得 camera 的信息,这个函数会使用 CameraService binder 服务来得到信息 */
    CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
    CameraDevice device = null;

    synchronized (mLock) {

        ICameraDeviceUser cameraUser = null;
        /* 创建 CameraDeviceImpl 对象,它继承自 CameraDevice */
        android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                new android.hardware.camera2.impl.CameraDeviceImpl(
                    cameraId,
                    callback,
                    handler,
                    characteristics,
                    mContext.getApplicationInfo().targetSdkVersion);
        /*
         * 获得回调, 这个回调很重要
         * 处理好的图像帧会通过这个回调传回上层,这是提供给远端连接到 CameraDeviceImpl 的接口。
         */
        ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();

        try {
			/*HAL3 中走的是这一部分逻辑,主要是从 CameraManagerGlobal 中获取 CameraService 的本地接口,通过它远端调用 connectDevice 方法连接到相机设备。注意返回的 cameraUser 实际上指向的是远端 CameraDeviceClient 的本地接口。*/
			ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
            if (cameraService == null) {
                throw new ServiceSpecificException(
                    ICameraService.ERROR_DISCONNECTED,
                    "Camera service is currently unavailable");
            }
            cameraUser = cameraService.connectDevice(callbacks, cameraId,
                mContext.getOpPackageName(),  mContext.getAttributionTag(), uid,
                oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion);
        } catch (ServiceSpecificException e) {
            ......
        } catch (RemoteException e) {
            ......
        }

        /* 将 CameraDeviceClient 设置到 CameraDeviceImpl 中进行管理。*/
        deviceImpl.setRemoteDevice(cameraUser);
        device = deviceImpl;
    }

    return device;
}

/* CameraDeviceImpl.java */
/*
	CameraDevice具体实现。使用 CameraManager#open 实例化。
	1. 获取 TAG
	2. 获取 partialCount
*/
public class CameraDeviceImpl extends CameraDevice
        implements IBinder.DeathRecipient {
	...
    public CameraDeviceImpl(String cameraId, StateCallback callback, Executor executor,
                        CameraCharacteristics characteristics, int appTargetSdkVersion) {
        if (cameraId == null || callback == null || executor == null || characteristics == null) {
            throw new IllegalArgumentException("Null argument given");
        }
        mCameraId = cameraId;
        mDeviceCallback = callback;
        mDeviceExecutor = executor;
        mCharacteristics = characteristics;
        mAppTargetSdkVersion = appTargetSdkVersion;

        final int MAX_TAG_LEN = 23;
        String tag = String.format("CameraDevice-JV-%s", mCameraId);
        if (tag.length() > MAX_TAG_LEN) {
            tag = tag.substring(0, MAX_TAG_LEN);
        }
        TAG = tag;

        Integer partialCount = mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT);
        /* REQUEST_PARTIAL_RESULT_COUNT 定义结果将由多少个子组件组成。为了消除流水线延迟,可以在部分结果可用时立即将其从相机设备传递到应用程序层。*/
        if (partialCount == null) {
            /* 1 means partial result is not supported.默认值为 1。表示不支持部分结果, 并且相机设备将仅生成最终的 TotalCaptureResult。一个典型的用例可能是:请求自动对焦(AF)锁定后, 新的 AF 状态在整个管道中可能有 50%可用 */
            mTotalPartialCount = 1;
        } else {
        	/* 相机设备可以通过部分结果立即将状态分发给应用程序, 其余的元数据则通过以后的部分结果进行分发 */
            mTotalPartialCount = partialCount;
        }
        mIsPrivilegedApp = checkPrivilegedAppList();
    }
    ...
}

/* CameraDeviceImpl.java */
public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
    synchronized(mInterfaceLock) {
        /* remoteDevice 由 cameraService.connectDevice() 得到。通过 ICameraDeviceUserWrapper 给远端设备实例加上一层封装。 */
        mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
		/* 使用Binder机制的一些基本设置 */
        IBinder remoteDeviceBinder = remoteDevice.asBinder();
        if (remoteDeviceBinder != null) {
            try {
                /* 连接死亡通知,当服务时挂掉会通知 */
                remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
            } catch (RemoteException e) {
                ......
            }
        }
        /* 需要注意这个时间节点,此处触发 onOpened 与 onUnconfigured 这两个回调,每个回调都是通过 mDeviceHandler 启用一个新线程来调用的。 */
        mDeviceHandler.post(mCallOnOpened);
        mDeviceHandler.post(mCallOnUnconfigured);
    }
}

/* CameraDeviceImpl.java */
private final Runnable mCallOnOpened = new Runnable() {
    public void run() {
        StateCallbackKK sessionCallback = null;
        synchronized(mInterfaceLock) {

            sessionCallback = mSessionStateCallback;
        }
        if (sessionCallback != null) {
            sessionCallback.onOpened(CameraDeviceImpl.this);
        }
        /* mDeviceCallback 就是 APP 调用openCamera()时传入的第二个参数
         * 所以这个回调是回调回应用程序
         * 之后应用程序使用 CameraDeviceImpl  *** 作相机
         */
        mDeviceCallback.onOpened(CameraDeviceImpl.this);
    }
};

/* CameraDeviceImpl.java */
private final Runnable mCallOnUnconfigured = new Runnable() {
    @Override
    public void run() {
        StateCallbackKK sessionCallback = null;
        synchronized(mInterfaceLock) {
            if (mRemoteDevice == null) return; // Camera already closed

            sessionCallback = mSessionStateCallback;
        }
        if (sessionCallback != null) {
            sessionCallback.onUnconfigured(CameraDeviceImpl.this);
        }
    }
};

2、C/C++ 层
  • frameworks/av/services/camera/libcameraservice/CameraService.cpp
  • frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
  • frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
    上面分析得知,Java 层中会通过 binder 跨进程调用 CameraService::connectDevice()
/* CameraService.cpp */
Status CameraService::connectDevice(
        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
        const String16& cameraId,
        const String16& clientPackageName,
        int clientUid,
        /*out*/
        sp<hardware::camera2::ICameraDeviceUser>* device) {

    Status ret = Status::ok();
    String8 id = String8(cameraId);
    sp<CameraDeviceClient> client = nullptr;
    /* 此处调用的 connectHelper 方法才真正实现了连接逻辑(HAL1 时最终也调用到这个方法)。需要注意的是,设定的模板类型是 ICameraDeviceCallbacks 以及 CameraDeviceClient。 */
    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
            clientUid, USE_CALLING_PID, API_2,
            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
            /*out*/client);
    
    /* 注意 client 指向的类型是 CameraDeviceClient,其实例则是最终的返回结果。*/
    *device = client;
    return ret;
}

/*
 * CameraService.cpp
 * CALLBACK = hardware::camera2::ICameraDeviceCallbacks
 * CLIENT = CameraDeviceClient
 */
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) {
    binder::Status ret = binder::Status::ok();

    String8 clientName8(clientPackageName);

    int originalClientPid = 0;

    /* CLIENT = CameraDeviceClient */
    sp<CLIENT> client = nullptr;
    {
        mFlashlight->prepareDeviceOpen(cameraId);

        int facing = -1;
        int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);

        /* 调用 makeClient 生成 CameraDeviceClient 实例,makeClient() 将会根据API版本以及HAL版本选择生成具体的 Client 实例。*/
        sp<BasicClient> tmp = nullptr;
        if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
                clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        /* 转换 CLIENT = CameraDeviceClient */
        client = static_cast<CLIENT*>(tmp.get());
        /* client 进行初始化工作,注意这里的参数,mCameraProviderManager 是 CameraService 运行起来时,第一次强指针引用从而调用 onFirstRef()  			函数创建的 CameraProviderManager 实例对象,它保存了 CameraProvider 信息。*/
        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                __FUNCTION__);
        
        err = client->initialize(mCameraProviderManager);

    device = client;
    return ret;
}

/* CameraService.cpp */
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) {
            ......
            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
                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());
                /* API2 HAL3 将会通过 CameraDeviceClient() 创建 client,这一 client 最终返回到 CameraDeviceImpl 实例,
                被保存在 mRemoteDevice*/
                *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
                        facing, clientPid, clientUid, servicePid);
            }
            break;
          default:

        }
    } else {
        ......
    }
    return Status::ok();
}
/* 至此,打开相机流程中,从 App 到 CameraService 的调用逻辑基本上就算走完了。*/
    
    
/* CameraDeviceClient.cpp */
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
        const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
        const String16& clientPackageName,
        const std::optional<String16>& clientFeatureId,
        const String8& cameraId,
        int cameraFacing,
        int clientPid,
        uid_t clientUid,
        int servicePid) :
    /* 通过构造函数初始化Camera2ClientBase,在它的构造函数中,将会创建一个Camera3Device 实例对象 */
    Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
                cameraId, /*API1 camera ID*/ -1, cameraFacing, sensorOrientation,
                clientPid, clientUid, servicePid, overrideForPerfClass),
    mInputStream(),
    mStreamingRequestId(REQUEST_ID_NONE),
    mRequestIdCounter(0),
    mOverrideForPerfClass(overrideForPerfClass) {

    ATRACE_CALL();
    ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}


/* Camera2ClientBase.cpp */
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)
{
    ALOGI("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.");
}

/* CameraDeviceClient.cpp */
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

/* TProviderPtr = CameraProviderManager */
template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {
    ATRACE_CALL();
    status_t res;

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

    String8 threadName;
    /* 创建 FrameProcessorBase 实例对象,它将负责帧处理 */
    mFrameProcessor = new FrameProcessorBase(mDevice);
    threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
    /* 创建线程进行获取图像数据 */
    mFrameProcessor->run(threadName.string());

    /* 将 CameraDeviceClient 注册登记到 FrameProcessorBase 的 mRangeListeners,当帧处理完成时,将会通过它来回调通知APP */
    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
                                      /*listener*/this,
                                      /*sendPartials*/true);

    return OK;
}

template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
        const String8& monitorTags) {

    // Verify ops permissions
    /* 将调用到 CameraService::BasicClient::startCameraOps() 函数 */
    res = TClientBase::startCameraOps();
    
    /* 将调用 Camera3Device::initialize() 函数 */
    res = mDevice->initialize(providerPtr, monitorTags);

    return OK;
}
 
/* CameraService.cpp */
status_t CameraService::BasicClient::startCameraOps() {
    
    /* 这里,将会通过Binder代理,将设备状态更新到远端,这个时候,CameraProvider 管理的device 状态将更新,设备进入 OPEN 状态 */
    sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
            mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);

    return OK;
}

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


    sp<ICameraDeviceSession> session;
    ATRACE_BEGIN("CameraHal::openSession");
    /* 从 CameraProviderManager 的 mProviders 查找对应 id 的 mDevices,而后调用相对应的 deviceInfo3->mInterface->open(),其中,mInterface是	   在CameraProvider adddevice 时,通过DeviceInfo3的构造函数传递进来的, mInterface 最终为
     android::hardware::camera::device::V3_4::implementation::CameraDevice */
    status_t res = manager->openSession(mId.string(), this,
            /*out*/ &session);
    ATRACE_END();

    res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
    
    /* 获取请求队列 */
    std::shared_ptr<RequestMetadataQueue> queue;
    auto requestQueueRet = session->getCaptureRequestMetadataQueue(
        [&queue](const auto& descriptor) {
            queue = std::make_shared<RequestMetadataQueue>(descriptor);
            if (!queue->isValid() || queue->availableToWrite() <= 0) {
                ALOGE("HAL returns empty request metadata fmq, not use it");
                queue = nullptr;
                // don't use the queue onwards.
            }
        });
    /* 获取请求结果返回队列 */
    std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
    auto resultQueueRet = session->getCaptureResultMetadataQueue(
        [&resQueue](const auto& descriptor) {
            resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
            if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
                ALOGE("HAL returns empty result metadata fmq, not use it");
                resQueue = nullptr;
                // Don't use the resQueue onwards.
            }
        });

    /* 运行相应的队列线程 */
    return initializeCommonLocked();
}

status_t Camera3Device::initializeCommonLocked() {
    /** Start up status tracker thread */
    mStatusTracker = new StatusTracker(this);
    status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());

	/** Register in-flight map to the status tracker */
    mInFlightStatusId = mStatusTracker->addComponent();
    
    /** Start up request queue thread */
    mRequestThread = new RequestThread(this, mStatusTracker, mInterface, sessionParamKeys);
    res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
    
    mPreparerThread = new PreparerThread();
    ...
}

/* CameraProviderManager.cpp */
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);
    
    /* 根据CameraDevice的版本,从所有Provider中,找到对应的DeviceInfo */
    auto deviceInfo = findDeviceInfoLocked(id,
            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});

    auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
    /* 根据刚刚deviceInfo中对应的provider的信息,获取到对应CameraProvider服务 */
    const sp<provider::V2_4::ICameraProvider> provider =
            deviceInfo->mParentProvider->startProviderInterface();
    if (provider == nullptr) {
        return DEAD_OBJECT;
    }
    saveRef(DeviceMode::CAMERA, id, provider);

    Status status;
    hardware::Return<void> ret;
    /* 通过CameraProvider的getCameraDeviceInterface_V3_x()实例化一个CameraDevice。这一步是通过HIDL调用到了Hal层 */
    auto interface = deviceInfo3->startDeviceInterface<
            CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
    if (interface == nullptr) {
        return DEAD_OBJECT;
    }
    /* 这个interface就是前面startDeviceInterface()得到的CameraDevice,这里是要通过CameraDevicce::open()创建一个有效的CameraDeviceSession。这一步也是通过HIDL调用到了HAL层 */
    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
                status = s;
                if (status == Status::OK) {
                    *session = cameraSession;
                }
            });
    return mapToStatusT(status);
}

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

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

        ATRACE_BEGIN("camera3->open");
        /* 调用 HAL 层的 open() 函数 */
        res = mModule->open(mCameraId.c_str(),
                reinterpret_cast<hw_device_t**>(&device));
        ATRACE_END();

        struct camera_info info;
        res = mModule->getCameraInfo(mCameraIdInt, &info);
        
        /* 创建session实例对象 */
        session = createSession(
                device, info.static_camera_characteristics, callback);

        mSession = session;

        mLock.unlock();
    }
    _hidl_cb(status, session->getInterface());
    return Void();
}

sp<CameraDeviceSession> CameraDevice::createSession(camera3_device_t* device,
        const camera_metadata_t* deviceInfo,
        const sp<ICameraDeviceCallback>& callback) {
    return new CameraDeviceSession(device, deviceInfo, callback);
}
ps:个人在网上找资料借鉴参考,仅供个人学习。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/924585.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存