1. 程式人生 > >淺析Android Camera架構

淺析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

    
}

相關推薦

淺析Android Camera架構

本博文是基於Android 4.4講解   1、application 層:                當我們Android工程師想開啟camera時通常直接呼叫Camera.java中的  Camer.open(cameraId)靜態函式              

淺析Android Camera開發中的三個尺寸和三種變形 貢獻一個自適配Picturesize和Previewsiz

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android Camera架構分層及程式碼結構(MTK version)

Android的Camera包含取景器(viewfinder)和拍攝照片(takepicture)的功能。目前MTKAndroid Camera程式的架構分成客戶端和伺服器兩個部分,它們建立在Android的程序間通訊Binder的結構上。Camera模組同樣遵循Andro

Qualcomm Android camera 架構簡析及如何debug

              Qualcomm Android camera 架構簡析及如何debug 一. Camera模組(CCM)介紹: CCM一般包含四大件: 鏡頭(lens)、感測器(sensor)、軟板(FPC)、影象處理晶片(DSP):   C

Android Camera架構

Android 的相機硬體抽象層 (HAL) 可將 Camera 2 中較高級別的相機框架 API 連線到底層的相機驅動程式和硬體

Android Camera 系統架構原始碼分析(4)---->Camera的資料來源及Camera的管理

Camera的資料來源及Camera的管理  我們接著第3篇,再返回Cam1DeviceBase::startPreview()的(4) mpCamAdapter->startPreview()。在講(4)前我們先來看看(1)onStartPreview(

Android Camera API2.0下全新的Camera FW/HAL架構簡述

本文均屬自己閱讀原始碼的點滴總結,轉賬請註明出處謝謝。歡迎和大家交流。qq:1037701636 email:Software:系統原始碼Android5.1前沿:        前面博文大多少總結的是Camera HAL1到HAL3的系統架構,但這些架構對於Camera A

Android 7.0 Camera架構原始碼分析

Android 7.0之前CameraService是在mediaserver程序中註冊的,看下Android 6.0的程式碼: //path: frameworks\av\media\mediaserver\main_mediaserver.cpp int m

Android Camera Subsystem 架構(Binder機制)及顯示分析(3)

Camera Display 對於AP層使用者,通過Camera介面, 以最直觀的方式能夠從Camera顯示視窗中看到的Camera Display主要包括三部分。各部分的具體細節如下所示。 (1)Camera Preview Display 對於Camera Pre

Android Camera 系統架構原始碼分析(2)---->Camera的startPreview和setPreviewCallback

Camera startPreview流程 上接第一篇,這個過程的主要任務是,如何讀取資料的,讀取的資料是什麼格式,最好能知道是如何去預覽的 上層APP呼叫的是Camera.java的startPreview();,下面列出startPreview的呼叫流程 //Camera

Android Camera HAL淺析

  1、Camera成像原理介紹 Camera工作流程圖     &

android app 架構設計01

clas -h tab size data 資源 top post 樣式 1:本文有摘抄, 1 2 3 4 5 - 開發過程中。需求、設計、編碼的一致性 - 整個程序具有統一的風格,比方對話框樣式,button風格,色調等UI元素 - 整個程序詳細統一的結

玩轉Android Camera開發(二):使用TextureView和SurfaceTexture預覽Camera 基礎拍照demo

處理 pict all sans 格式 facet ace ets nth Google自Android4.0出了TextureView。為什麽推出呢?就是為了彌補Surfaceview的不足。另外一方面也是為了平衡GlSurfaceView。當然這是本人揣度的。關於Te

Android Camera 通過V4L2與kernel driver的完整交互過程

initial length 詳細 eas handler use orien amp com http://blog.chinaunix.net/uid-26215986-id-3552456.html 原文地址:Android Camera 通過V4L2與kernel

溫故而知新---淺析三層架構(一個超簡單的系統登錄三層架構實例)

lda code windows comm 面向 box reader 業務 兩個 剛開始接觸三層架構是在快兩個月前,那時候找了好多例子感覺也都看不怎麽懂,今天閑著沒事,就把以前學的東西翻出來,算是溫習溫習。由於本人也接觸時間不長,所以以下言論有不正確之處,多多

Android 程序架構: MVC、MVP、MVVM、Unidirectional、Clean...

不同 概念 可能 十年 tin gettext 聲明 數據 content 摘選自:GUI 應用程序架構的十年變遷:MVC、MVP、MVVM、Unidirectional、Cleanhttps://zhuanlan.zhihu.com/p/26799645 MV

Android Camera

ubi 驅動 fim andro cmm roi target 工作原理 camera android camera(一):camera模組CMM介紹 android camera(二):攝像頭工作原理、s5PV310 攝像頭接口(CAMIF) android came

android camera之nv21旋轉

現象 rtx 不可 行數據 灰度 upa sfc max ide 這周做的一個android的camera開發,需要獲取到視頻幀數據,並且需要是nv21格式的byte數組,並且視頻幀的圖像需要是正方向的。和android相機打過交道的都清楚,android的camera獲取

【轉】Android Camera 相機開發詳解

exc troy start 當前 container rac google getconf 對比度 在Android 5.0(SDK 21)中,Google使用Camera2替代了Camera接口。Camera2在接口和架構上做了巨大的變動, 但是基於眾所周知的原因

Android Camera fw學習(四)-recording流程分析

應用開發 facet internal server 中一 sca med erase 流程分析 Android Camera fw學習(四)-recording流程分析 備註:備註:本文是Android5.1學習筆記。博文按照軟件啟動流程分析。   且行且惜,一步一個腳印