淺析Android Camera架構

本博文是基於Android 4.4講解

  1、application 層:

               當我們Android工程師想打開camera時通常直接調用Camera.java中的  Camer.open(cameraId)靜態函數

                camera.java 位於 frameworks/base/core/java/android/hardware目錄下

                //以下是部分代碼

               

 public static Camera open(int cameraId) {
        return new Camera(cameraId);
    }
</pre><pre code_snippet_id="1846209" snippet_file_name="blog_20160823_3_8904287" name="code" class="html"><pre name="code" class="html">Camera(int cameraId) {
        mShutterCallback = null;
        mRawImageCallback = null;
        mJpegCallback = null;
        mPreviewCallback = null;
        mPostviewCallback = null;
        mUsingPreviewAllocation = false;
        mZoomListener = null;

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

        String packageName = ActivityThread.currentPackageName();

        <span style="color:#ff0000;">native_setup(new WeakReference<Camera>(this), cameraId, packageName);</span>
    }



      其中native_setup接口是native接口其函數聲明如下

            

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

       2、jni層

             在camera.java中會調用到native_setup函數,此jni接口定義在  frameworks/base/core/jni下面的android_hardware_Camera.cpp中

             

// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId, jstring clientPackageName)
{
    // Convert jstring to String16
    const char16_t *rawClientName = env->GetStringChars(clientPackageName, NULL);
    jsize rawClientNameLen = env->GetStringLength(clientPackageName);
    String16 clientName(rawClientName, rawClientNameLen);
    env->ReleaseStringChars(clientPackageName, rawClientName);

   <span style="color:#ff0000;"> sp<Camera> camera = Camera::connect(cameraId, clientName,
            Camera::USE_CALLING_UID);
</span>
    if (camera == NULL) {
        jniThrowRuntimeException(env, "Fail to connect to camera service");
        return;
    }

    // make sure camera hardware is alive
    if (camera->getStatus() != NO_ERROR) {
        jniThrowRuntimeException(env, "Camera initialization failed");
        return;
    }

    jclass clazz = env->GetObjectClass(thiz);
    if (clazz == NULL) {
        jniThrowRuntimeException(env, "Can't find android/hardware/Camera");
        return;
    }

    // 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);

    // save context in opaque field
    env->SetIntField(thiz, fields.context, (int)context.get());
}
其中上面會調Camera::connect接口此類是frameworks/av/camera/Camera.cpp

sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
        int clientUid)
{
    return <span style="color:#ff0000;">CameraBaseT::connect</span>(cameraId, clientPackageName, clientUid);//調用了父類的connect接口
}
frameworks/av/camera/CameraBase.cpp

template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
                                               const String16& clientPackageName,
                                               int clientUid)
{
    ALOGV("%s: connect", __FUNCTION__);
    sp<TCam> c = new TCam(cameraId);
    sp<TCamCallbacks> cl = c;
    status_t status = NO_ERROR;
    <span style="color:#ff0000;">const sp<ICameraService>& cs = getCameraService();  //得到CameraService.cpp實例</span>

    if (cs != 0) {
       <span style="color:#ff0000;"> TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
                                             /*out*/ c->mCamera);                                   //此行最終會調用到CameraService.cpp中的connect接口</span>
    }
    if (status == OK && c->mCamera != 0) {
        c->mCamera->asBinder()->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        ALOGW("An error occurred while connecting to camera: %d", cameraId);
        c.clear();
    }
    return c;
}
frameworks/av/services/camera/libcameraservicw/CameraService.cpp

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

    String8 clientName8(clientPackageName);
    int callingPid = getCallingPid();

    LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
            clientName8.string(), cameraId);

    status_t status = validateConnect(cameraId, /*inout*/clientUid);
    if (status != OK) {
        return status;
    }


    sp<Client> client;
    {
        Mutex::Autolock lock(mServiceLock);
        sp<BasicClient> clientTmp;
        if (!canConnectUnsafe(cameraId, clientPackageName,
                              cameraClient->asBinder(),
                              /*out*/clientTmp)) {
            return -EBUSY;
        } else if (client.get() != NULL) {
            device = static_cast<Client*>(clientTmp.get());
            return OK;
        }

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

        // If there are other non-exclusive users of the camera,
        //  this will tear them down before we can reuse the camera
        if (isValidCameraId(cameraId)) {
            // transition from PRESENT -> NOT_AVAILABLE
            updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
                         cameraId);
        }

        switch(deviceVersion) {
          case CAMERA_DEVICE_API_VERSION_1_0:
            <span style="color:#ff0000;">client = new CameraClient(this, cameraClient,
                    clientPackageName, cameraId,
                    facing, callingPid, clientUid, getpid());    //我用的是camer1</span>
            break;
          case CAMERA_DEVICE_API_VERSION_2_0:
          case CAMERA_DEVICE_API_VERSION_2_1:
          case CAMERA_DEVICE_API_VERSION_3_0:
            client = new Camera2Client(this, cameraClient,
                    clientPackageName, cameraId,
                    facing, callingPid, clientUid, getpid(),
                    deviceVersion);
            break;
          case -1:
            ALOGE("Invalid camera id %d", cameraId);
            return BAD_VALUE;
          default:
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return INVALID_OPERATION;
        }

       <span style="color:#ff0000;"> status_t status = connectFinishUnsafe(client, client->getRemote()); //見下面定義</span>
        if (status != OK) {
            // this is probably not recoverable.. maybe the client can try again
            // OK: we can only get here if we were originally in PRESENT state
            updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
            return status;
        }

        mClient[cameraId] = client;
        LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
             getpid());
    }
    // 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 OK;
}

status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
                                            const sp<IBinder>& remoteCallback) {
   <span style="color:#ff0000;"> status_t status = client->initialize(mModule);   //其中  camera_module_t   *mModule爲一個結構體指針,此指針會在onFirstRef()接口中初始化見下面代碼</span>
    if (status != OK) {
        return status;
    }

    remoteCallback->linkToDeath(this);

    return OK;
}

//此接口會在CameraService實例化後調用,其中用到了sp機制,目前尚未研究通。

void CameraService::onFirstRef() 
{
    LOG1("CameraService::onFirstRef");

    BnCameraService::onFirstRef();

    if (<span style="color:#ff0000;">hw_get_module</span>(CAMERA_HARDWARE_MODULE_ID,//此句代碼是關鍵之處
                (const hw_module_t **)&mModule) < 0) {
        ALOGE("Could not load camera HAL module");
        mNumberOfCameras = 0;
    }
    else {
        ALOGI("Loaded \"%s\" camera module", mModule->common.name);
        mNumberOfCameras = mModule->get_number_of_cameras();
        if (mNumberOfCameras > MAX_CAMERAS) {
            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
                    mNumberOfCameras, MAX_CAMERAS);
            mNumberOfCameras = MAX_CAMERAS;
        }
        for (int i = 0; i < mNumberOfCameras; i++) {
            setCameraFree(i);
        }

        if (mModule->common.module_api_version >=
                CAMERA_MODULE_API_VERSION_2_1) {
            mModule->set_callbacks(this);
        }

        CameraDeviceFactory::registerService(this);
    }
}

hw_get_module位於Android源碼目錄下  hardware/libhardware/Hardware.c
int hw_get_module(const char *id, const struct hw_module_t **module)
{
    return hw_get_module_by_class(id, NULL, module);
}
//此函數會加載動態庫
"/system/lib/hw"下面有名字爲class_id的動態庫
int hw_get_module_by_class(const char *class_id, const char *inst,
                           const struct hw_module_t **module)
{
    int status;
    int i;
    const struct hw_module_t *hmi = NULL;
    char prop[PATH_MAX];
    char path[PATH_MAX];
    char name[PATH_MAX];

    if (inst)
        snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
    else
        strlcpy(name, class_id, PATH_MAX);

    /*
     * Here we rely on the fact that calling dlopen multiple times on
     * the same .so will simply increment a refcount (and not load
     * a new copy of the library).
     * We also assume that dlopen() is thread-safe.
     */

    /* Loop through the configuration variants looking for a module */
    for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
        if (i < HAL_VARIANT_KEYS_COUNT) {
            if (property_get(variant_keys[i], prop, NULL) == 0) {
                continue;
            }
            snprintf(path, sizeof(path), "%s/%s.%s.so",
                     HAL_LIBRARY_PATH2, name, prop);    //         PATH2: "/vendor/lib/hw"
            if (access(path, R_OK) == 0) break; 

            snprintf(path, sizeof(path), "%s/%s.%s.so",
                     HAL_LIBRARY_PATH1, name, prop);   //PATH1: "/system/lib/hw"
            if (access(path, R_OK) == 0) break;
        } else {
            snprintf(path, sizeof(path), "%s/%s.default.so",
                     HAL_LIBRARY_PATH2, name);
            if (access(path, R_OK) == 0) break;

            snprintf(path, sizeof(path), "%s/%s.default.so",
                     HAL_LIBRARY_PATH1, name);
            if (access(path, R_OK) == 0) break;
        }
    }

    status = -ENOENT;
    if (i < HAL_VARIANT_KEYS_COUNT+1) {
        /* load the module, if this fails, we're doomed, and we should not try
         * to load a different variant. */
        status = load(class_id, path, module);
    }

    return status;
}

<span style="color:#ff0000;">//</span>
static int load(const char *id,
        const char *path,
        const struct hw_module_t **pHmi)
{
    int status;
    void *handle;
    struct hw_module_t *hmi;

    /*
     * load the symbols resolving undefined symbols before
     * dlopen returns. Since RTLD_GLOBAL is not or'd in with
     * RTLD_NOW the external symbols will not be global
     */
    handle = dlopen(path, RTLD_NOW);
    if (handle == NULL) {
        char const *err_str = dlerror();
        ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
        status = -EINVAL;
        goto done;
    }

    /* Get the address of the struct hal_module_info. */
    const char *sym = HAL_MODULE_INFO_SYM_AS_STR;   //HAL_MODULE_INFO_SYM_AS_STR 爲 "HMI"
    <span style="color:#ff0000;">//dlsym根據sym去實例化hmi,其中Camera_Moduel.cpp下有"HMI"名字的camera_module_t變量,見下面代碼</span>
    hmi = (struct hw_module_t *)dlsym(handle, sym);
    if (hmi == NULL) {
        ALOGE("load: couldn't find symbol %s", sym);
        status = -EINVAL;
        goto done;
    }

    /* Check that the id matches */
    if (strcmp(id, hmi->id) != 0) {
        ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);
        status = -EINVAL;
        goto done;
    }

    hmi->dso = handle;

    /* success */
    status = 0;

    done:
    if (status != 0) {
        hmi = NULL;
        if (handle != NULL) {
            dlclose(handle);
            handle = NULL;
        }
    } else {
        ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
                id, path, *pHmi, handle);
    }

    *pHmi = hmi;

    return status;
}

CameraHal_Module.cpp   //此類位於hardware/rk29/camera/camerahal目錄下,這是我的源代碼camera模塊

camera_module_t HAL_MODULE_INFO_SYM = {
    common: {
         tag: HARDWARE_MODULE_TAG,
         version_major: ((CONFIG_CAMERAHAL_VERSION&0xff00)>>8),
         version_minor: CONFIG_CAMERAHAL_VERSION&0xff,
         id: CAMERA_HARDWARE_MODULE_ID,
         name: CAMERA_MODULE_NAME,
         author: "RockChip",
         <span style="color:#ff0000;">methods: &camera_module_methods,</span>
         dso: NULL, /* remove compilation warnings */
         reserved: {0}, /* remove compilation warnings */
    },
    get_number_of_cameras: camera_get_number_of_cameras,
    get_camera_info: camera_get_camera_info,
    set_callbacks:NULL,
    get_vendor_tag_ops:NULL,
    reserved: {0}
};

到此frameworks/av/services/camera/libcameraservicw/CameraService.cpp下的mModule實例化完成

我們在進入到CameraClient.cpp(frameworks/av/services/camera/libcameraservice/api1)中(上面的CameraService.cpp實例化了CameraClient並且調用了它內部的initialize(camera_module_t *module)接口)

status_t CameraClient::initialize(camera_module_t *module) {
    int callingPid = getCallingPid();
    status_t res;

    LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);

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

    char camera_device_name[10];
    snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);

    <span style="color:#ff0000;">mHardware = new CameraHardwareInterface(camera_device_name);</span>
    res = mHardware->initialize(&module->common);
    if (res != OK) {
        ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
                __FUNCTION__, mCameraId, strerror(-res), res);
        mHardware.clear();
        return NO_INIT;
    }

    mHardware->setCallbacks(notifyCallback,
            dataCallback,
            dataCallbackTimestamp,
            (void *)mCameraId);

    // Enable zoom, error, focus, and metadata messages by default
    enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
                  CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);

    LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);
    return OK;
}

CameraHardwareInterface.h位於 frameworks/av/services/camera/libcameraservice/device1

 status_t initialize(hw_module_t *module)
    {
        ALOGI("Opening camera %s", mName.string());
        <span style="color:#ff0000;">int rc = module->methods->open(module, mName.string(),
                                       (hw_device_t **)&mDevice);  //調用了上面CameraHal_Module.cpp下的</span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">camera_module_t HAL_MODULE_INFO_SYM的open函數</span><span style="color:#ff0000;">,此函數定義見下面代碼</span>
        if (rc != OK) {
            ALOGE("Could not open camera %s: %d", mName.string(), rc);
            return rc;
        }
        initHalPreviewWindow();
        return rc;
    }


static struct hw_module_methods_t camera_module_methods = {
        open: camera_device_open
};
int camera_device_open(const hw_module_t* module, const char* name,
                hw_device_t** device)
{
    int rv = 0;
    int cameraid;
    rk_camera_device_t* camera_device = NULL;
    camera_device_ops_t* camera_ops = NULL;
    android::CameraHal* camera = NULL;

    android::Mutex::Autolock lock(gCameraHalDeviceLock);

    LOGI("camera_device open");

    if (name != NULL) {
        cameraid = atoi(name);

        if(cameraid > gCamerasNumber) {
            LOGE("camera service provided cameraid out of bounds, "
                    "cameraid = %d, num supported = %d",
                    cameraid, gCamerasNumber);
            rv = -EINVAL;
            goto fail;
        }

        if(gCamerasOpen >= CAMERAS_SUPPORTED_SIMUL_MAX) {
            LOGE("maximum number(%d) of cameras already open",gCamerasOpen);
            rv = -ENOMEM;
            goto fail;
        }

        camera_device = (rk_camera_device_t*)malloc(sizeof(*camera_device));
        if(!camera_device) {
            LOGE("camera_device allocation fail");
            rv = -ENOMEM;
            goto fail;
        }

        camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));
        if(!camera_ops) {
            LOGE("camera_ops allocation fail");
            rv = -ENOMEM;
            goto fail;
        }

        memset(camera_device, 0, sizeof(*camera_device));
        memset(camera_ops, 0, sizeof(*camera_ops));

        camera_device->base.common.tag = HARDWARE_DEVICE_TAG;
        camera_device->base.common.version = 0;
        camera_device->base.common.module = (hw_module_t *)(module);
        camera_device->base.common.close = camera_device_close;
        camera_device->base.ops = camera_ops;

        camera_ops->set_preview_window = camera_set_preview_window;
        camera_ops->set_callbacks = camera_set_callbacks;
        camera_ops->enable_msg_type = camera_enable_msg_type;
        camera_ops->disable_msg_type = camera_disable_msg_type;
        camera_ops->msg_type_enabled = camera_msg_type_enabled;
        camera_ops->start_preview = camera_start_preview;
        camera_ops->stop_preview = camera_stop_preview;
        camera_ops->preview_enabled = camera_preview_enabled;
        camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;
        camera_ops->start_recording = camera_start_recording;
        camera_ops->stop_recording = camera_stop_recording;
        camera_ops->recording_enabled = camera_recording_enabled;
        camera_ops->release_recording_frame = camera_release_recording_frame;
        camera_ops->auto_focus = camera_auto_focus;
        camera_ops->cancel_auto_focus = camera_cancel_auto_focus;
        camera_ops->take_picture = camera_take_picture;
        camera_ops->cancel_picture = camera_cancel_picture;
        camera_ops->set_parameters = camera_set_parameters;
        camera_ops->get_parameters = camera_get_parameters;
        camera_ops->put_parameters = camera_put_parameters;
        camera_ops->send_command = camera_send_command;
        camera_ops->release = camera_release;
        camera_ops->dump = camera_dump;

        *device = &camera_device->base.common;

        // -------- RockChip specific stuff --------

        camera_device->cameraid = cameraid;
        
        <span style="color:#ff0000;">camera = new android::CameraHal(cameraid); //進入hal層</span>

        if(!camera) {
            LOGE("Couldn't create instance of CameraHal class");
            rv = -ENOMEM;
            goto fail;
        }

        gCameraHals[cameraid] = camera;
        gCamerasOpen++;
    }

    return rv;

fail:
    if(camera_device) {
        free(camera_device);
        camera_device = NULL;
    }
    if(camera_ops) {
        free(camera_ops);
        camera_ops = NULL;
    }
    if(camera) {
        delete camera;
        camera = NULL;
    }
    *device = NULL;
    return rv;
}


3、hal層

    hardware/rk29/camera/camerahal/CameraHal.cpp

     //以下會根據camera硬件分類uvc soc isp等,實例化成對應的adapter.cpp(數據適配器,此類會調用iotrl系統接口和驅動層進行通信)

CameraHal::CameraHal(int cameraId)
          :commandThreadCommandQ("commandCmdQ")
{
	LOG_FUNCTION_NAME
    
	{
        char trace_level[PROPERTY_VALUE_MAX];
        int level;

        property_get(CAMERAHAL_TRACE_LEVEL_PROPERTY_KEY, trace_level, "0");

        sscanf(trace_level,"%d",&level);
        
        setTracerLevel(level);

	}

    mCamId = cameraId;
    mCamFd = -1;
    mCommandRunning = -1;
	mCameraStatus = 0;

    #if (CONFIG_CAMERA_MEM == CAMERA_MEM_ION)
        mCamMemManager = new IonMemManager();
        LOG1("%s(%d): Camera Hal memory is alloced from ION device",__FUNCTION__,__LINE__);
	#elif(CONFIG_CAMERA_MEM == CAMERA_MEM_IONDMA)
        if((strcmp(gCamInfos[cameraId].driver,"uvcvideo") == 0) //uvc camera
            || (gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.type == CamSys_Phy_end)// soc cif
            ) {
            gCamInfos[cameraId].pcam_total_info->mIsIommuEnabled = (IOMMU_ENABLED == 1)? true:false;
        }
		mCamMemManager = new IonDmaMemManager(gCamInfos[cameraId].pcam_total_info->mIsIommuEnabled);
        LOG1("%s(%d): Camera Hal memory is alloced from ION device",__FUNCTION__,__LINE__);
    #elif(CONFIG_CAMERA_MEM == CAMERA_MEM_PMEM)
        if(access(CAMERA_PMEM_NAME, O_RDWR) < 0) {
            LOGE("%s(%d): %s isn't registered, CameraHal_Mem current configuration isn't support ION memory!!!",
                __FUNCTION__,__LINE__,CAMERA_PMEM_NAME);
        } else {
            mCamMemManager = new PmemManager((char*)CAMERA_PMEM_NAME);
            LOG1("%s(%d): Camera Hal memory is alloced from %s device",__FUNCTION__,__LINE__,CAMERA_PMEM_NAME);
        }
    #endif
    
    mPreviewBuf = new PreviewBufferProvider(mCamMemManager);
    mVideoBuf = new BufferProvider(mCamMemManager);
    mRawBuf = new BufferProvider(mCamMemManager);
    mJpegBuf = new BufferProvider(mCamMemManager);

    char value[PROPERTY_VALUE_MAX];
    property_get(/*CAMERAHAL_TYPE_PROPERTY_KEY*/"sys.cam_hal.type", value, "none");

    if (!strcmp(value, "fakecamera")) {
        LOGD("it is a fake camera!");
        mCameraAdapter = new CameraFakeAdapter(cameraId);
    } else {
	    if((strcmp(gCamInfos[cameraId].driver,"uvcvideo") == 0)) {
	        LOGD("it is a uvc camera!");
	        mCameraAdapter = new CameraUSBAdapter(cameraId);
	    }
	    else if(gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.type == CamSys_Phy_Cif){
	        LOGD("it is a isp soc camera");
	        if(gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.info.cif.fmt == CamSys_Fmt_Raw_10b)
	            mCameraAdapter = new CameraIspSOCAdapter(cameraId);
	        else
	            mCameraAdapter = new CameraIspAdapter(cameraId);
	    }
	    else if(gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.type == CamSys_Phy_Mipi){
	        LOGD("it is a isp  camera");
	        mCameraAdapter = new CameraIspAdapter(cameraId);
	    }
	    else{
	        LOGD("it is a soc camera!");
	        mCameraAdapter = new CameraSOCAdapter(cameraId);
	    }
    }
    
    //initialize    
    {
        char *call_process = getCallingProcess();
	    if(strstr(call_process,"com.android.cts.verifier")) {
            mCameraAdapter->setImageAllFov(true);
	    } else {
            mCameraAdapter->setImageAllFov(false);
	    }
    }

    mDisplayAdapter = new DisplayAdapter();
    mEventNotifier = new AppMsgNotifier(mCameraAdapter);
    
    mCameraAdapter->setEventNotifierRef(*mEventNotifier);
    mCameraAdapter->initialize();
    updateParameters(mParameters);
    mCameraAdapter->setPreviewBufProvider(mPreviewBuf);
    mCameraAdapter->setDisplayAdapterRef(*mDisplayAdapter);
    
    mDisplayAdapter->setFrameProvider(mCameraAdapter);
    
    mEventNotifier->setPictureRawBufProvider(mRawBuf);
    mEventNotifier->setPictureJpegBufProvider(mJpegBuf);
    mEventNotifier->setVideoBufProvider(mVideoBuf);
    mEventNotifier->setFrameProvider(mCameraAdapter);
    //command thread
    mCommandThread = new CommandThread(this);
	mCommandThread->run("CameraCmdThread", ANDROID_PRIORITY_URGENT_DISPLAY);

	bool dataCbFrontMirror;
	bool dataCbFrontFlip;
#if CONFIG_CAMERA_FRONT_MIRROR_MDATACB
    if (gCamInfos[cameraId].facing_info.facing == CAMERA_FACING_FRONT) {
#if CONFIG_CAMERA_FRONT_MIRROR_MDATACB_ALL
        dataCbFrontMirror = true;
#else
		const char* cameraCallProcess = getCallingProcess();
        if (strstr(CONFIG_CAMERA_FRONT_MIRROR_MDATACB_APK,cameraCallProcess)) {
            dataCbFrontMirror = true; 
        } else {
            dataCbFrontMirror = false;
        }
        if (strstr(CONFIG_CAMERA_FRONT_FLIP_MDATACB_APK,cameraCallProcess)) {
            dataCbFrontFlip = true; 
        } else {
            dataCbFrontFlip = false;
        }
#endif
    } else {
        dataCbFrontMirror = false;
        dataCbFrontFlip = false;
    }
#else
    dataCbFrontMirror = false;
#endif 
	mEventNotifier->setDatacbFrontMirrorFlipState(dataCbFrontMirror,dataCbFrontFlip);

      // register for sensor events
    mSensorListener = new SensorListener();
    if (mSensorListener.get()) {
        if (mSensorListener->initialize() == NO_ERROR) {
            mSensorListener->setCallbacks(gsensor_orientation_cb, this);
            mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION);
        } else {
            LOGE("Error initializing SensorListener. not fatal, continuing");
            mSensorListener.clear();
            mSensorListener = NULL;
        }
    }  

    
	LOG_FUNCTION_NAME_EXIT

    
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章