文章目录

  • 1 camera open总结
  • 2 Camera Open 代码流程分析
    • 2.1 Java 层 Camera Class 使用介绍
    • 2.2 Frameworks 层 Camera.java 分析
      • 2.2.1 \[JNI] CameraService初始化 native\_setup( ) —> android\_hardware\_Camera\_native\_setup( )
      • 2.2.2 \[AIDL] interface ICameraService
      • 2.2.3 \[Native] CameraService.cpp
        • 2.2.3.1 \[CameraService] 创建 Camera 客户端 makeClient( )
        • 2.2.3.2 \[Camera2Client] Camera2Client初始化 client->initialize(mModule))
          • 2.2.3.2.1 \[Camera3Device] Camera device 初始化 mDevice->initialize(module)
          • 2.2.3.2.2 \[CameraProviderManager] manager->openSession
        • 2.2.3.3 \[CameraDevice] CameraDevice::open
        • 2.2.3.4 \[CameraModule] CameraModule::open
          • 2.2.3.4.1 \[hardware] camera\_module\_t
        • 2.2.3.5 \[Hardware] 打开设备 QCamera2Factory::cameraDeviceOpen()
          • 2.2.3.5.1 camera\_open((uint8\_t)mCameraId, \&mCameraHandle)
          • 2.2.3.5.2 Camera 操作节构体 cam\_obj->vtbl.ops
          • 2.2.3.5.3 \[Hardware] 初始化Framewroks层的Callback 函数 QCamera3HardwareInterface::initialize( )
      • 2.2.4 EventHandler( )
    • 2.3 内核层msm\_open
  • 3 OpenSession 流程分析
    • 3.1 mm-camera2框架
    • 3.2 media controller线程
      • 3.2.1 mm\_camera\_module\_open\_session
      • 3.2.2 mct\_shimlayer\_process\_module\_init
      • 3.2.3 mct\_shimlayer\_start\_session
      • 3.2.4 mct\_controller\_new
        • 3.2.4.1 mct\_pipeline\_new
        • 3.2.4.2 mct\_pipeline\_start\_session
        • 3.2.4.3 mct\_pipeline\_modules\_start
        • 3.2.4.4 mct\_pipeline\_start\_session\_thread
    • 3.3 else
    • 3.3 else

1 camera open总结

整个Camera Open 过程总结如下:

Java APP 层
调用 Frameworks 层 Camera.java 中的 open() 方法,
在open camera 后,才开始调用对应的 getParameters(),setParameters(), startPreview() 等 函数,这些后续分析

Frameworks 层 Camera.java 中的 open()
(1) 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄
(2) 根据传入的 camera id 进行初始化
(3) 注册 EventHandler 循环监听Camera 事件
(4) 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号

JNI 层 android_hardware_Camera_native_setup
(1) 调用 Camera::connect() 函数,connect 为 AIDL 方法,通过binder 调用到服务端CameraService.cpp中的 CameraService::connect() 方法中
(2) 获取 Camera Class,建立专门负责与java Camera对象通信的对象
(3) 如果没有设置屏幕显示方向,则默认为0,如果不为0,调用sendCommand 下发屏幕显示方向

C++ Native 层 CameraService.cpp 中
(1) CameraService.cpp 是camera 初始化中讲过了,在开机时会注册好对应的 cameraservice 服务
(2) 前面AIDL中,调用到 CameraService.cpp中的 CameraService::connect() 方法 在该方法中,
(3) 首先检查是否存在 client ,如果存在的话直接返回
(4) 关闭所有的 flashlight 对象
(5) 调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象
(6) 调用client->initialize对前面创建好的 Camera client 进行初始化
(7) 初始化前先对device 进行初始化 ,在Camera3Device->initialize()中打开对应的 Camera 节点/dev/videox,进行初始化,获取到 Camera 的操作方法
(8) 初始化 Camera 默认参数
(9) 接着对创建 Camera 运行时的六大线程,
处理preview和录像 stream的线程、处理3A和人脸识别的线程、拍照流程状态机线程、处理拍照 jpeg stream 线程、处理零延时zsl stream使用的线程、处理callback的线程

2 Camera Open 代码流程分析

2.1 Java 层 Camera Class 使用介绍

先看下谷歌官方对 Camera Class 的介绍:

The Camera class is used to set image capture settings, start/stop preview,
snap pictures, and retrieve frames for encoding for video.
This Class is a client for the Camera service, which manages the actual camera hardware.

2.2 Frameworks 层 Camera.java 分析

调用 Frameworks 层 Camera.java 中的 open() 方法,
在open camera 后,才开始调用对应的 getParameters(),setParameters(), startPreview() 等 函数,这些后续分析

Java 层中调用的 Camera Class 源码位于 frameworks/base/core/java/android/hardware/Camera.java,

整个过程,主要工作如下:

(1) 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄
(2) 根据传入的 camera id 进行初始化
(3) 注册 EventHandler 循环监听Camera 事件
(4) 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号 @ frameworks/base/core/java/android/hardware/Camera.java

public class Camera {private static final String TAG = "Camera";private CameraDataCallback mCameraDataCallback;private CameraMetaDataCallback mCameraMetaDataCallback;public static final int CAMERA_HAL_API_VERSION_1_0 = 0x100;public static class CameraInfo {public static final int CAMERA_FACING_BACK = 0;public static final int CAMERA_FACING_FRONT = 1;public static final int CAMERA_SUPPORT_MODE_ZSL = 2;public static final int CAMERA_SUPPORT_MODE_NONZSL = 3;public int facing;public int orientation;public boolean canDisableShutterSound;};// 1. 找开指定 id 的Camerapublic static Camera open(int cameraId) {return new Camera(cameraId);}// 2. 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄public static Camera open() {int numberOfCameras = getNumberOfCameras();CameraInfo cameraInfo = new CameraInfo();for (int i = 0; i < numberOfCameras; i++) {getCameraInfo(i, cameraInfo);if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {return new Camera(i);}}return null;}// 3. 调用 cameraInitNormal() 初始对应 id 的Camera/** used by Camera#open, Camera#open(int) */Camera(int cameraId) {int err = cameraInitNormal(cameraId);}private int cameraInitNormal(int cameraId) {return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);// -2}private int cameraInitVersion(int cameraId, int halVersion) {mShutterCallback = null;mRawImageCallback = null;mJpegCallback = null;mPreviewCallback = null;mPostviewCallback = null;mUsingPreviewAllocation = false;mZoomListener = null;/* ### QC ADD-ONS: START */mCameraDataCallback = null;mCameraMetaDataCallback = null;/* ### QC ADD-ONS: END */// 1. 注册 EventHandler 循环监听Camera 事件Looper looper;if ((looper = Looper.myLooper()) != null) {mEventHandler = new EventHandler(this, looper);} else if ((looper = Looper.getMainLooper()) != null) {mEventHandler = new EventHandler(this, looper);} else {mEventHandler = null;}// 2. 获取当前包名String packageName = ActivityThread.currentOpPackageName();// 3. 如果定义了 prop 属性 "camera.hal1.packagelist" , 则强制使用 HAL1//Force HAL1 if the package name falls in this bucketString packageList = SystemProperties.get("camera.hal1.packagelist", "");if (packageList.length() > 0) {TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');splitter.setString(packageList);for (String str : splitter) {if (packageName.equals(str)) {halVersion = CAMERA_HAL_API_VERSION_1_0;break;}}}// 4. 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);}

2.2.1 [JNI] CameraService初始化 native_setup( ) —> android_hardware_Camera_native_setup( )

java 中通过JNI 调用 native 方法,Camera JNI 代码位于 @ frameworks/base/core/jni/android_hardware_Camera.cpp

//cameraId = 0//halVersion = -2native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);static const JNINativeMethod camMethods[] = {{ "_getNumberOfCameras", "()I", (void *)android_hardware_Camera_getNumberOfCameras },{ "_getCameraInfo", "(ILandroid/hardware/Camera$CameraInfo;)V", (void*)android_hardware_Camera_getCameraInfo },{ "native_setup", "(Ljava/lang/Object;IILjava/lang/String;)I", (void*)android_hardware_Camera_native_setup },{ "native_release", "()V", (void*)android_hardware_Camera_release },{ "setPreviewSurface", "(Landroid/view/Surface;)V", (void *)android_hardware_Camera_setPreviewSurface },{ "setPreviewTexture", "(Landroid/graphics/SurfaceTexture;)V",(void *)android_hardware_Camera_setPreviewTexture },{ "setPreviewCallbackSurface", "(Landroid/view/Surface;)V", (void *)android_hardware_Camera_setPreviewCallbackSurface },{ "startPreview","()V", (void *)android_hardware_Camera_startPreview },{ "_stopPreview","()V",(void *)android_hardware_Camera_stopPreview },{ "previewEnabled", "()Z", (void *)android_hardware_Camera_previewEnabled },{ "setHasPreviewCallback","(ZZ)V",(void *)android_hardware_Camera_setHasPreviewCallback },{ "_addCallbackBuffer","([BI)V",(void *)android_hardware_Camera_addCallbackBuffer },{ "native_autoFocus", "()V",(void *)android_hardware_Camera_autoFocus },{ "native_cancelAutoFocus","()V",(void *)android_hardware_Camera_cancelAutoFocus },{ "native_takePicture","(I)V",(void *)android_hardware_Camera_takePicture },{ "native_setHistogramMode","(Z)V",(void *)android_hardware_Camera_setHistogramMode },{ "native_setMetadataCb","(Z)V", (void *)android_hardware_Camera_setMetadataCb },{ "native_sendHistogramData","()V",(void *)android_hardware_Camera_sendHistogramData }, { "native_setLongshot","(Z)V",(void *)android_hardware_Camera_setLongshot },{ "native_setParameters","(Ljava/lang/String;)V",(void *)android_hardware_Camera_setParameters },{ "native_getParameters", "()Ljava/lang/String;",(void *)android_hardware_Camera_getParameters },{ "reconnect", "()V",(void*)android_hardware_Camera_reconnect },{ "lock","()V", (void*)android_hardware_Camera_lock },{ "unlock","()V",(void*)android_hardware_Camera_unlock },{ "startSmoothZoom","(I)V",(void *)android_hardware_Camera_startSmoothZoom },{ "stopSmoothZoom","()V",(void *)android_hardware_Camera_stopSmoothZoom },{ "setDisplayOrientation","(I)V",(void *)android_hardware_Camera_setDisplayOrientation },{ "_enableShutterSound","(Z)Z",(void *)android_hardware_Camera_enableShutterSound },{ "_startFaceDetection","(I)V",(void *)android_hardware_Camera_startFaceDetection },{ "_stopFaceDetection","()V",(void *)android_hardware_Camera_stopFaceDetection},{ "enableFocusMoveCallback","(I)V",(void *)android_hardware_Camera_enableFocusMoveCallback},};

// connect to camera servicestatic jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName){// Convert jstring to String16const char16_t *rawClientName = reinterpret_cast<const char16_t*>(env->GetStringChars(clientPackageName, NULL));jsize rawClientNameLen = env->GetStringLength(clientPackageName);String16 clientName(rawClientName, rawClientNameLen);env->ReleaseStringChars(clientPackageName, reinterpret_cast<const jchar*>(rawClientName));sp<Camera> camera;if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {// -2// Default path: hal version is don't care, do normal camera connect.// 调用 Camera::connect() 函数,connect 为 AIDL 方法,// 通过binder 调用到服务端CameraService.cpp中的 CameraService::connect() 方法中camera = Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);======================> +// frameworks/av/camera/Camera.cpp+return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);+========> +// frameworks/av/camera/CameraBase.cpp+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();+TCamConnectService fnConnectService = TCamTraits::fnConnectService;+ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid, clientPid, /*out*/ &c->mCamera);+--------->+CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = +&::android::hardware::ICameraService::connect;++IInterface::asBinder(c->mCamera)->linkToDeath(c);+return c;+}+<========<======================} else {jint status = Camera::connectLegacy(cameraId, halVersion, clientName, Camera::USE_CALLING_UID, camera);if (status != NO_ERROR) {return status;}}// make sure camera hardware is aliveif (camera->getStatus() != NO_ERROR) {return NO_INIT;}// 获取 Camera Classjclass clazz = env->GetObjectClass(thiz);if (clazz == NULL) {// This should never happenjniThrowRuntimeException(env, "Can't find android/hardware/Camera");return INVALID_OPERATION;}// We use a weak reference so the Camera object can be garbage collected.// The reference is only used as a proxy for callbacks.sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);context->incStrong((void*)android_hardware_Camera_native_setup);camera->setListener(context);// 专门负责与java Camera对象通信的对象 // save context in opaque fieldenv->SetLongField(thiz, fields.context, (jlong)context.get());// Update default display orientation in case the sensor is reverse-landscapeCameraInfo cameraInfo;status_t rc = Camera::getCameraInfo(cameraId, &cameraInfo);int defaultOrientation = 0;switch (cameraInfo.orientation) {case 0: break;case 90:if (cameraInfo.facing == CAMERA_FACING_FRONT) {defaultOrientation = 180;}break;case 180:defaultOrientation = 180;break;case 270:if (cameraInfo.facing != CAMERA_FACING_FRONT) {defaultOrientation = 180;}break;default:ALOGE("Unexpected camera orientation %d!", cameraInfo.orientation);break;}// 如果没有设置屏幕显示方向,则默认为0,如果不为0,调用sendCommand 下发屏幕显示方向if (defaultOrientation != 0) {ALOGV("Setting default display orientation to %d", defaultOrientation);rc = camera->sendCommand(CAMERA_CMD_SET_DISPLAY_ORIENTATION,defaultOrientation, 0);}return NO_ERROR;}

2.2.2 [AIDL] interface ICameraService

在前面代码中, 经过如下一系列调用,最终走到了 AIDL 层。

native_setup() —> android_hardware_Camera_native_setup() —> CameraBaseT::connect —> sp CameraBase::connect —> ret = (cs.get()->*fnConnectService) —> ::android::hardware::ICameraService::connect()

fnConnectService 定义如下:

CameraTraits::TCamConnectService CameraTraits::fnConnectService = &::android::hardware::ICameraService::connect;

@frameworks/av/camera/aidl/android/hardware/ICameraService.aidl

/** * Binder interface for the native camera service running in mediaserver. * @hide */interface ICameraService{ /** Open a camera device through the old camera API */ICamera connect(ICameraClient client, int cameraId, String opPackageName, int clientUid, int clientPid);/** Open a camera device through the new camera API Only supported for device HAL versions >= 3.2 */ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,String opPackageName,int clientUid);}

AIDL 中,我们走的是老方法, ICamera connect().

AIDL——Android Interface Definition Language,是一种接口定义语言,用于生成可以在Android设备上两个进程间进行通信的代码。
Android Java Service Framework提供的大多数系统服务都是使用AIDL语言生成的。使用AIDL语言,可以自动生成服务接口、服务代理、服务Stub代码。

2.2.3 [Native] CameraService.cpp

通过 AIDL 的 Binder 通信,跳转到 CameraService.cpp 中。CameraService.cpp 是在开机时会注册好对应的 cameraservice 服务。
此时通过Binder通信,调用CameraService 服务中的 connect 方法: @frameworks/av/services/camera/libcameraservice/CameraService.cpp

Status CameraService::connect(const sp& cameraClient,int cameraId,const String16& clientPackageName,int clientUid,int clientPid,/*out*/sp* device) {String8 id = String8::format("%d", cameraId);sp client = nullptr;ret = connectHelper(cameraClient, id,CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,/*legacyMode*/ false, /*shimUpdateOnly*/ false,/*out*/client);*device = client;return ret;}

进入 connectHelper 函数看下:

1.检查 Client 的权限
2.如果已存在 client 则直接返回
3.在打开Camera 前,所有Flashlight 都应该被关闭
4.调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象
5.调用client->initialize对前面创建好的 Camera client 进行初始化

template<class CALLBACK, class CLIENT>binder::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;//这里可以打印 camera的包名 cameraId 以及camera API versionALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and ""Camera API version %d", clientPid, clientName8.string(), cameraId.string(),(halVersion == -1) " />"default" : std::to_string(halVersion).c_str(), static_cast<int>(effectiveApiLevel));sp<CLIENT> client = nullptr;{// 1. 检查 Client 的权限// Enforce client permissions and do basic sanity checksif(!(ret = validateConnectLocked(cameraId, clientName8,/*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {return ret;}sp<BasicClient> clientTmp = nullptr;std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp, /*out*/&partial));// 2. 如果已存在 client 则直接返回if (clientTmp.get() != nullptr) {// Handle special case for API1 MediaRecorder where the existing client is returneddevice = static_cast<CLIENT*>(clientTmp.get());return ret;}// 3. 在打开Camera 前,所有Flashlight 都应该被关闭// give flashlight a chance to close devices if necessary.mFlashlight->prepareDeviceOpen(cameraId);// TODO: Update getDeviceVersion + HAL interface to use strings for Camera IDsint id = cameraIdToInt(cameraId);int facing = -1;int deviceVersion = getDeviceVersion(id, /*out*/&facing);sp<BasicClient> tmp = nullptr;// 4.调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象if(!(ret = makeClient(this, cameraCb, clientPackageName, id, facing, clientPid,clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,/*out*/&tmp)).isOk()) {return ret;}client = static_cast<CLIENT*>(tmp.get());// Camera2ClientLOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",__FUNCTION__);// 5. 调用client->initialize对前面创建好的 Camera client 进行初始化if ((err = client->initialize(mModule)) != OK) {ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);// Errors could be from the HAL module open call or from AppOpsManagerswitch(err) {case BAD_VALUE:return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,"Illegal argument to HAL module for camera \"%s\"", cameraId.string());case -EBUSY:return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,"Camera \"%s\" is already open", cameraId.string());case -EUSERS:return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,"Too many cameras already open, cannot open camera \"%s\"",cameraId.string());case PERMISSION_DENIED:return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,"No permission to open camera \"%s\"", cameraId.string());case -EACCES:return STATUS_ERROR_FMT(ERROR_DISABLED,"Camera \"%s\" disabled by policy", cameraId.string());case -ENODEV:default:return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,"Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),strerror(-err), err);}}// Update shim paremeters for legacy clientsif (effectiveApiLevel == API_1) {// Assume we have always received a Client subclass for API1sp<Client> shimClient = reinterpret_cast<Client*>(client.get());String8 rawParams = shimClient->getParameters();CameraParameters params(rawParams);auto cameraState = getCameraState(cameraId);if (cameraState != nullptr) {cameraState->setShimParams(params);} else {ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",__FUNCTION__, cameraId.string());}}if (shimUpdateOnly) {// If only updating legacy shim parameters, immediately disconnect clientmServiceLock.unlock();client->disconnect();mServiceLock.lock();} else {// Otherwise, add client to active clients listfinishConnectLocked(client, partial);}} // lock is destroyed, allow further connect calls// Important: release the mutex here so the client can call back into the service from its// destructor (can be at the end of the call)device = client;return ret;}
2.2.3.1 [CameraService] 创建 Camera 客户端 makeClient( )

接着调用
makeClient(this, cameraCb, clientPackageName, id, facing, clientPid, clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel, /out/&tmp))
根据 deviceVersion选择Camera1 or Camera2 API route @ frameworks/av/services/camera/libcameraservice/CameraService.cpp

Status CameraService::makeClient(const sp<CameraService>& cameraService,const sp<IInterface>& cameraCb, const String16& packageName, int 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 routesp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());*client = new CameraClient(cameraService, tmp, packageName, cameraId, facing,clientPid, clientUid, getpid(), legacyMode);} else { // Camera2 API routeALOGW("Camera using old HAL version: %d", deviceVersion);return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,"Camera device \"%d\" HAL version %d does not support camera2 API",cameraId, 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 routesp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());*client = new Camera2Client(cameraService, tmp, packageName, cameraId, facing,clientPid, clientUid, servicePid, legacyMode);} else { // Camera2 API routesp<hardware::camera2::ICameraDeviceCallbacks> tmp =static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,facing, clientPid, clientUid, servicePid);}break;}} 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, 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 \"%d\" (HAL version %d) cannot be opened as HAL version %d",cameraId, deviceVersion, halVersion);}}return Status::ok();}

接着调用 *client = new Camera2Client(cameraService, tmp, packageName, cameraId, facing, clientPid, clientUid, servicePid, legacyMode);
client是通过 Camera2ClientBase() 进行创建的 @ frameworks/av/services/camera/libcameraservice/api1/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,cameraId, cameraFacing, clientPid, clientUid, servicePid),mParameters(cameraId, cameraFacing){ATRACE_CALL();SharedParameters::Lock l(mParameters);l.mParameters.state = Parameters::DISCONNECTED;mLegacyMode = legacyMode;}

创建Camera3Device 对象

// Interface used by CameraServicetemplate <typename TClientBase>Camera2ClientBase<TClientBase>::Camera2ClientBase(const sp<CameraService>& cameraService,const sp<TCamCallbacks>& remoteCallback,const String16& clientPackageName,int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid):TClientBase(cameraService, remoteCallback, clientPackageName,cameraId, cameraFacing, clientPid, clientUid, servicePid),mSharedCameraCallbacks(remoteCallback),mDeviceVersion(cameraService->getDeviceVersion(cameraId)),mDeviceActive(false){ALOGI("Camera %d: Opened. Client: %s (PID %d, UID %d)", cameraId, String8(clientPackageName).string(), clientPid, clientUid);mInitialClientPid = clientPid;mDevice = new Camera3Device(cameraId);LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");}

Camera3Device的有参构造 @ frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp

Camera3Device::Camera3Device(int id):mId(id),mIsConstrainedHighSpeedConfiguration(false),mHal3Device(NULL),mStatus(STATUS_UNINITIALIZED),mStatusWaiters(0),mUsePartialResult(false),mNumPartialResults(1),mTimestampOffset(0),mNextResultFrameNumber(0),mNextReprocessResultFrameNumber(0),mNextShutterFrameNumber(0),mNextReprocessShutterFrameNumber(0),mListener(NULL){ATRACE_CALL();camera3_callback_ops::notify = &sNotify;camera3_callback_ops::process_capture_result = &sProcessCaptureResult;ALOGV("%s: Created device for camera %d", __FUNCTION__, id);}
2.2.3.2 [Camera2Client] Camera2Client初始化 client->initialize(mModule))
  • 1 Camera2ClientBase::initialize里面会调用 Camera3Device::initialize 对/dev/videox 调备节点进行初始化,获取对应的设备的opt 操作函数
  • 2 初始化 Camera 默认参数
  • 3 创建 Camera 运行时的六大线程
    • 3.1 StreamingProcessor:用来处理preview和录像 stream的线程。
    • 3.2 FrameProcessor:用来处理3A和人脸识别的线程。
    • 3.3 CaptureSequencer:拍照流程状态机线程,拍照的场景非常多,后面会发出状态机的运转流程。
    • 3.4 JpegProcessor:用来处理拍照 jpeg stream 线程
    • 3.5 ZslProcessor3:这个处理零延时zsl stream使用的线程
    • 3.6 mCallbackProcessor:处理callback的线程,主要包含对 callback stream 的创建函数 updateStream()以及处理 HAL 层传上来的 callback stream 的线程

@ frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp

status_t Camera2Client::initialize(CameraModule *module){ATRACE_CALL();ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);status_t res;// 1. Camera2ClientBase::initialize调用 Camera3Device::initialize 进行设备初始化,获取对应的 camera device 的opt 操作函数res = Camera2ClientBase::initialize(module);==============> @ frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cppmDevice->initialize(module);mDevice->setNotifyCallback(weakThis);<==============// 2. 初始化 Camera默认参数{SharedParameters::Lock l(mParameters);res = l.mParameters.initialize(&(mDevice->info()), mDeviceVersion);================>+@ frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.cpp+status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) {+......+videoWidth = previewWidth;+videoHeight = previewHeight;+params.setPreviewSize(previewWidth, previewHeight);+params.setVideoSize(videoWidth, videoHeight);+params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, +String8::format("%dx%d", previewWidth, previewHeight));+params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, supportedPreviewFormats);+......省略一系列 参数初始化代码<================}String8 threadName;// 3. 创建 Camera 运行时的六大线程// 3.1 StreamingProcessor:用来处理preview和录像 stream的线程。mStreamingProcessor = new StreamingProcessor(this);threadName = String8::format("C2-%d-StreamProc", mCameraId);mFrameProcessor->run(threadName.string());// 3.2 FrameProcessor:用来处理3A和人脸识别的线程。mFrameProcessor = new FrameProcessor(mDevice, this);threadName = String8::format("C2-%d-FrameProc",mCameraId);mFrameProcessor->run(threadName.string());// 3.3 CaptureSequencer:拍照流程状态机线程,拍照的场景非常多,后面会发出状态机的运转流程。mCaptureSequencer = new CaptureSequencer(this);threadName = String8::format("C2-%d-CaptureSeq",mCameraId);mCaptureSequencer->run(threadName.string());// 3.4 JpegProcessor:用来处理拍照 jpeg stream 线程mJpegProcessor = new JpegProcessor(this, mCaptureSequencer);threadName = String8::format("C2-%d-JpegProc",mCameraId);mJpegProcessor->run(threadName.string());// 3.5 ZslProcessor3:这个处理零延时zsl stream使用的线程mZslProcessor = new ZslProcessor(this, mCaptureSequencer);threadName = String8::format("C2-%d-ZslProc",mCameraId);mZslProcessor->run(threadName.string());// 3.6 mCallbackProcessor:处理callback的线程,主要包含对 callback stream 的创建函数 updateStream()以及处理 HAL 层传上来的 callback stream 的线程mCallbackProcessor = new CallbackProcessor(this);threadName = String8::format("C2-%d-CallbkProc",mCameraId);mCallbackProcessor->run(threadName.string());return OK;}
2.2.3.2.1 [Camera3Device] Camera device 初始化 mDevice->initialize(module)
  • 1 创建session
  • 2 调用CameraProviderManager的opensession方法 @frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {ATRACE_CALL();Mutex::Autolock il(mInterfaceLock);Mutex::Autolock l(mLock);ALOGE("sundpmy_ %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");ALOGE("sundpmy_ manager->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;}......}
2.2.3.2.2 [CameraProviderManager] manager->openSession
  • 1 根据CameraDevice的版本,从所有Provider中,找到对应的DeviceInfo
  • 2 根据刚刚deviceInfo中对应的provider的信息,获取到对应CameraProvider服务 @frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
status_t CameraProviderManager::openSession(const std::string &id, const sp<device::V3_2::ICameraDeviceCallback>& callback, /*out*/ sp<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}); if (deviceInfo == nullptr) return NAME_NOT_FOUND; // 根据刚刚deviceInfo中对应的provider的信息,获取到对应CameraProvider服务 auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo); 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; } ALOGE("sundpmy_ openSession"); // 这个interface就是前面startDeviceInterface()得到的CameraDevice,这里是要通过CameraDevicce::open()创建一个有效的CameraDeviceSession。这一步也是通过HIDL调用到了HAL ret = interface->open(callback, [&status, &session] (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) { status = s; if (status == Status::OK) { *session = cameraSession; } }); if (!ret.isOk()) { removeRef(DeviceMode::CAMERA, id); 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); }
2.2.3.3 [CameraDevice] CameraDevice::open
  • 1 通过CameraModule的对象mModule继续open
  • 2 通过CameraModule的对象mModule调用getCameraInfo得到camera的一些信息
  • 3 创建CameraDeviceSession @hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback,ICameraDevice::open_cb _hidl_cb){Status status = initStatus();sp<CameraDeviceSession> session = nullptr;ALOGE("sundpmy_ 3.2 CameraDevice::open");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) {// Provider will never pass initFailed device to client, so// this must be a disconnected cameraALOGE("%s: cannot open camera %s. camera is disconnected!",__FUNCTION__, mCameraId.c_str());_hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);return Void();} else {mLock.lock();ALOGE("sundpmy_%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);session = mSession.promote();if (session != nullptr && !session->isClosed()) {ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);mLock.unlock();_hidl_cb(Status::CAMERA_IN_USE, nullptr);return Void();}/** Open HAL device */status_t res;camera3_device_t *device;ATRACE_BEGIN("camera3->open");//通过的CameraModule的对象mModule继续openres = mModule->open(mCameraId.c_str(),reinterpret_cast<hw_device_t**>(&device));ATRACE_END();if (res != OK) {ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());mLock.unlock();_hidl_cb(getHidlStatus(res), nullptr);return Void();}/** Cross-check device version */ if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) { ALOGE("%s: Could not open camera: " "Camera device should be at least %x, reports %x instead", __FUNCTION__, CAMERA_DEVICE_API_VERSION_3_2, device->common.version); device->common.close(&device->common); mLock.unlock(); _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); } struct camera_info info; //通过CameraModule的对象mModule调用getCameraInfo得到camera的一些信息 res = mModule->getCameraInfo(mCameraIdInt, &info); if (res != OK) { ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__); device->common.close(&device->common); mLock.unlock(); _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); } //创建CameraDeviceSession session = createSession( device, info.static_camera_characteristics, callback); if (session == nullptr) { ALOGE("%s: camera device session allocation failed", __FUNCTION__); mLock.unlock(); _hidl_cb(Status::INTERNAL_ERROR, nullptr); return Void(); } if (session->isInitFailed()) { ALOGE("%s: camera device session init failed", __FUNCTION__); session = nullptr; mLock.unlock(); _hidl_cb(Status::INTERNAL_ERROR, nullptr); return Void(); } mSession = session; IF_ALOGV() { session->getInterface()->interfaceChain([]( ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { ALOGV("Session interface chain:"); for (const auto& iface : interfaceChain) { ALOGV("%s", iface.c_str()); } }); } mLock.unlock(); } _hidl_cb(status, session->getInterface()); return Void(); }
2.2.3.4 [CameraModule] CameraModule::open

@hardware/interfaces/camera/common/1.0/default/CameraModule.cpp

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;}

filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
的参数mModule->common.methods->open(&mModule->common, id, device)
首先关注一下mModule,它是在CameraModule构造的时候赋值的

bool LegacyCameraProviderImpl_2_4::initialize() {camera_module_t *rawModule;int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,(const hw_module_t **)&rawModule);if (err < 0) {ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));return true;}//CameraModule构造的时候赋值mModule = new CameraModule(rawModule);err = mModule->init();if (err != OK) {ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));mModule.clear();return true;}ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());// Setup vendor tags here so HAL can setup vendor keys in camera characteristicsVendorTagDescriptor::clearGlobalVendorTagDescriptor();if (!setUpVendorTags()) {ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);}......}
2.2.3.4.1 [hardware] camera_module_t

@hardware/qcom/camera/QCamera2/QCamera2Hal.cpp

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 = "QCamera Module",.author = "Qualcomm Innovation Center Inc",.methods= &qcamera::QCamera2Factory::mModuleMethods,.dso= NULL,.reserved = {0}};camera_module_t HAL_MODULE_INFO_SYM = {.common = camera_common,.get_number_of_cameras= qcamera::QCamera2Factory::get_number_of_cameras,.get_camera_info= qcamera::QCamera2Factory::get_camera_info,.set_callbacks= qcamera::QCamera2Factory::set_callbacks,.get_vendor_tag_ops = qcamera::QCamera3VendorTags::get_vendor_tag_ops,.open_legacy= (qcamera::QCameraCommon::needHAL1Support()) ?qcamera::QCamera2Factory::open_legacy : NULL,.set_torch_mode = qcamera::QCamera2Factory::set_torch_mode,.init = NULL,.reserved = {0}};

mModule->common.methods->open(&mModule->common, id, device)的open,
就是:
camera_common.&qcamera::QCamera2Factory::mModuleMethods.open
即:camera_device_open

struct hw_module_methods_t QCamera2Factory::mModuleMethods = {.open = QCamera2Factory::camera_device_open,};
2.2.3.5 [Hardware] 打开设备 QCamera2Factory::cameraDeviceOpen()

@ hardware/qcom/camera/QCamera2/QCamera2Factory.cpp

int QCamera2Factory::cameraDeviceOpen(int camera_id, struct hw_device_t **hw_device){LOGI("Open camera id %d API version %d",camera_id, mHalDescriptors[camera_id].device_version);if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {CAMSCOPE_INIT(CAMSCOPE_SECTION_HAL);QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId, mCallbacks);rc = hw->openCamera(hw_device);}#ifdef QCAMERA_HAL1_SUPPORTelse if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);rc = hw->openCamera(hw_device);}#endifreturn rc;}

初始化 QCamera3HardwareInterface() 可以不看 @ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp

QCamera3HardwareInterface::QCamera3HardwareInterface(uint32_t cameraId, const camera_module_callbacks_t *callbacks): mCameraId(cameraId),mCameraHandle(NULL),mCameraInitialized(false),mCallbacks(callbacks),...... //省略一系列Camera 初始化默认值{// 1. 获取HAL 层 log 等级getLogLevel();=========>property_get("persist.camera.hal.debug", prop, "0");property_get("persist.camera.kpi.debug", prop, "0");property_get("persist.camera.global.debug", prop, "0");mCommon.init(gCamCapability[cameraId]);mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;mCameraDevice.common.close = close_camera_device;mCameraDevice.ops = &mCameraOps;===⇒ @ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cppmCameraDevice.priv = this;gCamCapability[cameraId]->version = CAM_HAL_V3;// TODO: hardcode for now until mctl add support for min_num_pp_bufs//TBD - To see if this hardcoding is needed. Check by printing if this is filled by mctl to 3gCamCapability[cameraId]->min_num_pp_bufs = 3;pthread_condattr_t mCondAttr;pthread_condattr_init(&mCondAttr);pthread_condattr_setclock(&mCondAttr, CLOCK_MONOTONIC);pthread_cond_init(&mBuffersCond, &mCondAttr);pthread_cond_init(&mRequestCond, &mCondAttr);pthread_cond_init(&mHdrRequestCond, &mCondAttr);pthread_condattr_destroy(&mCondAttr);mPendingLiveRequest = 0;mCurrentRequestId = -1;pthread_mutex_init(&mMutex, NULL);for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++)mDefaultMetadata[i] = NULL;// Getting system props of different kindschar prop[PROPERTY_VALUE_MAX];memset(prop, 0, sizeof(prop));// 获取 persist.camera.raw.dump,是否使能 RAW dump 功能property_get("persist.camera.raw.dump", prop, "0");mEnableRawDump = atoi(prop);// 获取 persist.camera.hal3.force.hdr,是否使能 hdr 功能property_get("persist.camera.hal3.force.hdr", prop, "0");mForceHdrSnapshot = atoi(prop);if (mEnableRawDump)LOGD("Raw dump from Camera HAL enabled");memset(&mInputStreamInfo, 0, sizeof(mInputStreamInfo));memset(mLdafCalib, 0, sizeof(mLdafCalib));memset(prop, 0, sizeof(prop));property_get("persist.camera.tnr.preview", prop, "0");m_bTnrPreview = (uint8_t)atoi(prop);memset(prop, 0, sizeof(prop));property_get("persist.camera.swtnr.preview", prop, "1");m_bSwTnrPreview = (uint8_t)atoi(prop);memset(prop, 0, sizeof(prop));property_get("persist.camera.tnr.video", prop, "0");m_bTnrVideo = (uint8_t)atoi(prop);memset(prop, 0, sizeof(prop));property_get("persist.camera.avtimer.debug", prop, "0");m_debug_avtimer = (uint8_t)atoi(prop);LOGI("AV timer enabled: %d", m_debug_avtimer);memset(prop, 0, sizeof(prop));property_get("persist.camera.cacmode.disable", prop, "0");m_cacModeDisabled = (uint8_t)atoi(prop);mRdiModeFmt = gCamCapability[mCameraId]->rdi_mode_stream_fmt;//Load and read GPU library.lib_surface_utils = NULL;LINK_get_surface_pixel_alignment = NULL;mSurfaceStridePadding = CAM_PAD_TO_32;// 打开 libadreno_utils.solib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);if (lib_surface_utils) {*(void **)&LINK_get_surface_pixel_alignment =dlsym(lib_surface_utils, "get_gpu_pixel_alignment"); if (LINK_get_surface_pixel_alignment) { mSurfaceStridePadding = LINK_get_surface_pixel_alignment(); } dlclose(lib_surface_utils);}if (gCamCapability[cameraId]->is_quadracfa_sensor) {LOGI("Sensor support Quadra CFA mode");m_bQuadraCfaSensor = true;}m_bQuadraCfaRequest = false;m_bQuadraSizeConfigured = false;memset(&mStreamList, 0, sizeof(camera3_stream_configuration_t));}

接下来,调用 hw->openCamera(hw_device); @ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp

int QCamera3HardwareInterface::openCamera(struct hw_device_t **hw_device){......if (mState != CLOSED) {*hw_device = NULL;return PERMISSION_DENIED;}mPerfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",mCameraId);rc = openCamera();if (rc == 0) {*hw_device = &mCameraDevice.common;} else {*hw_device = NULL;}LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d", mCameraId, rc);if (rc == NO_ERROR) {mState = OPENED;}return rc;}

接下来调用 int QCamera3HardwareInterface::openCamera() @ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp

int QCamera3HardwareInterface::openCamera(){KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_OPENCAMERA);if (mCameraHandle) {LOGE("Failure: Camera already opened");return ALREADY_EXISTS;}rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);if (rc < 0) {LOGE("Failed to reserve flash for camera id: %d",mCameraId);return UNKNOWN_ERROR;}rc = camera_open((uint8_t)mCameraId, &mCameraHandle);rc = mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, camEvtHandle, (void *)this);mExifParams.debug_params = (mm_jpeg_debug_exif_params_t *) malloc (sizeof(mm_jpeg_debug_exif_params_t));if (mExifParams.debug_params) {memset(mExifParams.debug_params, 0, sizeof(mm_jpeg_debug_exif_params_t));} else {LOGE("Out of Memory. Allocation failed for 3A debug exif params");return NO_MEMORY;}mFirstConfiguration = true;......}
2.2.3.5.1 camera_open((uint8_t)mCameraId, &mCameraHandle)

打开Camera 成功后,hardware 层中将Camera 所有信息保存在 g_cam_ctrl.cam_obj[cam_idx] 中,同时返回对应的camera 的opt 操作函数

@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c

int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl){int32_t rc = 0;mm_camera_obj_t *cam_obj = NULL;uint32_t cam_idx = camera_idx;uint32_t aux_idx = 0;uint8_t is_multi_camera = 0;#ifdef QCAMERA_REDEFINE_LOGmm_camera_debug_open();#endifLOGD("E camera_idx = %d\n", camera_idx);//判断是否是双摄cameraif (is_dual_camera_by_idx(camera_idx)) {is_multi_camera = 1;cam_idx = mm_camera_util_get_handle_by_num(0,g_cam_ctrl.cam_index[camera_idx]);aux_idx = (get_aux_camera_handle(g_cam_ctrl.cam_index[camera_idx]) >> MM_CAMERA_HANDLE_SHIFT_MASK);LOGH("Dual Camera: Main ID = %d Aux ID = %d", cam_idx, aux_idx);}pthread_mutex_lock(&g_intf_lock);/* opened already */if(NULL != g_cam_ctrl.cam_obj[cam_idx] && g_cam_ctrl.cam_obj[cam_idx]->ref_count != 0) {pthread_mutex_unlock(&g_intf_lock);LOGE("Camera %d is already open", cam_idx);return -EBUSY;}cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));/* 初始化cam_obj的信息*/memset(cam_obj, 0, sizeof(mm_camera_obj_t));cam_obj->ctrl_fd = -1;cam_obj->ds_fd = -1;cam_obj->ref_count++;cam_obj->my_num = 0;cam_obj->my_hdl = mm_camera_util_generate_handler(cam_idx);cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */cam_obj->vtbl.ops = &mm_camera_ops;pthread_mutex_init(&cam_obj->cam_lock, NULL);pthread_mutex_init(&cam_obj->muxer_lock, NULL);/* unlock global interface lock, if not, in dual camera use case,* current open will block operation of another opened camera obj*/pthread_mutex_lock(&cam_obj->cam_lock);pthread_mutex_unlock(&g_intf_lock);//hererc = mm_camera_open(cam_obj);if (is_multi_camera) {/*Open Aux camer's*/pthread_mutex_lock(&g_intf_lock);if(NULL != g_cam_ctrl.cam_obj[aux_idx] &&g_cam_ctrl.cam_obj[aux_idx]->ref_count != 0) {pthread_mutex_unlock(&g_intf_lock);LOGE("Camera %d is already open", aux_idx);rc = -EBUSY;} else {pthread_mutex_lock(&cam_obj->muxer_lock);pthread_mutex_unlock(&g_intf_lock);rc = mm_camera_muxer_camera_open(aux_idx, cam_obj);}}LOGH("Open succeded: handle = %d", cam_obj->vtbl.camera_handle);g_cam_ctrl.cam_obj[cam_idx] = cam_obj;*camera_vtbl = &cam_obj->vtbl;return 0;}

继续跟进分析:
终于来到最底层的实现了,mm_camera_open 主要工作是填充 my_obj,并且启动、初始化一些线程相关的东西,关于线程的部分我这里就省略掉了。
此时Open 对应的 /dev/video 节点,获得对应的session_id,创建好相关的 socket ,最终所有信息,保存在 mm_camera_obj_t * cam_obj节构体中。
@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera.c

int32_t mm_camera_open(mm_camera_obj_t *my_obj){char dev_name[MM_CAMERA_DEV_NAME_LEN];int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;int cam_idx = 0;const char *dev_name_value = NULL;LOGD("begin\n");dev_name_value = mm_camera_util_get_dev_name_by_num(my_obj->my_num, my_obj->my_hdl);snprintf(dev_name, sizeof(dev_name), "/dev/%s",dev_name_value);sscanf(dev_name, "/dev/video%d", &cam_idx);LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx);do{n_try--;errno = 0;my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);l_errno = errno;LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno);if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {break;}LOGE("Failed with %s error, retrying after %d milli-seconds", strerror(errno), sleep_msec);usleep(sleep_msec * 1000U);}while (n_try > 0);mm_camera_get_session_id(my_obj, &my_obj->sessionid);LOGH("Camera Opened id = %d sessionid = %d", cam_idx, my_obj->sessionid);#ifdef DAEMON_PRESENT/* open domain socket*/n_try = MM_CAMERA_DEV_OPEN_TRIES;do {n_try--;my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);l_errno = errno;LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno);if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {LOGD("opened, break out while loop");break;}LOGD("failed with I/O error retrying after %d milli-seconds", sleep_msec);usleep(sleep_msec * 1000U);} while (n_try > 0);#else /* DAEMON_PRESENT */cam_status_t cam_status;cam_status = mm_camera_module_open_session(my_obj->sessionid,mm_camera_module_event_handler);#endif /* DAEMON_PRESENT */pthread_condattr_init(&cond_attr);pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);pthread_mutex_init(&my_obj->msg_lock, NULL);pthread_mutex_init(&my_obj->cb_lock, NULL);pthread_mutex_init(&my_obj->evt_lock, NULL);pthread_cond_init(&my_obj->evt_cond, &cond_attr);pthread_condattr_destroy(&cond_attr);LOGD("Launch evt Thread in Cam Open");snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");mm_camera_cmd_thread_launch(&my_obj->evt_thread, mm_camera_dispatch_app_event, (void *)my_obj);/* launch event poll thread * we will add evt fd into event poll thread upon user first register for evt */LOGD("Launch evt Poll Thread in Cam Open");snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll");mm_camera_poll_thread_launch(&my_obj->evt_poll_thread, MM_CAMERA_POLL_TYPE_EVT);mm_camera_evt_sub(my_obj, TRUE);/* unlock cam_lock, we need release global intf_lock in camera_open(), * in order not block operation of other Camera in dual camera use case.*/pthread_mutex_unlock(&my_obj->cam_lock);LOGD("end (rc = %d)\n", rc);return rc;}
2.2.3.5.2 Camera 操作节构体 cam_obj->vtbl.ops
@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.cstatic mm_camera_ops_t mm_camera_ops = {.query_capability = mm_camera_intf_query_capability,.register_event_notify = mm_camera_intf_register_event_notify,.close_camera = mm_camera_intf_close,.set_parms = mm_camera_intf_set_parms,.get_parms = mm_camera_intf_get_parms,.do_auto_focus = mm_camera_intf_do_auto_focus,.cancel_auto_focus = mm_camera_intf_cancel_auto_focus,.prepare_snapshot = mm_camera_intf_prepare_snapshot,.start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,.stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,.map_buf = mm_camera_intf_map_buf,.map_bufs = mm_camera_intf_map_bufs,.unmap_buf = mm_camera_intf_unmap_buf,.add_channel = mm_camera_intf_add_channel,.delete_channel = mm_camera_intf_del_channel,.get_bundle_info = mm_camera_intf_get_bundle_info,.add_stream = mm_camera_intf_add_stream,.link_stream = mm_camera_intf_link_stream,.delete_stream = mm_camera_intf_del_stream,.config_stream = mm_camera_intf_config_stream,.qbuf = mm_camera_intf_qbuf,.cancel_buffer = mm_camera_intf_cancel_buf,.get_queued_buf_count = mm_camera_intf_get_queued_buf_count,.map_stream_buf = mm_camera_intf_map_stream_buf,.map_stream_bufs = mm_camera_intf_map_stream_bufs,.unmap_stream_buf = mm_camera_intf_unmap_stream_buf,.set_stream_parms = mm_camera_intf_set_stream_parms,.get_stream_parms = mm_camera_intf_get_stream_parms,.start_channel = mm_camera_intf_start_channel,.stop_channel = mm_camera_intf_stop_channel,.request_super_buf = mm_camera_intf_request_super_buf,.cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,.flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,.configure_notify_mode = mm_camera_intf_configure_notify_mode,.process_advanced_capture = mm_camera_intf_process_advanced_capture,.get_session_id = mm_camera_intf_get_session_id,.set_dual_cam_cmd = mm_camera_intf_set_dual_cam_cmd,.flush = mm_camera_intf_flush,.register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb,.register_frame_sync = mm_camera_intf_reg_frame_sync,.handle_frame_sync_cb = mm_camera_intf_handle_frame_sync_cb};
2.2.3.5.3 [Hardware] 初始化Framewroks层的Callback 函数 QCamera3HardwareInterface::initialize( )
@ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp/*=========================================================================== * FUNCTION : initialize * DESCRIPTION: Initialize frameworks callback functions * @callback_ops : callback function to frameworks *==========================================================================*/int QCamera3HardwareInterface::initialize(const struct camera3_callback_ops *callback_ops){ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_INIT);LOGI("E :mCameraId = %d mState = %d", mCameraId, mState);rc = initParameters();mCallbackOps = callback_ops;=====> 该Callback 是从 frameworks/av/services/camera/libcameraservice/CameraService.cpp 中传递下来的if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {mModule->setCallbacks(this);}mChannelHandle = mCameraHandle->ops->add_channel( mCameraHandle->camera_handle, NULL, NULL, this);mCameraInitialized = true;mState = INITIALIZED;LOGI("X");return 0;}

2.2.4 EventHandler( )

在 EventHandler 中,根据具体的事件,调用不同的 callback 函数

@ frameworks/base/core/java/android/hardware/Camera.javaprivate class EventHandler extends Handler{private final Camera mCamera;public EventHandler(Camera c, Looper looper) {super(looper);mCamera = c;}@Overridepublic void handleMessage(Message msg) {switch(msg.what) {case CAMERA_MSG_SHUTTER:if (mShutterCallback != null) {mShutterCallback.onShutter();}return;case CAMERA_MSG_RAW_IMAGE:if (mRawImageCallback != null) {mRawImageCallback.onPictureTaken((byte[])msg.obj, mCamera);}return;case CAMERA_MSG_COMPRESSED_IMAGE:if (mJpegCallback != null) {mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);}return;case CAMERA_MSG_PREVIEW_FRAME:PreviewCallback pCb = mPreviewCallback;if (pCb != null) {if (mOneShot) {// Clear the callback variable before the callback// in case the app calls setPreviewCallback from// the callback functionmPreviewCallback = null;} else if (!mWithBuffer) {// We're faking the camera preview mode to prevent// the app from being flooded with preview frames.// Set to oneshot mode again.setHasPreviewCallback(true, false);}pCb.onPreviewFrame((byte[])msg.obj, mCamera);}return;case CAMERA_MSG_POSTVIEW_FRAME:if (mPostviewCallback != null) {mPostviewCallback.onPictureTaken((byte[])msg.obj, mCamera);}return;case CAMERA_MSG_FOCUS:AutoFocusCallback cb = null;synchronized (mAutoFocusCallbackLock) {cb = mAutoFocusCallback;}if (cb != null) {boolean success = msg.arg1 == 0 ? false : true;cb.onAutoFocus(success, mCamera);}return;case CAMERA_MSG_ZOOM:if (mZoomListener != null) {mZoomListener.onZoomChange(msg.arg1, msg.arg2 != 0, mCamera);}return;case CAMERA_MSG_PREVIEW_METADATA:if (mFaceListener != null) {mFaceListener.onFaceDetection((Face[])msg.obj, mCamera);}return;case CAMERA_MSG_ERROR :Log.e(TAG, "Error " + msg.arg1);if (mErrorCallback != null) {mErrorCallback.onError(msg.arg1, mCamera);}return;case CAMERA_MSG_FOCUS_MOVE:if (mAutoFocusMoveCallback != null) {mAutoFocusMoveCallback.onAutoFocusMoving(msg.arg1 == 0 ? false : true, mCamera);}return;/* ### QC ADD-ONS: START */case CAMERA_MSG_STATS_DATA:int statsdata[] = new int[257];for(int i =0; i<257; i++ ) { statsdata[i] = byteToInt( (byte[])msg.obj, i*4);}if (mCameraDataCallback != null) { mCameraDataCallback.onCameraData(statsdata, mCamera);}return;case CAMERA_MSG_META_DATA:if (mCameraMetaDataCallback != null) {mCameraMetaDataCallback.onCameraMetaData((byte[])msg.obj, mCamera);}return;/* ### QC ADD-ONS: END */default:Log.e(TAG, "Unknown message type " + msg.what);return;}}}

2.3 内核层msm_open

从上文的my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
调用到内核:@kernel/msm-4.14/drivers/media/platform/msm/camera_v2/msm.c

static int msm_open(struct file *filep){int rc = -1;unsigned long flags;struct msm_video_device *pvdev = video_drvdata(filep);DEBUG("enter");if (WARN_ON(!pvdev))return rc;/* !!! only ONE open is allowed !!! */if (atomic_cmpxchg(&pvdev->opened, 0, 1))return -EBUSY;spin_lock_irqsave(&msm_pid_lock, flags);msm_pid = get_pid(task_pid(current));spin_unlock_irqrestore(&msm_pid_lock, flags);/* create event queue */rc = v4l2_fh_open(filep);if (rcprivate_data;spin_unlock_irqrestore(&msm_eventq_lock, flags);/* register msm_v4l2_pm_qos_request */msm_pm_qos_add_request();return rc;}

后面的流程就不看了。
至此,整个open Camera 流程就完了

3 OpenSession 流程分析

open过程中会 start session 大概流程如下:

3.1 mm-camera2框架

mm-camera架构有2个版本,我们这里研究的是新版本:

(1)最老的版本是有一个守护进程mm-qcamera-daemon的,
如msm8909平台,后来新版的架构改过,移除了这个守护进程,如msm8937(sdm429)平台。
(2) Android O 中,系统启动时,就会启动 CameraProvider 服务。它将 Camera HAL 从 cameraserver 进程中分离出来,做为一个独立进程 android.hardware.camera.provider@2.4-service 来控制 HAL。这两个进程之间经过 HIDL 机制进行通讯。

mm-camera代码位于 vendor/qcom/proprietary/mm-camera/mm-camera2 目录下,
在此目录下有 media-controllerserver-tuningserver-imaging,我们需要关注的是 media-controller 目录,整个树形结构如下:

|- mct——应该就是camera的引擎() 里面包含了引擎、pipiline、bus、module、stream及event等定义及封装。
|- modules —— 这里面就是划分好的一些模块代码,各模块大致功能如下 :
|- sensor —— sensor 的驱动模块(src模块)
|- actuator_libs,actuators 马达基本配置以及效果参数
|- sensor_libs,chromatix camera模组基本配置以及效果参数,模组这块最重要的两部分
|- eeprom_libs,eeprom eeprom配置以及参数,现在基本不用
|- strobe_flash,led_flash strobe,led flash驱动
|- iface—— ISP interface模块
|- isp—— 主要是ISP的处理,其内部又包含了众多的模块(inter模块)
|- stats—— 一些统计算法模块,如3A,ASD,AFD,IS,GRRO等数据统计的处理(sink模块)
|- pproc—— post process处理(inter模块)
|- imglib —— 主要是图片的一些后端处理,如HDR,人脸识别等(sink模块)

3.2 media controller线程

MCT线程是camera新架构的引擎部分,负责对管道的监控,由此来完成一个camera设备的控制运转。下面看的是mct controller线程的创建

3.2.1 mm_camera_module_open_session

Open阶段完成后,会继续opensession。

@hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera.cint32_t mm_camera_open(mm_camera_obj_t *my_obj){......const char *dev_name_value = NULL;dev_name_value = mm_camera_util_get_dev_name_by_num(my_obj->my_num,my_obj->my_hdl);snprintf(dev_name, sizeof(dev_name), "/dev/%s",dev_name_value);my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);cam_status_t cam_status;......cam_status = mm_camera_module_open_session(my_obj->sessionid,mm_camera_module_event_handler);......}

@ hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c

/*=========================================================================== * FUNCTION : mm_camera_module_open_session * * DESCRIPTION: wrapper function to call shim layer API to open session. * * PARAMETERS : * @sessionid: sessionID to open session * @evt_cb : Event callback function * * RETURN : int32_t type of status *0-- success *non-zero error code -- failure *==========================================================================*/cam_status_t mm_camera_module_open_session(int sessionid,mm_camera_shim_event_handler_func evt_cb){cam_status_t rc = -1;if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session) {rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session(sessionid, evt_cb);}return rc;}

g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session

1 @hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.cstatic mm_camera_ctrl_t g_cam_ctrl;2 @hardware/qcom/camera/QCamera2/stack/mm-camera-interface/inc/mm_camera.htypedef struct {int8_t num_cam;mm_camera_shim_ops_t cam_shim_ops;int8_t num_cam_to_expose;char video_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN];mm_camera_obj_t *cam_obj[MM_CAMERA_MAX_NUM_SENSORS];struct camera_info info[MM_CAMERA_MAX_NUM_SENSORS];cam_sync_type_t cam_type[MM_CAMERA_MAX_NUM_SENSORS];cam_sync_mode_t cam_mode[MM_CAMERA_MAX_NUM_SENSORS];uint8_t is_yuv[MM_CAMERA_MAX_NUM_SENSORS]; // 1=CAM_SENSOR_YUV, 0=CAM_SENSOR_RAWuint32_t cam_index[MM_CAMERA_MAX_NUM_SENSORS]; //Actual cam index are stored in bits} mm_camera_ctrl_t;3 @hardware/qcom/camera/QCamera2/stack/common/mm_camera_shim.htypedef struct {cam_status_t (*mm_camera_shim_open_session) (int session,mm_camera_shim_event_handler_func evt_cb);int32_t (*mm_camera_shim_close_session)(int session);int32_t (*mm_camera_shim_send_cmd)(cam_shim_packet_t *event);} mm_camera_shim_ops_t;

3.2.2 mct_shimlayer_process_module_init

上面其中的mm_camera_shim_open_session就是mct_shimlayer_start_session @vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct_shim_layer/mct_shim_layer.c

int mct_shimlayer_process_module_init(mm_camera_shim_ops_t*shim_ops_tbl){...shim_ops_tbl->mm_camera_shim_open_session = mct_shimlayer_start_session;shim_ops_tbl->mm_camera_shim_close_session = mct_shimlayer_stop_session;shim_ops_tbl->mm_camera_shim_send_cmd = mct_shimlayer_process_event;...}

3.2.3 mct_shimlayer_start_session

@vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct_shim_layer/mct_shim_layer.c
1.创建mct_controller

cam_status_t mct_shimlayer_start_session(int session,mm_camera_shim_event_handler_func event_cb){int32_t enabled_savemem;char savemem[128];cam_status_t ret = CAM_STATUS_FAILED;char prop[PROPERTY_VALUE_MAX];int enable_memleak = 0;//内存泄漏检查#ifdef MEMLEAK_FLAGproperty_get("persist.vendor.camera.memleak.enable", prop, "0");enable_memleak = atoi(prop);if (enable_memleak) {CLOGH(CAM_MCT_MODULE, "Memory leak tracking enabled.");enable_memleak_trace(0);}#endifpthread_mutex_lock(&session_mutex);property_get("vendor.camera.cameradaemon.SaveMemAtBoot", savemem, "0");enabled_savemem = atoi(savemem);if (enabled_savemem == 1) {if (mct_shimlayer_module_init() == FALSE) {pthread_mutex_unlock(&session_mutex);return CAM_STATUS_FAILED;}}//创建mct_controllerret = mct_controller_new(modules, session, config_fd, event_cb);if (ret == CAM_STATUS_BUSY || ret == CAM_STATUS_FAILED) {pthread_mutex_unlock(&session_mutex);CLOGE(CAM_SHIM_LAYER,"Session creation for session =%d failed with err %d",session, ret);/*Signalling memleak thread to print if any memory leak present */#ifdef MEMLEAK_FLAGif (enable_memleak) {CLOGH(CAM_MCT_MODULE, "Signal to print memory leak");if (pthread_mutex_trylock (&server_memleak_mut) == 0) {server_memleak_event = PRINT_LEAK_MEMORY;pthread_cond_signal(&server_memleak_con);pthread_mutex_unlock (&server_memleak_mut);}}#endifreturn ret;}pthread_mutex_unlock(&session_mutex);return ret;}

3.2.4 mct_controller_new

1.创建mct_pipeline
2.mct_pipeline 启动session @vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/pipeline/mct_pipeline.c

cam_status_t mct_controller_new(mct_list_t *mods,unsigned int session_idx, int serv_fd, void *event_cb){mct_controller_t *mct = NULL;mct = (mct_controller_t *)malloc(sizeof(mct_controller_t));memset(mct, 0, sizeof(mct_controller_t));//创建mct_pipelinemct->pipeline = mct_pipeline_new(session_idx, mct);...//mct_pipeline 启动sessionret_type = mct_pipeline_start_session(mct->pipeline);} 
3.2.4.1 mct_pipeline_new

1.创建mct_pipeline
2.初始化pipeline的信息

mct_pipeline_t* mct_pipeline_new (unsigned int session_idx,mct_controller_t *pController){//创建mct_pipelinemct_pipeline_t *pipeline;pipeline = malloc(sizeof(mct_pipeline_t));memset(pipeline, 0, sizeof(mct_pipeline_t));//初始化pipeline的信息}
3.2.4.2 mct_pipeline_start_session
cam_status_t mct_pipeline_start_session(mct_pipeline_t *pipeline){boolean rc;int ret;int rdi_standalone_streams = 0;struct timespec timeToWait;char prop[PROPERTY_VALUE_MAX];CLOGE(CAM_MCT_MODULE, "sundp_ mct_pipeline_start_session\n");if (!pipeline) {CLOGE(CAM_MCT_MODULE, "NULL pipeline ptr");return CAM_STATUS_FAILED;}property_get("persist.vendor.camera.mct.multirdi", prop, "0");rdi_standalone_streams = atoi (prop);CLOGE(CAM_MCT_MODULE, "sundp_ rdi_standalone_streams = %d\n",rdi_standalone_streams);ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_MCT_START_SESSION);pthread_mutex_init(&pipeline->thread_data.mutex, NULL);pthread_condattr_init(&pipeline->thread_data.condattr);pthread_condattr_setclock(&pipeline->thread_data.condattr, CLOCK_MONOTONIC);pthread_cond_init(&pipeline->thread_data.cond_v, &pipeline->thread_data.condattr);pipeline->thread_data.started_num = 0;pipeline->thread_data.modules_num = 0;pipeline->thread_data.started_num_success = 0;//获得module的数量,这里的module就是sensor,iface等等rc = mct_list_traverse(pipeline->modules, mct_pipeline_get_module_num,pipeline);//开启modulerc &= mct_list_traverse(pipeline->modules, mct_pipeline_modules_start,pipeline);rc = mct_util_get_timeout(MCT_THREAD_TIMEOUT, &timeToWait);
3.2.4.3 mct_pipeline_modules_start

主要通过调用pthread_create,创建6大线程:
pthread_create(sensor)
pthread_create(iface)
pthread_create(isp)
pthread_create(stats)
pthread_create(pproc)
pthread_create(imglib)
然后在start这些session

static boolean mct_pipeline_modules_start(void *data1, void *data2){int rc = 0;pthread_attr_t attr;char thread_name[20];mct_pipeline_t *pipeline = (mct_pipeline_t *)data2;mct_pipeline_thread_data_t *thread_data = &(pipeline->thread_data);thread_data->module = (mct_module_t *)data1;thread_data->session_id = pipeline->session;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);pthread_mutex_lock(&thread_data->mutex);CLOGE(CAM_MCT_MODULE,"sundp_ pthread_create\n");//主要通过调用pthread_create,创建6大线程rc = pthread_create(&pipeline->thread_data.pid, &attr,&mct_pipeline_start_session_thread, (void *)thread_data);snprintf(thread_name, sizeof(thread_name), "CAM_start%s", MCT_MODULE_NAME(thread_data->module));CLOGE(CAM_MCT_MODULE,"sundp_ %s\n",thread_name);if(!rc) {pthread_setname_np(pipeline->thread_data.pid,thread_name);pthread_cond_wait(&thread_data->cond_v, &thread_data->mutex);}pthread_mutex_unlock(&thread_data->mutex);return TRUE;}
3.2.4.4 mct_pipeline_start_session_thread

start_session

static void* mct_pipeline_start_session_thread(void *data){mct_pipeline_thread_data_t *thread_data = (mct_pipeline_thread_data_t*)data;mct_module_t *module = thread_data->module;unsigned int session_id = thread_data->session_id;boolean rc = FALSE;ATRACE_BEGIN_SNPRINTF(30, "Camera:MCTModStart:%s", MCT_MODULE_NAME(thread_data->module));CLOGI(CAM_MCT_MODULE, "sundp_ E %s" , MCT_MODULE_NAME(thread_data->module));pthread_mutex_lock(&thread_data->mutex);pthread_cond_signal(&thread_data->cond_v);pthread_mutex_unlock(&thread_data->mutex);if (module->start_session) {CLOGI(CAM_MCT_MODULE, "sudp_ Calling start_session on Module %s",MCT_MODULE_NAME(module));rc = module->start_session(module, session_id);CLOGI(CAM_MCT_MODULE, "Module %s start_session rc = %d", MCT_MODULE_NAME(module), rc);}pthread_mutex_lock(&thread_data->mutex);thread_data->started_num++;if (rc == TRUE)thread_data->started_num_success++;CLOGI(CAM_MCT_MODULE, "started_num = %d, success = %d", thread_data->started_num, thread_data->started_num_success);if(thread_data->started_num == thread_data->modules_num)pthread_cond_signal(&thread_data->cond_v);pthread_mutex_unlock(&thread_data->mutex);ATRACE_END();CLOGI(CAM_MCT_MODULE, "sundp_ X %s" , MCT_MODULE_NAME(module));return NULL;}

3.3 else

后边的就不看了。到这open也open成功了。调用流程大概是

flowchart LRmm_camera_open --> open;mm_camera_open --> mm_camera_module_open_session --> mct_shimlayer_start_session --> mct_controller_new mct_controller_new --> mct_pipeline_new mct_controller_new --> mct_pipeline_start_session mct_pipeline_start_session --> mct_pipeline_get_module_num mct_pipeline_start_session --> mct_pipeline_modules_start mct_pipeline_modules_start --> sensor --> start_session mct_pipeline_modules_start --> iface --> start_session mct_pipeline_modules_start --> isp --> start_session mct_pipeline_modules_start --> stats --> start_session mct_pipeline_modules_start --> pproc --> start_sessiond_cond_signal(&thread_data->cond_v);pthread_mutex_unlock(&thread_data->mutex);if (module->start_session) {CLOGI(CAM_MCT_MODULE, "sudp_ Calling start_session on Module %s",MCT_MODULE_NAME(module));rc = module->start_session(module, session_id);CLOGI(CAM_MCT_MODULE, "Module %s start_session rc = %d", MCT_MODULE_NAME(module), rc);}pthread_mutex_lock(&thread_data->mutex);thread_data->started_num++;if (rc == TRUE)thread_data->started_num_success++;CLOGI(CAM_MCT_MODULE, "started_num = %d, success = %d", thread_data->started_num, thread_data->started_num_success);if(thread_data->started_num == thread_data->modules_num)pthread_cond_signal(&thread_data->cond_v);pthread_mutex_unlock(&thread_data->mutex);ATRACE_END();CLOGI(CAM_MCT_MODULE, "sundp_ X %s" , MCT_MODULE_NAME(module));return NULL;}

3.3 else

后边的就不看了。到这open也open成功了。调用流程大概是

#mermaid-svg-6hTXxcQ9XubYoAaA {font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6hTXxcQ9XubYoAaA .error-icon{fill:#552222;}#mermaid-svg-6hTXxcQ9XubYoAaA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6hTXxcQ9XubYoAaA .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-6hTXxcQ9XubYoAaA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6hTXxcQ9XubYoAaA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6hTXxcQ9XubYoAaA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6hTXxcQ9XubYoAaA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6hTXxcQ9XubYoAaA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6hTXxcQ9XubYoAaA .marker.cross{stroke:#333333;}#mermaid-svg-6hTXxcQ9XubYoAaA svg{font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6hTXxcQ9XubYoAaA .label{font-family:”trebuchet ms”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-6hTXxcQ9XubYoAaA .cluster-label text{fill:#333;}#mermaid-svg-6hTXxcQ9XubYoAaA .cluster-label span{color:#333;}#mermaid-svg-6hTXxcQ9XubYoAaA .label text,#mermaid-svg-6hTXxcQ9XubYoAaA span{fill:#333;color:#333;}#mermaid-svg-6hTXxcQ9XubYoAaA .node rect,#mermaid-svg-6hTXxcQ9XubYoAaA .node circle,#mermaid-svg-6hTXxcQ9XubYoAaA .node ellipse,#mermaid-svg-6hTXxcQ9XubYoAaA .node polygon,#mermaid-svg-6hTXxcQ9XubYoAaA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6hTXxcQ9XubYoAaA .node .label{text-align:center;}#mermaid-svg-6hTXxcQ9XubYoAaA .node.clickable{cursor:pointer;}#mermaid-svg-6hTXxcQ9XubYoAaA .arrowheadPath{fill:#333333;}#mermaid-svg-6hTXxcQ9XubYoAaA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6hTXxcQ9XubYoAaA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6hTXxcQ9XubYoAaA .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-6hTXxcQ9XubYoAaA .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-6hTXxcQ9XubYoAaA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6hTXxcQ9XubYoAaA .cluster text{fill:#333;}#mermaid-svg-6hTXxcQ9XubYoAaA .cluster span{color:#333;}#mermaid-svg-6hTXxcQ9XubYoAaA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6hTXxcQ9XubYoAaA :root{–mermaid-font-family:”trebuchet ms”,verdana,arial,sans-serif;} mm_camera_open open mm_camera_module_open_session mct_shimlayer_start_session mct_controller_new mct_pipeline_new mct_pipeline_start_session mct_pipeline_get_module_num mct_pipeline_modules_start sensor start_session iface isp stats pproc imglib