高通CAMERA架構(一)

從JNI往下看


JNI : frameworks/base/core/jni/android_hardware_camera.cpp

static 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;II)V",    (void*)android_hardware_Camera_native_setup },
  { "native_release",    "()V",    (void*)android_hardware_Camera_release },
  { "setPreviewDisplay",    "(Landroid/view/Surface;)V",    (void *)android_hardware_Camera_setPreviewDisplay },
  { "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",    "([B)V",    (void *)android_hardware_Camera_addCallbackBuffer },
  { "native_autoFocus",   "()V",    (void *)android_hardware_Camera_autoFocus },
  { "native_encodeData",    "()V",    (void *)android_hardware_Camera_encodeData },
  { "native_cancelAutoFocus",    "()V",    (void *)android_hardware_Camera_cancelAutoFocus },
  { "native_takePicture",   "()V",    (void *)android_hardware_Camera_takePicture },
  { "native_setHistogramMode",    "(Z)V",    (void *)android_hardware_Camera_setHistogramMode },
  { "native_sendHistogramData",    "()V",    (void *)android_hardware_Camera_sendHistogramData },
  { "native_setFaceDetectionCb",    "(Z)V",    (void *)android_hardware_Camera_setFaceDetectionCb },
  { "native_sendMetaData",    "()V",    (void *)android_hardware_Camera_sendMetaData },
  { "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 },
};

====================================================================================

static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz)
{
    return Camera::getNumberOfCameras();
}

此處調到/framework/base/libs/camera/camera.cpp 中。

int32_t Camera::getNumberOfCameras()
{
    const sp<ICameraService>& cs = getCameraService();
    if (cs == 0) return 0;
    return cs->getNumberOfCameras();
}

此處調用到/framework/base/service/camera/libcameraservice/cameraservice.cpp中藉口

int32_t CameraService::getNumberOfCameras() {
    return mNumberOfCameras;
}

而,此處mNumberOfCamerascameraservice.cpp

 mNumberOfCameras = HAL_getNumberOfCameras(); 獲得。


HAL_getNumberOfCameras()函數,調用\vendor\qcom\android-open\libcamera2\QualcommCameraHardware.cpp中的接口。

extern "C" int HAL_getNumberOfCameras()
{
    QualcommCameraHardware::getCameraInfo();
    return HAL_numOfCameras;
}

接下來看下getCameraInfo()


void QualcommCameraHardware::getCameraInfo()
{
    LOGI("getCameraInfo: IN");
    mm_camera_status_t status;

#if DLOPEN_LIBMMCAMERA
    void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
    LOGI("getCameraInfo: loading libqcamera at %p", libhandle);
    if (!libhandle) {
        LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
    }
    *(void **)&LINK_mm_camera_get_camera_info =
        ::dlsym(libhandle, "mm_camera_get_camera_info");
#endif
    storeTargetType();
    status = LINK_mm_camera_get_camera_info(HAL_cameraInfo, &HAL_numOfCameras);
    LOGI("getCameraInfo: numOfCameras = %d", HAL_numOfCameras);
    for(int i = 0; i < HAL_numOfCameras; i++) {
        if((HAL_cameraInfo[i].position == BACK_CAMERA )&&
            mCurrentTarget == TARGET_MSM8660){
            HAL_cameraInfo[i].modes_supported |= CAMERA_ZSL_MODE;
        } else{
            HAL_cameraInfo[i].modes_supported |= CAMERA_NONZSL_MODE;
        }
        LOGI("Camera sensor %d info:", i);
        LOGI("camera_id: %d", HAL_cameraInfo[i].camera_id);
        LOGI("modes_supported: %x", HAL_cameraInfo[i].modes_supported);
        LOGI("position: %d", HAL_cameraInfo[i].position);
        LOGI("sensor_mount_angle: %d", HAL_cameraInfo[i].sensor_mount_angle);
    }

#if DLOPEN_LIBMMCAMERA
    if (libhandle) {
        ::dlclose(libhandle);
        LOGV("getCameraInfo: dlclose(libqcamera)");
    }
#endif
    LOGI("getCameraInfo: OUT");
}


在前面有#define LINK_mm_camera_get_camera_info mm_camera_get_camera_info  ,所以我們接下來到

mm_camera_get_camera_info(HAL_cameraInfo, &HAL_numOfCameras);調用到哪。

在 vendor\qcom\proprietary\mm-camera\apps\appslib\mm_camera_interface.c中有定義

mm_camera_status_t mm_camera_get_camera_info(camera_info_t* p_cam_info,
  int* p_num_cameras)
{
  int i = 0;
  int controlfd = -1;
  char device[MAX_DEV_NAME_LEN];

  CDBG("%s: [S]\n", __func__);
  mm_camera_status_t status = MM_CAMERA_SUCCESS;
  struct msm_camera_info cameraInfo;

  if (NULL == p_cam_info) {
    status = MM_CAMERA_ERR_INVALID_INPUT;
    goto ERROR;
  }

  sprintf (device, MSM_CAMERA_CONTROL, 0);
  controlfd = open(device, O_RDWR);

//此處打開的是內核註冊的控制節點 "/dev/msm_camera/control%d"

// 內核一共註冊了四個節點,control、config、frame、pic 對應了四組操作函數。老一點的版本是三組節點。

  if (controlfd < 0) {
    CDBG_HIGH("%s: controlfd is invalid %s", __func__, strerror(errno));
    status = MM_CAMERA_ERR_GENERAL;
    goto ERROR;
  }

  if (ioctl(controlfd, MSM_CAM_IOCTL_GET_CAMERA_INFO, &cameraInfo) < 0) {  //此處獲得內核註冊camera信息
    CDBG_HIGH("%s: error (%s)", __func__, strerror(errno));
    status = MM_CAMERA_ERR_GENERAL;
    goto ERROR;
  }

  CDBG("%s: num %d\n", __func__, cameraInfo.num_cameras);
  for (i=0; i < cameraInfo.num_cameras; i++) {
    p_cam_info[i].camera_id = i; 
    p_cam_info[i].modes_supported =
      (!cameraInfo.has_3d_support[i]) ? CAMERA_MODE_2D :  //前置攝像頭只支持2D
      CAMERA_MODE_2D | CAMERA_MODE_3D; 
    p_cam_info[i].position =                           //在內核前置攝像頭is_internal_cam[i]定義爲1,後置攝像頭默認爲0.
      (cameraInfo.is_internal_cam[i]) ? FRONT_CAMERA : BACK_CAMERA;

//到此用戶層將前置和後置攝像頭區分開
    p_cam_info[i].sensor_mount_angle = cameraInfo.s_mount_angle[i];
  }
  *p_num_cameras = cameraInfo.num_cameras;
  ERROR:
  if (controlfd > 0) {
    close(controlfd);
  }
  CDBG("%s: %d [E]", __func__, status);
  return status;
}


至此 android_hardware_Camera_getNumberOfCameras 的流程完成。

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