Android 设置参数至kernel_ois为例

时间:2023-01-08 18:36:40

       由于最近研究OIS,而android4.4并没有相关逻辑(vendor&hal&kernel)当然android 6.0拥有完善逻辑,增加OIS光学防抖参数设置(ois参数一般不作为设置参数,仅作实验测试):

A:上层逻辑

1)  添加接口函数

参考public void setSaturation(int saturation)设置

在code/frameworks/base/core/java/android/hardware/Camera.java文件增加接口:

定义用于app层设置的接口函数:

        public void setOis(int saturation){
              …………
              set(KEY_QC_OIS, String.valueOf(OIS));
}
2)  App设置参数调用,假设设置ois值为1
参考 packages/apps/SnapdragonCamera/src/com/android/camera/PhotoModule.java
mParameters.setSaturation(saturation);函数调用;
mParameters.setOis(ois); //app调用接口函数
由于HAL V1参数传递是通过字符串来完成的,最后传递到HAL层的字符串里面会有“ois=1”,在HAL层进行解析。
B、Hal层相关修改:
1、    添加相关定义
1.1
、 文件:hardware/qcom/camera/QCamera2/HAL/QCameraParameters.h
     static const char KEY_QC_SCE_FACTOR_STEP[];
+    static const char KEY_QC_OIS[];
     static const char KEY_QC_HISTOGRAM[] ;
     int32_t setSharpness(const QCameraParameters& );
+    int32_t setOis(const QCameraParameters& );
     int32_t setSaturation(const QCameraParameters& );
     int32_t setSharpness(int sharpness);
+    int32_t setOis(int ois);
     int32_t setSaturation(int saturation);
1.2、 文件:hardware/qcom/camera/QCamera2/stack/common/cam_types.h
            typedef enum {
                CAM_INTF_PARM_FLASH_BRACKETING,
                CAM_INTF_PARM_GET_IMG_PROP,
                    CAM_INTF_PARM_MAX
+    CAM_INTF_PARM_OIS
            } cam_intf_parm_type_t;
1.3、 文件:hardware/qcom/camera/QCamera2/stack/common/cam_intf.h
typedef struct{
     cam_af_bracketing_t  mtf_af_bracketing_parm;
    
     cam_sensor_type_t sensor_type;
+   
+    int32_t ois_default_value;
 } cam_capability_t;
2、    添加相关设置
文件:hardware/qcom/camera/QCamera2/HAL/QCameraParameters.cpp
const char QCameraParameters::KEY_QC_SCE_FACTOR_STEP[] = "sce-factor-step";
+const char QCameraParameters::KEY_QC_OIS[] = "ois";
//open camera时OIS默认值,该值在vendor中设置
int32_t QCameraParameters::initDefaultParameters()
{

       ………

+    // Set Ois

+    setOis(m_pCapability->ois_default_value); //m_pCapability即为通过共享内存从vendor层拿到的初始化数据

//请参考Android ION机制_HAL与vendor层共享内存_流程简介(1)

//http://blog.csdn.net/liwei16611/article/details/51104400

+    ALOGE("the default_ois = %d", m_pCapability->ois_default_value);
     // Set Contrast
     set(KEY_QC_MIN_CONTRAST, m_pCapability->contrast_ctrl.min_value);
     set(KEY_QC_MAX_CONTRAST, m_pCapability->contrast_ctrl.max_value);
     ………
}
+int32_t QCameraParameters::setOis(const QCameraParameters& params)
+{
+    int ois = params.getInt(KEY_QC_OIS);
+    int prev_ois = getInt(KEY_QC_OIS);
+    if(params.get(KEY_QC_OIS) == NULL) {
+       CDBG_HIGH("%s: Ois not set by App ",__func__);
+       return NO_ERROR;
+    }
+    ALOGE("haljay ois=%d prev_ois=%d",ois, prev_ois);
+    if (prev_ois !=  ois) {
+        if((ois >= 0) && (ois <= 2)) {
+            CDBG(" new ois value : %d ", ois);
+            return setOis(ois);
+        } else {
+            ALOGE("%s: invalid value %d",__func__, ois);
+            return BAD_VALUE;
+        }
+    } else {
+        ALOGE("haljay no value change");
+        CDBG("%s: No value change in ois", __func__);
+        return NO_ERROR;
+    }
+}
+int32_t QCameraParameters::setOis(int ois)
+{
+    char val[16];
+    sprintf(val, "%d", ois);
+    updateParamEntry(KEY_QC_OIS, val);
+    CDBG("%s: Setting ois %s", __func__, val);
+    ALOGE("haljay %s set ois=%s OIS=%d", __func__, val, CAM_INTF_PARM_OIS);
+    int32_t value = ois;
+    return AddSetParmEntryToBatch(m_pParamBuf,
+                                  CAM_INTF_PARM_OIS,
+                                  sizeof(value),
+                                  &value);
+}
函数int32_t QCameraParameters::updateParameters添加setOis:
     if ((rc = setBrightness(params)))                   final_rc = rc;
     if ((rc = setZoom(params)))                         final_rc = rc;
     if ((rc = setSharpness(params)))                    final_rc = rc;
+    if ((rc = setOis(params)))                          final_rc = rc;
     if ((rc = setSaturation(params)))                   final_rc = rc;
C、Vendor层相关修改:
1、    添加相关定义
1.1
、 文件:kernel/include/media/msm_cam_sensor.h
enum msm_actuator_cfg_type_t {
  CFG_SET_POSITION,
  CFG_ACTUATOR_POWERDOWN,
  CFG_ACTUATOR_POWERUP,
+ CFG_ACTUATOR_OIS,
 };
struct msm_actuator_cfg_data {
      struct msm_actuator_get_info_t get_info;
      struct msm_actuator_set_position_t setpos;
      enum af_camera_name cam_name;
+      void *setting;
  } cfg;
1.2、 文件:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/pipeline/mct_pipeline.c
      在函数boolean mct_pipeline_populate_query_cap_buffer(mct_pipeline_t *pipeline)中添加:
                hal_data->sharpness_ctrl.min_value = 0;
                hal_data->sharpness_ctrl.step = 6;
 
+  hal_data->ois_default_value = 1;  //通过ION机制传至hal层
                hal_data->contrast_ctrl.def_value = 5;
                hal_data->contrast_ctrl.max_value = 10;
1.3、 文件:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_common.h
typedef enum {
  
  
   SENSOR_SET_AWB_UPDATE,
+  ACTUATOR_SET_OIS
 } sensor_submodule_event_type_t;
2、    添加相关设置
文件:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
2.1、获取hal层参数
在函数static boolean module_sensor_event_control_set_parm中增加:
+  case CAM_INTF_PARM_OIS:{
+    if (!event_control->parm_data) {
+        SERR("failed parm_data NULL");
+        ret = FALSE;
+        break;
+      }
+    module_sensor_params_t        *ois_module_params = NULL;
+    ois_module_params = s_bundle->module_sensor_params[SUB_MODULE_ACTUATOR];
+    if (ois_module_params->func_tbl.process != NULL) {
+      rc = ois_module_params->func_tbl.process(
+        ois_module_params->sub_module_private,
+        ACTUATOR_SET_OIS, event_control->parm_data);
+    }
+    if (rc < 0) {
+      SERR("failed");
+      ret = FALSE;
+    }
+     break;
+  }
文件:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/actuators/actuator.c
2.2、在函数int32_t actuator_process中增加
       case ACTUATOR_SET_POSITION:
            rc = actuator_set_position(actuator_ctrl, data);
            break;

+   case ACTUATOR_SET_OIS:
+   rc = actuator_set_ois(actuator_ctrl, data);
+   break;
2.3、将参数通过ioctl方法下至内核
        +static int actuator_set_ois(void *ptr, void *data) {
+  int rc = 0;
+  int32_t *ois_level = (int32_t*)data;
+  actuator_data_t *ois_actuator_ptr = (actuator_data_t *)ptr;
+  struct msm_actuator_cfg_data cfg;
+  if (ois_actuator_ptr->fd <= 0)
+    return -EINVAL;
+  cfg.cfgtype = CFG_ACTUATOR_OIS;
+  cfg.cfg.setting = ois_level;

+  rc = ioctl(ois_actuator_ptr->fd, VIDIOC_MSM_ACTUATOR_CFG, &cfg);
+  if (rc < 0) {
+    SERR("failed-errno: %s!!!",strerror(errno));
+  }
+  return rc;
+}