前段时间公司有一个项目,是双摄像头,但是是共同驱动的。这两颗通过光感切换镜片实现正常和夜景两种效果。但是由于夜景和正常场景是不同的效果参数,这就需要在不同场景下调用匹配对应的效果参数。
相机APP通过光感发起场景的切换,设置当前要进入的是夜景还是普通模式到framework 然后再通知到hal 依次告诉sensor来加载不同效果。
路径:
packages/apps/SnapdragonCamera/src/com/android/camera/PhotoModule.java根据光感条件下发如下参数来通知framework准备切换场景:
Parameters p = mCameraDevice.getParameters(); mParameters.setNightMode(onOff == 1 ? "1" : "0");路径:
frameworks/base/core/java/android/hardware/Camera.java增加接口实现:
public static final String KEY_NIGHT_MODE = "night-mode"; '''' public void setNightMode(String value) { Log.i(TAG, "camera freamwork setNightMode onOff =" + value); set(KEY_NIGHT_MODE, value); }路径:
hardware/qcom/camera/QCamera2/HAL/QCameraParameters.cpp hardware/qcom/camera/QCamera2/HAL/QCameraParameters.h const char QCameraParameters::KEY_QC_NIGHT_MODE[] = "night-mode"; int32_t QCameraParameters::updateParameters(const String8& p, bool &needRestart) 、、、 if ((rc = setNightMode(params))) final_rc = rc; 、、、 } int32_t QCameraParameters::setNightMode(const QCameraParameters& params) { const char *str = params.get(KEY_QC_NIGHT_MODE); const char *prev_str = get(KEY_QC_NIGHT_MODE); LOGI("hal setNightMode cur status = %s pre = %s", str,prev_str); if (str != NULL) { if (prev_str == NULL || strcmp(str, prev_str) != 0) { int8_t onOff = atoi(str); updateParamEntry(KEY_QC_NIGHT_MODE, str); set(KEY_QC_NIGHT_MODE, str); if (ADD_SET_PARAM_ENTRY_TO_BATCH(m_pParamBuf, CAM_INTF_PARM_NIGHT_VISION_MODE, onOff)) { LOGI("hal setNightMode BAD_VALUE "); return BAD_VALUE; } } } return NO_ERROR; }注意在 QCameraParameters.h 声明一下 static const char KEY_QC_NIGHT_MODE[]; 和 QCameraParameters::setNightMode(const QCameraParameters& params);
定义一下 CAM_INTF_PARM_NIGHT_VISION_MODE
路径:
hardware/qcom/camera/QCamera2/stack/common/cam_intf.h typedef struct { /************************************************************************************** * ID from (cam_intf_metadata_type_t) DATATYPE COUNT **************************************************************************************/ /* common between HAL1 and HAL3 */ 、、、 //最后增加 INCLUDE(CAM_INTF_PARM_NIGHT_VISION_MODE, uint8_t, 1); }同样的在:
hardware/qcom/camera/QCamera2/stack/common/cam_types.htypedef enum { CAM_INTF_PARM_HAL_VERSION = 0x1, 、、、 //最后 CAM_INTF_PARM_NIGHT_VISION_MODE, CAM_INTF_PARM_MAX } cam_intf_parm_type_t;
首先是在相应的sensor效果参数文件中加入夜景的参数:
路径 :
vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/configs/imx335_chromatix.xml
增加:
<ChromatixName sensor_resolution_index="0" special_mode_mask="NIGHT_VISION_MODE"> <ISPPreview>imx335_snapshot_night</ISPPreview> <ISPSnapshot>imx335_snapshot_night</ISPSnapshot> <ISPVideo>imx335_default_video_night</ISPVideo> <CPPVideo>imx335_cpp_video</CPPVideo> <A3Preview>imx335_zsl_preview_3a</A3Preview> <A3Video>imx335_zsl_video_3a</A3Video> </ChromatixName>其实就是通过 special_mode_mask 这个来判断是否是夜景的参数。
而 imx335_snapshot_night 这些参数是要在:
vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/chromatix/0310/chromatix_imx335/
这个路径下面 参考 isp 新建isp_night 然后把所有的夜景参数 加进来。
修改对应的android.mk 会生成 libchromatix_imx335_snapshot_night 和 libchromatix_imx335_default_video_night
于是我们需要将这个两个库加到 vendor/qcom/proprietary/common/config/device-vendor.mk
需要把效果库加载进来:
MM_CAMERA += libchromatix_imx335_snapshot_night MM_CAMERA += libchromatix_imx335_default_video_night
之后 我们需要在
vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_util_xml.c
定义 我们的 夜景的mode 也就是 上面所说的 special_mode_mask
添加:
static char special_mode_string[SENSOR_SPECIAL_MODE_MAX][50] = { 、、、 [SENSOR_SPECIAL_MODE_NIGHT_VISION] = "NIGHT_VISION_MODE", 、、、 }vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/camera_config.h
结构体中添加成员变量用于记录和判断是否需要切换夜景 :
vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_common.h
typedef struct module_sensor_bundle_info_t { 、、、 int32_t night_version_mode; int32_t previous_night_version_mode; }vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/stream/mct_stream.c
void *get_pointer_of(cam_intf_parm_type_t meta_id, metadata_buffer_t* metadata) { switch(meta_id) { 、、、 //*/ add for night vision mode separation of effect parameters case CAM_INTF_PARM_NIGHT_VISION_MODE: CLOGI(CAM_MCT_MODULE, " get_pointer_of :CAM_INTF_PARM_NIGHT_VISION_MODE "); return POINTER_OF_META(CAM_INTF_PARM_NIGHT_VISION_MODE, metadata); //*/ default: CLOGD(CAM_MCT_MODULE, "case is not implemented for meta_id %d", meta_id); return NULL; } } uint32_t get_size_of(cam_intf_parm_type_t param_id) { metadata_buffer_t* metadata = NULL; switch(param_id) { 、、、 //*/add for night vision mode separation of effect parameters case CAM_INTF_PARM_NIGHT_VISION_MODE: CLOGI(CAM_MCT_MODULE, "CAM_INTF_PARM_NIGHT_VISION_MODE "); return SIZE_OF_PARAM(CAM_INTF_PARM_NIGHT_VISION_MODE, metadata); //*/ default: CLOGD(CAM_MCT_MODULE, "case is not implemented for param_id %d", param_id); return 0; } }vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
boolean module_sensor_event_control_set_parm( mct_module_t *module, uint32_t frame_id, module_sensor_bundle_info_t *s_bundle, mct_event_control_parm_t *event_control, uint32_t identity) { ''' SLOW("event type =%d", event_control->type); switch (event_control->type) { case CAM_INTF_PARM_FPS_RANGE: { ''' //*/add for night vision mode separation of effect parameters case CAM_INTF_PARM_NIGHT_VISION_MODE: { RETURN_ON_NULL(event_control->parm_data); uint8_t mode = *((uint8_t*)event_control->parm_data); SERR("Setting CAM_INTF_PARM_NIGHT_VISION_MODE %d \n", mode); if(mode !=0 && mode !=1){ SERR("night_version_mode error mode "); break; } s_bundle->night_version_mode = mode; s_bundle->sensor_common_info.night_version_mode = s_bundle->night_version_mode; // reload SERR("chromatix night_version_mode=%d, previous_night_version_mode=%d, sensor_common_info.night_version_mode=%d", s_bundle->night_version_mode, s_bundle->previous_night_version_mode, s_bundle->sensor_common_info.night_version_mode); if (s_bundle->night_version_mode != s_bundle->previous_night_version_mode) { SERR("night_version_mode reload chromatix"); RETURN_ON_FALSE(module_sensor_reload_chromatix(s_bundle, module, identity)); } s_bundle->previous_night_version_mode = s_bundle->night_version_mode; } break; //*/ ''' } ''' }最后我们就是根据上面定义的 special_mode_mask 来加载 夜景参数。
vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor/module/sensor.c
static int32_t sensor_get_cur_chromatix_name(void *sctrl, void *data) { 、、、 sensor_common_info = ctrl->s_data->sensor_common_info; chromatix_name = &(sensor_common_info->camera_config.chromatix_info.chromatix_name[cur_res]); //*/ add for night vision mode separation of effect parameters if (sensor_common_info->night_version_mode == 1) { sensor_util_set_special_mode(ctrl->s_data->sensor_common_info, SENSOR_SPECIAL_MODE_NIGHT_VISION, TRUE); } SLOW("special_mode_mask = %lld", sensor_common_info->special_mode_mask); //*/ 、、、 }至此 我们的添加流程结束了,特别要强调的是 这个从APP 中设置night mode 后 需要重新request一下。
对了 特此要感谢一些 帮助过我的那么大神! 谢谢!
