CAMERA学习(一)-------跟踪应用层到HAL

眉间皱痕 提交于 2019-12-04 21:54:29

    publicstatic Camera mCameraDevice;

try {

         Log.d(TAG,"open camera 0");

         //writeFile(APK_FILE_PATH,1);

         Log.d("qyh","opencamera"+System.currentTimeMillis());

         mCameraDevice = Camera.open(0);/*打开camera,获取camera实例给mCameraDevice */

         Log.d("qyh","sendMessage"+System.currentTimeMillis());

         mHandler.sendEmptyMessageDelayed(DISMISS_ALL,500);

         }catch (Exception e) {

         Log.e(TAG,"open camera error");

         //writeFile(APK_FILE_PATH,0);

         e.printStackTrace();

         return;

         }

         try{

         mCameraDevice.setPreviewDisplay(holder);/*这个应该是数据的显示部分,待分析*/

         }catch (Exception e) {

         e.printStackTrace();

         }

 

         Camera.Parameters parameters = mCameraDevice.getParameters();/*获取驱动的相关参数*/

         parameters.setPreviewSize(800, 600);/*重新设置预览的分辨率*/

         mCameraDevice.setParameters(parameters);/*设置相关参数*/

         mCameraDevice.startPreview();/*开始进入预览模式*/

 

以上是应用APP中打开camera的简要步骤,下面我们就对mCameraDevice = Camera.open(0);进行具体的跟进下:

 

STEP 1:

\frameworks\base\core\java\android\hardware\Camera.java

   public static Camera open(int cameraId) {

       if (!isPermissionGranted()) {

           return null;

       }

       returnnewCamera(cameraId);

}

 

STEP 2:

\frameworks\base\core\java\android\hardware\Camera.java

 

    /** used by Camera#open, Camera#open(int)*/

    Camera(int cameraId) {

        int err = cameraInitNormal(cameraId);

        if (checkInitErrors(err)) {

            switch(err) {

                case EACCESS:

                    throw newRuntimeException("Fail to connect to camera service");

                case ENODEV:

                    throw newRuntimeException("Camera initialization failed");

                default:

                    // Should never hit this.

                    throw newRuntimeException("Unknown camera error");

            }

        }

    }

 

STEP 3:

    private int cameraInitNormal(int cameraId){

      return cameraInitVersion(cameraId,CAMERA_HAL_API_VERSION_NORMAL_CONNECT);

    }

/*

CAMERA_HAL_API_VERSION_NORMAL_CONNECT参数的定义

private static final int CAMERA_HAL_API_VERSION_NORMAL_CONNECT= -2;

*/

STEP 4:

    private int cameraInitVersion(int cameraId,int halVersion) {

        mShutterCallback = null;

        mRawImageCallback = null;

        mJpegCallback = null;

        mPreviewCallback = null;

        mPreviewRawDumpCallback = 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 = newEventHandler(this, looper);

        } else {

            mEventHandler = null;

        }

 

        return native_setup(newWeakReference<Camera>(this), cameraId, halVersion,

               ActivityThread.currentOpPackageName());

    }

/*

    private native final int native_setup(Object camera_this, int cameraId,int halVersion,

                                          String packageName);

 

native_setup是一个本地的方法,对应的JNI在下面步骤中。

*/

STEP 5:

\frameworks\base\core\jni\android_hardware_Camera.cpp

 

// connect tocamera service

static jint android_hardware_Camera_native_setup(JNIEnv *env,jobject thiz,

    jobject weak_this, jint cameraId, jinthalVersion, jstring clientPackageName)

{

    // Convert jstring to String16

    const 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) {

        // Default path: hal version is don'tcare, do normal camera connect.

        camera = Camera::connect(cameraId,clientName,

               Camera::USE_CALLING_UID);/*这里的 Camera 为本地的类,在下面步骤的Camera.cpp中,而不是前面用到的Camera.java中的类。*/

    } else {

        jint status =Camera::connectLegacy(cameraId, halVersion, clientName,

                Camera::USE_CALLING_UID,camera);

        if (status != NO_ERROR) {

            return status;

        }

    }

 

    if (camera == NULL) {

        return -EACCES;

    }

 

    // make sure camera hardware is alive

    if (camera->getStatus() != NO_ERROR) {

        return NO_INIT;

    }

 

    jclass clazz =env->GetObjectClass(thiz);

    if (clazz == NULL) {

        // This should never happen

        jniThrowRuntimeException(env,"Can't find android/hardware/Camera");

        return INVALID_OPERATION;

    }

 

    // We use a weak reference so the Cameraobject can be garbage collected.

    // The reference is only used as a proxyfor callbacks.

    //!++

    #if 0 // Use MTK JNI for MTK camerafeature.

    sp<JNICameraContext> context = newJNICameraContext(env, weak_this, clazz, camera);

    #else

    sp<JNICameraContext> context = new MtkJNICameraContext(env,weak_this, clazz, camera);

    #endif

    //!--

   context->incStrong((void*)android_hardware_Camera_native_setup);

    camera->setListener(context);

 

    // save context in opaque field

    env->SetLongField(thiz, fields.context,(jlong)context.get());

    return NO_ERROR;

}

 

STEP 6:

\frameworks\av\camera\Camera.cpp

sp<Camera>Camera::connect(int cameraId, const String16& clientPackageName,

        int clientUid)

{

    return CameraBaseT::connect(cameraId,clientPackageName, clientUid);

}

/*

CameraBaseT在/frameworks/av/include/camera/CameraBase.h中有定义如下:

    typedefCameraBase<TCam>        CameraBaseT

所以就是调用的CameraBase类的connect了。

*/

 

STEP 7:

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

    constsp<ICameraService>& cs = getCameraService();/*获取cameraService,这个在开机的时候已经注册过的一个camera服务: media.camera */

 

    if (cs != 0) {

        TCamConnectService fnConnectService =TCamTraits::fnConnectService;

        status =(cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,

                                            /*out*/ c->mCamera);

/*

这个对应的就是CameraService::connect;这里面的具体转换过程还不太清楚。待后续学习。Cs.get()是什么意思?CameraService 中没有找到get这个函数。

fnConnectService的定义在:\frameworks\av\camera\ Camera.cpp

CameraTraits<Camera>::TCamConnectServiceCameraTraits<Camera>::fnConnectService =

       &ICameraService::connect;

*/

    }

    if (status == OK && c->mCamera!= 0) {

       IInterface::asBinder(c->mCamera)->linkToDeath(c);

        c->mStatus = NO_ERROR;

    } else {

        ALOGW("An error occurred whileconnecting to camera: %d", cameraId);

        c.clear();

    }

    return c;

}

 

STEP 8:

\frameworks\av\services\camera\libcameraservice\CameraService.cpp

status_tCameraService::connect(

        const sp<ICameraClient>&cameraClient,

        int cameraId,

        const String16& clientPackageName,

        int clientUid,

        /*out*/

        sp<ICamera>& device) {

 

    status_t ret = NO_ERROR;

    String8 id =String8::format("%d", cameraId);

    sp<Client> client = nullptr;

    ret =connectHelper<ICameraClient,Client>(cameraClient, id,CAMERA_HAL_API_VERSION_UNSPECIFIED,

           clientPackageName, clientUid, API_1, false, false, /*out*/client);

 

    if(ret != NO_ERROR) {

        logRejected(id, getCallingPid(),String8(clientPackageName),

                String8::format("%s(%d)", strerror(-ret), ret));

        return ret;

    }

 

    device = client;

    return NO_ERROR;

}

 

STEP 9:

\frameworks\av\services\camera\libcameraservice\CameraService.h

 

template<classCALLBACK, class CLIENT>

status_t CameraService::connectHelper(constsp<CALLBACK>& cameraCb, const String8& cameraId,

        int halVersion, const String16&clientPackageName, int clientUid,

        apiLevel effectiveApiLevel, boollegacyMode, bool shimUpdateOnly,

        /*out*/sp<CLIENT>& device) {

    status_t ret = NO_ERROR;

    String8 clientName8(clientPackageName);

    int clientPid = getCallingPid();

 

    ALOGI("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;

    {

        // Acquire mServiceLock and preventother clients from connecting

        std::unique_ptr<AutoConditionLock>lock =

               AutoConditionLock::waitAndAcquire(mServiceLockWrapper,DEFAULT_CONNECT_TIMEOUT_NS);

 

        if (lock == nullptr) {

            ALOGE("CameraService::connectX (PID %d) rejected (too many other clients connecting)."

                    , clientPid);

            return -EBUSY;

        }

 

        // Enforce client permissions and dobasic sanity checks

        if((ret =validateConnectLocked(cameraId, /*inout*/clientUid)) != NO_ERROR) {

            return ret;

        }

 

        // Check the shim parameters afteracquiring lock, if they have already been updated and

        // we were doing a shim update, returnimmediately

        if (shimUpdateOnly) {

            auto cameraState =getCameraState(cameraId);

            if (cameraState != nullptr) {

                if(!cameraState->getShimParams().isEmpty()) return NO_ERROR;

            }

        }

 

        sp<BasicClient> clientTmp =nullptr;

       std::shared_ptr<resource_policy::ClientDescriptor<String8,sp<BasicClient>>> partial;

        if ((ret =handleEvictionsLocked(cameraId, clientPid, effectiveApiLevel,

                IInterface::asBinder(cameraCb),clientName8, /*out*/&clientTmp,

                /*out*/&partial)) !=NO_ERROR) {

            return ret;

        }

 

        if (clientTmp.get() != nullptr) {

            // Handle special case for API1MediaRecorder where the existing client is returned

            device =static_cast<CLIENT*>(clientTmp.get());

            return NO_ERROR;

        }

 

        // give flashlight a chance to closedevices if necessary.

       mFlashlight->prepareDeviceOpen(cameraId);

 

        // TODO: Update getDeviceVersion + HALinterface to use strings for Camera IDs

        int id = cameraIdToInt(cameraId);

        if (id == -1) {

            ALOGE("%s: Invalid camera ID%s, cannot get device version from HAL.", __FUNCTION__,

                    cameraId.string());

            return BAD_VALUE;

        }

 

        int facing = -1;

        int deviceVersion =getDeviceVersion(id, /*out*/&facing);

        sp<BasicClient> tmp = nullptr;

        if((ret =makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,

               clientUid, getpid(), legacyMode, halVersion, deviceVersion,effectiveApiLevel,

               /*out*/&tmp)) != NO_ERROR) {

            return ret;

        }

/*

上面的makeClient创建的只是cameraservice内部类client,而不是客户端。主要从打印中可以看到,是先创建cameraservice的内部clinet然后再创建的客户端clinet的。具体过程带分析。

01-02 00:27:12.751  181   448 D CameraService:[CameraService::loadSound] + tid:448 mSoundLock - ref=0

01-02 00:27:12.751  181   448 D CameraService:CameraService::loadSound ref=0

01-02 00:27:12.751  638   660 V DisplayEventReceiver:call nativeScheduleVsync mReceiverPtr = -1606054400

01-02 00:27:12.752  181   448 D CameraService:Client::Client X (pid 4232, id 0)

01-02 00:27:12.752  181   448 D CameraClient:CameraClient::CameraClient E (pid 4232, id 0)

01-02 00:27:12.752  181   448 D CameraClient:CameraClient::CameraClient X (pid 4232, id 0)

01-02 00:27:12.752  181   448 D CameraClient:CameraClient::initialize E (pid 4232, id 0)

*/

        client =static_cast<CLIENT*>(tmp.get());

/*

Client则为客户端,具体的实现带分析。Tmp.get()不知道什么意思?

*/

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

                __FUNCTION__);

 

        if ((ret =client->initialize(mModule)) != OK) {/*客户端初始化*/

/*

这里的mModule就是开机初始化cameraservice实例的时候获取的

    mModule = newCameraModule(rawModule);

   ALOGI("Loaded \"%s\" camera module",mModule->getModuleName());

    err =mModule->init();

    if (err != OK){

       ALOGE("Could not initialize camera HAL module: %d (%s)", err,

           strerror(-err));

       logServiceError("Could not initialize camera HAL module",err);

 

       mNumberOfCameras = 0;

        deletemModule;

        mModule =nullptr;

        return;

    }

*/

            ALOGE("%s: Could notinitialize client from HAL module.", __FUNCTION__);

            return ret;

        }

 

        //!++ The part is merged by MTK, googlewill merge in MR1

        /*

        sp<IBinder> remoteCallback =client->getRemote();

        if (remoteCallback != nullptr) {

            remoteCallback->linkToDeath(this);

        }

        */

        //!--

 

        // Update shim paremeters for legacyclients

        if (effectiveApiLevel == API_1) {

            // Assume we have always received aClient subclass for API1

            sp<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 updateshim parameters for camera %s, no such device exists.",

                        __FUNCTION__,cameraId.string());

            }

        }

 

        if (shimUpdateOnly) {

            // If only updating legacy shimparameters, immediately disconnect client

            mServiceLock.unlock();

            client->disconnect();

            mServiceLock.lock();

        } else {

            // Otherwise, add client to activeclients list

            finishConnectLocked(client,partial);

        }

    } // lock is destroyed, allow furtherconnect calls

 

    // Important: release the mutex here so theclient can call back into the service from its

    // destructor (can be at the end of thecall)

    device = client;

    return NO_ERROR;

}

 

STEP 10:

\frameworks\av\services\camera\libcameraservice\api1\CameraClient.cpp

status_tCameraClient::initialize(CameraModule *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);

 

    mHardware = newCameraHardwareInterface(camera_device_name);

/*

mHardware 定义是 CameraHardwareInterface,他也是Android的通用接口。各个厂家提供的功能都要通过CameraHardwareInterface适配向CameraService提供硬件操作接口。

*/

    res = mHardware->initialize(module);

    if (res != OK) {

        ALOGE("%s: Camera %d: unable toinitialize device: %s (%d)",

                __FUNCTION__, mCameraId,strerror(-res), res);

        mHardware.clear();

        return res;

    }

 

    //!++

    // mtk callback

    mHardware->setMtkCallbacks(

            mtkMetadataCallback,

            (void *)(uintptr_t)mCameraId);

    //!--

 

    mHardware->setCallbacks(notifyCallback,

            dataCallback,

            dataCallbackTimestamp,

            (void *)(uintptr_t)mCameraId);

 

    // Enable zoom, error, focus, and metadatamessages by default

    enableMsgType(CAMERA_MSG_ERROR |CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |

                  CAMERA_MSG_PREVIEW_METADATA |CAMERA_MSG_FOCUS_MOVE);

 

    //!++

    enableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY |MTK_CAMERA_MSG_EXT_DATA); // Enable MTK-extended messages by default

    //!--

 

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

    return OK;

}

 

STEP 10:

 

\frameworks\av\services\camera\libcameraservice\device1\CameraHardwareInterface.h

 

   status_t initialize(CameraModule *module)

    {

        ALOGI("Opening camera %s",mName.string());

        camera_info info;

        status_t res = module->getCameraInfo(atoi(mName.string()),&info);

        if (res != OK) return res;

 

        int rc = OK;

        if (module->getModuleApiVersion()>= CAMERA_MODULE_API_VERSION_2_3 &&

            info.device_version >CAMERA_DEVICE_API_VERSION_1_0) {

            // Open higher version cameradevice as HAL1.0 device.

            rc =module->openLegacy(mName.string(),

                                     CAMERA_DEVICE_API_VERSION_1_0,

                                    (hw_device_t **)&mDevice);

        } else {

            rc =module->open(mName.string(), (hw_device_t **)&mDevice);

        }

        if (rc != OK) {

            ALOGE("Could not open camera%s: %d", mName.string(), rc);

            return rc;

        }

        initHalPreviewWindow();

        return rc;

    }

 

/*

module->open这里的module就是\frameworks\av\services\camera\libcameraservice\CameraService.cpp中的onFirstRef在启动该服务的时候就创建好了,而cameraserver是在开机的时候就servicemanager中启动的。

 

void CameraService::onFirstRef()

{

   ALOGI("CameraService process starting");

 

   BnCameraService::onFirstRef();

 

    // Updatebattery life tracking if service is restarting

   BatteryNotifier& notifier(BatteryNotifier::getInstance());

    notifier.noteResetCamera();

   notifier.noteResetFlashlight();

 

    camera_module_t*rawModule;

    int err= hw_get_module(CAMERA_HARDWARE_MODULE_ID,

            (consthw_module_t **)&rawModule);

/*

这里的hw_get_module获取的就是CAMERA_HARDWARE_MODULE_ID对应的库文档,对应我们现在分析平台就是camera.mt8127.so,mt8127对应的是MTK的芯片平台。

*/

    if (err < 0){

       ALOGE("Could not load camera HAL module: %d (%s)", err,strerror(-err));

       logServiceError("Could not load camera HAL module", err);

       mNumberOfCameras = 0;

        return;

    }

 

    mModule = newCameraModule(rawModule);

   ALOGI("Loaded \"%s\" camera module",mModule->getModuleName());

    err =mModule->init();

    if (err != OK){

       ALOGE("Could not initialize camera HAL module: %d (%s)", err,

           strerror(-err));

       logServiceError("Could not initialize camera HAL module",err);

 

       mNumberOfCameras = 0;

        deletemModule;

        mModule =nullptr;

        return;

    }

 

   mNumberOfCameras = mModule->getNumberOfCameras();

   mNumberOfNormalCameras = mNumberOfCameras;

……

 

 

*/

 

HAL层就是camera.mt8127.so具体的实现,就是MTK做的一些接口。对于\frameworks\av\services\camera\libcameraservice\device1\CameraHardwareInterface.h具体的实现。所以后面一篇文章中,我们再单独的学习CAMERA 的 HAL.

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!