我们公司用的是高通sdm660平台,oppo等大厂长按相机拍照时,即使闪光灯打开也不会亮,从SnapdragonCamera里面通过设置parameters = camera.getParameters(); parameters.setFlashMode(Parameters.FLASH_MODE_OFF);//关闭camera.setParameters(parameters);设置完生效需要时间,长按拍照时关闭有时候不生效,在这种背景下就需要往系统去分析,从系统里面去解决问题,经过分析最终在驱动层解决了该问题,分析思路如下:
主要是这几个文件里面,flash.c是闪光灯驱动
module_sensor.c主要是对闪光灯的一个控制方法在里面实现。
diff --git a/mm-camera/mm-camera2/media-controller/modules/sensors/flash/module/flash.c b/mm-camera/mm-camera2/media-controller/modules/sensors/flash/module/flash.c
index e7c42ff..ee525f4 100755
--- a/mm-camera/mm-camera2/media-controller/modules/sensors/flash/module/flash.c
+++ b/mm-camera/mm-camera2/media-controller/modules/sensors/flash/module/flash.c
@@ -40,6 +40,7 @@ static int32_t flash_open(void **flash_ctrl, void *data)
(sensor_submodule_info_t *)data;
SDBG("Enter");
+ SERR("zjy flash flash_open");
RETURN_ERROR_ON_NULL(flash_ctrl);
RETURN_ERROR_ON_NULL(info);
RETURN_ERROR_ON_NULL(info->intf_info[SUBDEV_INTF_PRIMARY].sensor_sd_name);
@@ -315,7 +316,7 @@ static int32_t flash_process(void *ctrl,
struct msm_flash_cfg_data_t cfg;
int32_t default_current = -1;
struct msm_camera_i2c_reg_setting_array *flash_settings = NULL;
-
+
RETURN_ERROR_ON_NULL(ctrl);
flash_ctrl = (sensor_flash_data_t *)ctrl;
@@ -333,7 +334,7 @@ static int32_t flash_process(void *ctrl,
RETURN_ERROR_ON_NULL(flash_settings);
SLOW("event %d", event);
-
+ SERR("zjy flash flash_process event:%d",event);
switch (event) {
case LED_FLASH_GET_MAX_CURRENT: {
int32_t ** flash_current = (int32_t **)data;
diff --git a/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c b/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
index 00cebe0..afc541d 100755
--- a/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
+++ b/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
@@ -980,6 +980,7 @@ static boolean module_sensor_update_settings_size(
static boolean module_sensors_subinit(void *data,
void *user_data __attribute__((unused)))
{
+ SERR("zjy module_sensor module_sensors_subinit");
int32_t rc = SENSOR_SUCCESS, i = 0;
module_sensor_bundle_info_t *s_bundle = (module_sensor_bundle_info_t *)data;
sensor_submodule_intf_info_t *intf_info = NULL;
@@ -2982,11 +2983,11 @@ static boolean module_sensor_preflash_control(mct_module_t* module,
uint8_t ret = 0;
void *data = NULL;
uint32_t max_frame_skip = 0;
-
+ SERR("zjy module_sensor module_sensor_preflash_control");
if (s_bundle->last_idx < bctrl->ctrl_end_frame) {
if (ctrl->retry_frame_skip >= 0) {
if (!ctrl->retry_frame_skip--) {
- SHIGH("preflash on/off %d. Sending flash mode downstream - %d",
+ SERR("module_sensor_preflash_control preflash on/off %d. Sending flash mode downstream - %d",
bctrl->flash_mode, bctrl->cam_flash_mode);
/* Post desired flash mode for each batch in advance */
sensor_util_post_downstream_event(module, event->identity,
@@ -2995,6 +2996,7 @@ static boolean module_sensor_preflash_control(mct_module_t* module,
if (bctrl->flash_mode == LED_FLASH_SET_OFF &&
s_bundle->regular_led_af == 0 &&
s_bundle->flash_rer_enable) {
+ SERR("module_sensor_preflash_control flash mode is off");
data = (void *)led_module_params;
bctrl->flash_mode = LED_FLASH_SET_RER_PROCESS;
}
@@ -3007,7 +3009,7 @@ static boolean module_sensor_preflash_control(mct_module_t* module,
bctrl->led_toggle_pending = FALSE;
}
} else {
- SHIGH("request isp sw skip range");
+ SERR("module_sensor_preflash_control request isp sw skip range");
/*send skip request to isp to enable skip*/
max_frame_skip = bctrl->interval;
rc = sensor_util_sw_frame_skip_to_isp(module, event->identity, s_bundle,
@@ -3027,7 +3029,7 @@ static boolean module_sensor_preflash_control(mct_module_t* module,
PTHREAD_MUTEX_LOCK(&s_bundle->capture_control_mutex);
if (s_bundle->regular_led_af == 0) {
if (!bctrl->led_toggle_pending) {
- SHIGH("Need future frame");
+ SERR("module_sensor_preflash_control Need future frame");
s_bundle->regular_led_trigger = 1;
cam_prep_snapshot_state_t state;
ctrl->enable = 0;
@@ -3038,7 +3040,7 @@ static boolean module_sensor_preflash_control(mct_module_t* module,
SERR("error posting led frame range msg");
}
} else if (s_bundle->last_idx == bctrl->ctrl_end_frame - 1) {
- SHIGH("Led config ioctl in progress. flash mode %d",
+ SERR("module_sensor_preflash_control Led config ioctl in progress. flash mode %d",
bctrl->flash_mode);
/*This is to account for led kernel ioctl taking too much time.
*Retry unless led ioctl fail or mode is set. Partial skip will
@@ -3050,16 +3052,18 @@ static boolean module_sensor_preflash_control(mct_module_t* module,
LDF AF usecase in order to avoid race condition in HAL1
where sending MCT_BUS_MSG_PREPARE_HW_DONE happens in
different thread */
+ SERR("module_sensor_preflash_control regular_led_af 0");
s_bundle->regular_led_af = 0;
}
PTHREAD_MUTEX_UNLOCK(&s_bundle->capture_control_mutex);
} else if (bctrl->flash_mode == LED_FLASH_SET_PRE_FLASH){
+ SERR("module_sensor_preflash_control enable is 0");
ctrl->enable = 0;
SLOW("preflash on control exit");
}
}
} else {
- SLOW("preflash control exit");
+ SERR("module_sensor_preflash_control preflash control exit");
ctrl->enable = 0;
}
@@ -3521,9 +3525,10 @@ boolean module_sensor_capture_control(mct_module_t* module,
/* Allow to process delay event based batches only
at the end of SOF or non delay event based batches
before SOF*/
+ SERR("module_sensor_capture_control is_delayed:%d",is_delayed);
if (ctrl->delay_evt[ctrl->idx] ^ is_delayed)
return TRUE;
-
+ SERR("module_sensor_capture_control enable:%d,idx:%d",ctrl->enable,ctrl->evt[ctrl->idx]);
if (ctrl->enable) {
switch(ctrl->evt[ctrl->idx]) {
case SENSOR_AEC_EST_EVT:
@@ -4289,9 +4294,11 @@ static boolean module_sensor_set_start_stream_on(
if (s_bundle->regular_led_trigger == 1
&& s_bundle->hal_version == CAM_HAL_V1) {
+ SERR("zjy module_sensor_set_start_stream_on trigger is 1");
uint8_t flash_mode;
if (s_bundle->longshot)
- flash_mode = LED_FLASH_SET_PRE_FLASH;
+ //flash_mode = LED_FLASH_SET_PRE_FLASH;
+ flash_mode = LED_FLASH_SET_MAIN_FLASH;
else
flash_mode = LED_FLASH_SET_MAIN_FLASH;
SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_LED_FLASH,
@@ -4301,8 +4308,13 @@ static boolean module_sensor_set_start_stream_on(
s_bundle->sensor_params.flash_state = CAM_FLASH_STATE_READY;
SERR("failed: LED_FLASH_SET_MAIN_FLASH");
} else {
+ if(!s_bundle->longshot){
s_bundle->sensor_params.flash_mode = CAM_FLASH_MODE_ON;
s_bundle->sensor_params.flash_state = CAM_FLASH_STATE_FIRED;
+ } else {
+ s_bundle->sensor_params.flash_mode = CAM_FLASH_MODE_OFF;
+ s_bundle->sensor_params.flash_state = CAM_FLASH_STATE_READY;
+ }
}
sensor_util_post_led_state_msg(module, s_bundle, event->identity);
@@ -6302,7 +6314,7 @@ static boolean module_sensor_module_process_event(mct_module_t *module,
RETURN_ON_NULL(event);
if (event->type != MCT_EVENT_CONTROL_CMD) {
- SERR("failed invalid event type %d",
+ SERR("module_sensor_module_process_event failed invalid event type %d",
event->type);
return FALSE;
}
@@ -6316,7 +6328,6 @@ static boolean module_sensor_module_process_event(mct_module_t *module,
RETURN_ON_FALSE(sensor_util_get_sbundle(module, event->identity, &bundle_info));
SLOW("event type %d current_frame_id %d last_idx %d",
event_ctrl->type, event_ctrl->current_frame_id, bundle_info.s_bundle->last_idx);
-
if (bundle_info.s_bundle->block_parm || (event_ctrl->type !=
MCT_EVENT_CONTROL_SET_PARM && event_ctrl->type !=
MCT_EVENT_CONTROL_GET_PARM)) {
@@ -6490,7 +6501,7 @@ static boolean module_sensor_module_process_event(mct_module_t *module,
max_led_on_period = MAX_LED_ON_DURATION_DEFAULT;
}
- SLOW("max_led_on_period set to %d",max_led_on_period);
+ SERR("MCT_EVENT_CONTROL_START_ZSL_SNAPSHOT max_led_on_period set to %d",max_led_on_period);
memset(&stats_get, 0, sizeof(stats_get_data_t));
module_sensor_params =
@@ -6543,7 +6554,7 @@ static boolean module_sensor_module_process_event(mct_module_t *module,
aec_update.hdr_sensitivity_ratio = stats_get.aec_get.hdr_sensitivity_ratio;
aec_update.hdr_exp_time_ratio = stats_get.aec_get.hdr_exp_time_ratio;
aec_update.total_drc_gain = stats_get.aec_get.total_drc_gain;
- SLOW("get stats led trigger %d ",stats_get.aec_get.trigger_led);
+ SERR("MCT_EVENT_CONTROL_START_ZSL_SNAPSHOT get stats led trigger %d ",stats_get.aec_get.trigger_led);
if (stats_get.aec_get.trigger_led) {
module_sensor_params_t *led_module_params = NULL;
led_module_params =
@@ -6561,16 +6572,19 @@ static boolean module_sensor_module_process_event(mct_module_t *module,
delay_flash_on = 1;
if (led_module_params->func_tbl.process != NULL && !delay_flash_on) {
+ SERR("zjy module_sensor_module_process_event delay_flash_on is false");
uint8_t flash_mode;
cam_flash_mode_t cam_flash_mode;
if (bundle_info.s_bundle->longshot) {
- flash_mode = LED_FLASH_SET_TORCH;
- cam_flash_mode = CAM_FLASH_MODE_TORCH;
+ //flash_mode = LED_FLASH_SET_TORCH;
+ //cam_flash_mode = CAM_FLASH_MODE_TORCH;
+ flash_mode = LED_FLASH_SET_OFF;
+ cam_flash_mode = CAM_FLASH_MODE_OFF;
} else {
flash_mode = LED_FLASH_SET_MAIN_FLASH;
cam_flash_mode = CAM_FLASH_MODE_ON;
}
- SHIGH("Sending flash mode downstream - %d", cam_flash_mode);
+ SERR("MCT_EVENT_CONTROL_START_ZSL_SNAPSHOT Sending flash mode downstream - %d", cam_flash_mode);
sensor_util_post_downstream_event(module, event->identity,
MCT_EVENT_MODULE_SET_FLASH_MODE, &cam_flash_mode);
@@ -6699,10 +6713,10 @@ static boolean module_sensor_module_process_event(mct_module_t *module,
DONE:
if (stats_get.aec_get.valid_entries > 1 &&
bundle_info.s_bundle->sensor_common_info.ae_bracket_params.enable) {
- if (FALSE == module_sensor_set_frame_skip_for_isp(module, event,
- bundle_info.s_bundle, TRUE, CAM_STREAM_TYPE_SNAPSHOT)) {
- SERR("failed");
- }
+ //if (FALSE == module_sensor_set_frame_skip_for_isp(module, event,
+ // bundle_info.s_bundle, TRUE, CAM_STREAM_TYPE_SNAPSHOT)) {
+ // SERR("failed");
+ // }
}
MCT_PROF_LOG_END();
@@ -8106,7 +8120,7 @@ mct_module_t *module_sensor_init(const char *name)
SHIGH("PDAF driver Version: %s", PDAF_DRIVER_VERSION);
SHIGH("PDAF SDK capabilities: %s", PDAF_SDK_CAPABILITIES);
-
+ SERR("zjy module_sensor module_sensor_init");
/* Create MCT module for sensor */
s_module = mct_module_create(name);
if (!s_module) {
diff --git a/mm-camera/mm-camera2/media-controller/modules/sensors/module/port_sensor.c b/mm-camera/mm-camera2/media-controller/modules/sensors/module/port_sensor.c
index 43b233e..e6bd6d2 100755
--- a/mm-camera/mm-camera2/media-controller/modules/sensors/module/port_sensor.c
+++ b/mm-camera/mm-camera2/media-controller/modules/sensors/module/port_sensor.c
@@ -407,7 +407,7 @@ boolean port_sensor_handle_aec_update(
SERR("failed");
return FALSE;
}
- SLOW("stats sensor_gain %f real_gain=%f lnct %d exp time %f",
+ SERR("port_sensor_handle_aec_update stats sensor_gain %f real_gain=%f lnct %d exp time %f",
stats_update->aec_update.sensor_gain, stats_update->aec_update.real_gain,
stats_update->aec_update.linecount, stats_update->aec_update.exp_time);
@@ -512,7 +512,7 @@ boolean port_sensor_handle_aec_update(
bundle_info->s_bundle->state = SENSOR_AEC_EST_DONE;
SHIGH ("AEC EST DONE");
if (bundle_info->s_bundle->partial_flash_frame_skip
- && bundle_info->s_bundle->hal_version == CAM_HAL_V1) {
+ && bundle_info->s_bundle->hal_version == CAM_HAL_V1 && !(s_bundle->longshot)) {
port_sensor_aec_est_frame_skip(module, event, bundle_info);
} else {
if (led_module_params->func_tbl.process != NULL) {
@@ -588,18 +588,19 @@ boolean port_sensor_handle_aec_update(
if(rc != TRUE)
SERR("Failure posting to the bus!");
} else if (stats_update->aec_update.est_state == AEC_EST_START
- && bundle_info->s_bundle->state != SENSOR_AEC_EST_START) {
- SHIGH("AEC EST START");
+ && bundle_info->s_bundle->state != SENSOR_AEC_EST_START && !(s_bundle->longshot)) {
+ SERR("port_sensor_handle_aec_update AEC EST START");
bundle_info->s_bundle->state = SENSOR_AEC_EST_START;
if (bundle_info->s_bundle->dual_led_calib_enabled) {
if (led_module_params->func_tbl.process != NULL) {
- SLOW("In dual LED calibration mode");
+ SERR("port_sensor_handle_aec_update In dual LED calibration mode");
rc = led_module_params->func_tbl.process(
led_module_params->sub_module_private,
LED_FLASH_SET_MAIN_FLASH, NULL);
if (rc < 0) {
- SERR("failed: LED_FLASH_SET_MAIN_FLASH");
+ SERR("port_sensor_handle_aec_update failed: LED_FLASH_SET_MAIN_FLASH");
} else {
+ SERR("port_sensor_handle_aec_update LED_FLASH_SET_MAIN_FLASH sucess");
bundle_info->s_bundle->sensor_params.flash_mode =
CAM_FLASH_MODE_ON;
bundle_info->s_bundle->sensor_params.flash_state =
@@ -612,6 +613,7 @@ boolean port_sensor_handle_aec_update(
&& bundle_info->s_bundle->hal_version == CAM_HAL_V1) {
port_sensor_aec_est_frame_skip(module, event, bundle_info);
} else if (led_module_params->func_tbl.process != NULL) {
+ SERR("port_sensor_handle_aec_update failed: LED_FLASH_SET_PRE_FLASH");
rc = led_module_params->func_tbl.process(
led_module_params->sub_module_private,
LED_FLASH_SET_PRE_FLASH, NULL);
总结:
最终修改位置如下:
1./vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c中的module_sensor_module_process_event方法:
2. /vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/port_sensor.c中的port_sensor_handle_aec_update方法:
3.调试方法:在/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors$位置输入mma,编译成功后,会生成libmmcamera2_sensor_modules.so库在out目录的vendor/lib里面,将该文件push到手机的vendor/lib目录下,重启手机即可生效。