Camera启动篇一

主要记录一下启动的过程,顺便看看是否能把握到数据流的走向,这次以高通810平台Android5.1为蓝本。本篇主要讲述Framework及Hardware部分,涉及到JAVA及driver部分的如有必要也会捎带提及一下。

一、启动Camera在JAVA层开始,主要是启动了一个OpenCameraThread的线程(PhotoModule.java),代码如下:

1 if (mOpenCameraThread == null && !mActivity.mIsModuleSwitchInProgress) {
2             mOpenCameraThread = new OpenCameraThread();
3             mOpenCameraThread.start();
4         }

    在这个线程中只做了两件事情,整个Camera的启动过程也是围绕着他们展开的:

复制代码

1     private class OpenCameraThread extends Thread {
2         @Override
3         public void run() {
4             openCamera();      // 第一步开启camera
5             startPreview();    // 第二部开始preview
6         }
7     }

复制代码

二、开启第一步openCamera

1. 还是在Java层,openCamera主要干了下面这些事情:

        1.1 CameraUtility.openCamera  ------->重点部分

        1.2 getParameters    ------->一些参数获得

        1.3 initializeFocusManager   -------->Focus管理

        1.4 initializeCapabilities    -------->Camera选择的一些特性

        1.5 sendMSG--CAMERA_OPEN_DONE    -------->Open完成之后的处理

2. 上面那么多,我们只需要关注第一点就可以了,现在继续往下查看。关于这部分网上也有不少资料,可自行查看,直接查看源代码也比较清晰。总之在Camera开启成功后Java层会获得一个mCameraDevice,这个其实就是Camera的一个代理--AndroidCameraProxyImpl,当然我们要关注的是前面开启的过程。

复制代码

 1     public CameraManager.CameraProxy cameraOpen(
 2         Handler handler, int cameraId, CameraOpenErrorCallback callback) {
 3         mCameraHandler.obtainMessage(OPEN_CAMERA, cameraId, 0,
 4                 CameraOpenErrorCallbackForward.getNewInstance(
 5                         handler, callback)).sendToTarget();
 6         mCameraHandler.waitDone();
 7         if (mCamera != null) {
 8             return new AndroidCameraProxyImpl();  // ----->这个就是丢给前台的mCameraDevice
 9         } else {
10             return null;
11         }
12     }

复制代码

3. OPEN_CAMERA的处理先使用传统的方式开启,如果不行再尝试新的open方式,这里开始就转到frameworks。frameworks基本没做什么东西,就是一个传话筒而已,很快就到了JNI。

复制代码

 1         public void handleMessage(final Message msg) {
 2             try {
 3                 switch (msg.what) {
 4                     case OPEN_CAMERA:
 5                         try {
 6                             mCamera = android.hardware.Camera.openLegacy(msg.arg1,     // 这里的android.hardware.Camera就指向frameworks\base\core\java\android\hardware\camera.java
 7                                     android.hardware.Camera.CAMERA_HAL_API_VERSION_1_0);  // 先使用传统的接口打开
 8                         } catch (RuntimeException e) {
 9                             /* Retry with open if openLegacy fails */
10                             Log.v(TAG, "openLegacy failed. Using open instead");
11                             mCamera = android.hardware.Camera.open(msg.arg1); //若出现异常再使用新的接口打开,这里提供两种方式也是方便硬件厂商做兼容及区别处理,到现在的AndroidM版本,Camera HAL已经有了3个版本了,但高通810目前还是使用HAL1
12                         }

复制代码

4. openLegacy的JNI调用为native_setup。JNI调用将转到android_hardware_Camera.cpp文件,关于这部分网上也有很多资料。其实这里也没干什么事情,跟frameworks一样,都只是一个传递的作用,整个Camera框架真正有内涵的还是HAL以及driver部分,当然APP部分的各种呈现也很有内涵。

 1 return native_setup(new WeakReference(this), cameraId, halVersion, packageName); 

        这里通过JNI到了C++层

复制代码

 1 // connect to camera service
 2 static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
 3     jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
 4 {
    。。。。。。10     //ALOGV("native setup: halversion %d", halVersion);//native setup: halversion 256
11     sp camera;
12     if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {  //CAMERA_HAL_API_VERSION_NORMAL_CONNECT = -2
13         // Default path: hal version is don't care, do normal camera connect.
14         camera = Camera::connect(cameraId, clientName,
15                 Camera::USE_CALLING_UID);
16     } else {
17         jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
18                 Camera::USE_CALLING_UID, camera);
19         if (status != NO_ERROR) {
20             return status;
21         }

复制代码

       调用到Camera的connectLegacy

复制代码

 1 status_t Camera::connectLegacy(int cameraId, int halVersion,
 2         const String16& clientPackageName,
 3         int clientUid,
 4         sp& camera)    // 需返回的Camera设备
 5 {
 6     ALOGV("connectLegacy: connect legacy camera device,halVersion %d", halVersion);
 7     sp c = new Camera(cameraId);
 8     sp cl = c;      // 这个示例很重要,CameraService将包含此示例,用来执行回调调用到Client这边。
 9     status_t status = NO_ERROR;
10     const sp& cs = CameraBaseT::getCameraService();   // 获取CameraService
11 
12     if (cs != 0) {
13         status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,   // 调用CameraService的connectLegacy
14                                         clientUid, /*out*/c->mCamera);
15     }
16     if (status == OK && c->mCamera != 0) {
17         c->mCamera->asBinder()->linkToDeath(c);
18         c->mStatus = NO_ERROR;
19         camera = c;
20     } else {
21         ALOGW("An error occurred while connecting to camera: %d", cameraId);
22         c.clear();
23     }
24     return status;
25 }

复制代码

        这部分有太多的资料阐述,毕竟还是Android通用代码,未涉及到硬件芯片厂商的差异性。简约一些,connect会获得一个CameraService,这个Service将进行HAL层设备的管理及交互。我们跳转到CameraService::connectLegacy可以看到在这个Service中包含了一个CameraClient,而上面说到的返回的Camera设备就是这个Client(源码:device = client;)。

复制代码

 1 status_t CameraService::connectLegacy(
 2         const sp& cameraClient,
 3         int cameraId, int halVersion,
 4         const String16& clientPackageName,
 5         int clientUid,
 6         /*out*/
 7         sp& device) {// go here
 8 
 9  。。。。。。
10 
11     status_t status = validateConnect(cameraId, /*inout*/clientUid);
12     if (status != OK) {
13         return status;
14     }
15 
16     sp client;
17     {
18         sp clientTmp;
19         Mutex::Autolock lock(mServiceLock);
20         if (!canConnectUnsafe(cameraId, clientPackageName,
21                               cameraClient->asBinder(),
22                               /*out*/clientTmp)) {
23             return -EBUSY;
24         } else if (client.get() != NULL) {
25             device = static_cast(clientTmp.get());
26             return OK;
27         }
28 
29         status = connectHelperLocked(/*out*/client,   // 这个client就是上面调用中要返回的Camera设备device
30                                      cameraClient,    // 传下来的ICameraClient实例
31                                      cameraId,
32                                      clientPackageName,
33                                      clientUid,
34                                      callingPid,
35                                      halVersion,
36                                      /*legacyMode*/true);
37         if (status != OK) {
38             return status;
39         }
40 
41     }
42     // important: release the mutex here so the client can call back
43     //    into the service from its destructor (can be at the end of the call)
44 
45     device = client;   // 返回的Client设备
46     return OK;
47 }

复制代码

        在connectHelperLocked中,将根据不同HAL版本实现不同的示例,目前有CameraClient和Camera2Client两种

复制代码

 1           case CAMERA_DEVICE_API_VERSION_1_0:
 2             ALOGV("create a camera client.line %d",__LINE__);
 3             client = new CameraClient(this, cameraClient,      // 前面那个CameraClient是要实现的Client,第二个cameraClient就是上面传下来的ICameraClient实例
 4                     clientPackageName, cameraId,
 5                     facing, callingPid, clientUid, getpid(), legacyMode);
 6             break;
 7           case CAMERA_DEVICE_API_VERSION_2_0:
 8           case CAMERA_DEVICE_API_VERSION_2_1:
 9           case CAMERA_DEVICE_API_VERSION_3_0:
10           case CAMERA_DEVICE_API_VERSION_3_1:
11           case CAMERA_DEVICE_API_VERSION_3_2:
12             ALOGI("create a camera2 client");
13             client = new Camera2Client(this, cameraClient,
14                     clientPackageName, cameraId,
15                     facing, callingPid, clientUid, getpid(), legacyMode);
16             break;

复制代码

        上面获得Client后会调用connectFinishUnsafe(client, client->getRemote()),这个函数将会执行到HAL的interface,所以厂家通用。

复制代码

 1 status_t CameraService::connectFinishUnsafe(const sp& client,
 2                                             const sp& remoteCallback) {
 3     status_t status = client->initialize(mModule); //这个mModule很关键,是在CameraService.cpp中onFirstRef中获取的。其实就是根据类名等规则加载一个动态库,一般在/system/lib/hw/目录下,如camera.msm8994.so

 4     if (status != OK) {
 5         ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
 6         return status;
 7     }
 8     if (remoteCallback != NULL) {
 9         remoteCallback->linkToDeath(this);
10     }
11 
12     return OK;
13 }

复制代码

        上面client中的initialize会调用到hardware interface中的initialize并设置callback (CameraHardwareInterface.h),而在这里就会调用到具体厂家HAL层的函数了。

复制代码

 1     status_t initialize(hw_module_t *module)
 2     {
 3         ALOGI("Opening camera %s", mName.string());
 4         camera_module_t *cameraModule = reinterpret_cast(module);
 5         camera_info info;
 6         status_t res = cameraModule->get_camera_info(atoi(mName.string()), &info);
 7         if (res != OK) return res;
 8         ALOGI("init hal-ver:%d,dev-ver %d",module->module_api_version,info.device_version);// 515=v2.3,770=v3.2
 9         int rc = OK;
10         if (module->module_api_version >= CAMERA_MODULE_API_VERSION_2_3 &&
11             info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {ALOGI("open legacy");
12             // Open higher version camera device as HAL1.0 device.
13             rc = cameraModule->open_legacy(module, mName.string(),  // 这个cameraModule就上具体厂家代码编译出来的so库,这里对应QCamera2Factory.cpp
14                                                CAMERA_DEVICE_API_VERSION_1_0,
15                                                (hw_device_t **)&mDevice);
16         } else {
17             rc = CameraService::filterOpenErrorCode(module->methods->open(
18                 module, mName.string(), (hw_device_t **)&mDevice));
19         }
20         if (rc != OK) {
21             ALOGE("Could not open camera %s: %d", mName.string(), rc);
22             return rc;
23         }
24         initHalPreviewWindow();
25         return rc;
26     }

复制代码

5.到这里就正式进入HAL层,每个厂家的实现代码也变得不一样,但大致模式还是差不多,都是通过V4L2的命令接口来控制具体的Camera设备。 HAL及driver将在另一篇继续讨论。

 

你可能感兴趣的:(android模块分析)