高通骁龙相机实现黑白夜景效果

it2026-10-02  5

背景:

     前段时间公司有一个项目,是双摄像头,但是是共同驱动的。这两颗通过光感切换镜片实现正常和夜景两种效果。但是由于夜景和正常场景是不同的效果参数,这就需要在不同场景下调用匹配对应的效果参数。

思路:

     相机APP通过光感发起场景的切换,设置当前要进入的是夜景还是普通模式到framework 然后再通知到hal 依次告诉sensor来加载不同效果。

实现:

相机应用:

    路径:

packages/apps/SnapdragonCamera/src/com/android/camera/PhotoModule.java

       根据光感条件下发如下参数来通知framework准备切换场景:

Parameters p = mCameraDevice.getParameters(); mParameters.setNightMode(onOff == 1 ? "1" : "0");

framework:  

      路径:

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); }

Hal 层:

 路径:

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.h

  

typedef enum { CAM_INTF_PARM_HAL_VERSION = 0x1, 、、、 //最后 CAM_INTF_PARM_NIGHT_VISION_MODE, CAM_INTF_PARM_MAX } cam_intf_parm_type_t;

Vendor 下面的修改:

首先是在相应的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一下。

对了 特此要感谢一些 帮助过我的那么大神! 谢谢!

 

 

最新回复(0)