Beispiel #1
0
Point computeVfromM() {
/*
	Knowing M(X, Y, Z), V(x, y, z) is defined by the three following equations :
(1)		x² + y² + z² = upperArmLength²
(2)		(x - X)² + (y - Y)² + (z - Z)² = lowerArmLength²
(3)		Xy = Yx
	The last one imply that the whole arm is in a vertical plane.
	The system as two solutions, we want the one with the biggest z coordinate.

	RESOLUTION: We substitue (1) in (2) and the system become (with no nul M coord)
(1)		x² + y² + z² = upperArmLength²
(2)		z = (A - xX - yY) / Z
			where A = (X² + Y² + Z² + upperArmLength² - lowerArmLength²) / 2
(3)		y = Y/X * x

	We then obtains the following 2nd degree equation in x :
		x² + Y²/X² * x² + (A - xX - Y²/X * x)² / Z² = upperArmLength²
	=>	(1 + Y²/X² + (X + Y²/X)²/Z²) * x² - 2A(X + Y²/X)/Z² * x + A²/Z² - upperArmLength² = 0

	If (x == 0)
(1)		y² + z² = upperArmLength²
(2)		y = (A - zZ) / Y
	=> (1 + Z²/Y²) * z² - 2AZ/Y² * z + A² / Y² - upperArmLength² = 0

*/
	float	X2 = M.x * M.x,
			Y2 = M.y * M.y;

	if (F_EQUAL(M.z, 0)) {
		return Point(M.x / 2, M.y / 2, static_cast<float>(sqrt(
			upperArmLength * upperArmLength - X2 / 4 - Y2 / 4)));
	}

	float	Z2 = M.z * M.z,
			A = (X2 + Y2 + Z2 + upperArmLength * upperArmLength - lowerArmLength * lowerArmLength) / 2;

	if (F_EQUAL(M.x, 0)) {
		float dumb = 0, z = 0;
		sol2ndDegree(1 + Z2 / Y2, -2 * A * M.z / Y2, A * A / Y2 - upperArmLength * upperArmLength, dumb, z);
		return Point(0, (A - z * M.z) / M.y, z);
	} else if (F_EQUAL(M.y, 0)) {
		float dumb = 0, z = 0;
		sol2ndDegree(1 + Z2 / X2, -2 * A * M.z / X2, A * A / X2 - upperArmLength * upperArmLength, dumb, z);
		return Point((A - z * M.z) / M.x, 0, z);
	}

	float x1 = 0, x2 = 0;
	sol2ndDegree(	1 + Y2 / X2 + (M.x + Y2 / M.x) * (M.x + Y2 / M.x) / Z2,
					-2 * A * (M.x + Y2 / M.x) / Z2,
					A * A / Z2 - upperArmLength * upperArmLength,
					x1, x2);

	float	z1 = (A - x1 * M.x - x1 * Y2 / M.x) / M.z,
			z2 = (A - x2 * M.x - x2 * Y2 / M.x) / M.z;

	if (z1 > z2)
		return Point(x1, x1 * M.y / M.x, z1);
	else
		return Point(x2, x2 * M.y / M.x, z2);
}
Beispiel #2
0
/** color_correct_set_effect:
 *    @mod: pointer to instance private data
 *    @in_params: input data
 *    @in_params_size: size of input data
 *
 * Set effect.
 *
 * This function executes in ISP thread context
 *
 * Return 0 on success.
 **/
static int color_correct_set_effect(isp_color_correct_mod_t *mod,
  isp_hw_pix_setting_params_t *in_params, uint32_t in_param_size)
{
  int type;
  float s;
  if (in_param_size != sizeof(isp_hw_pix_setting_params_t)) {
    /* size mismatch */
    CDBG_ERROR("%s: size mismatch, expecting = %d, received = %d",
      __func__, sizeof(isp_hw_pix_setting_params_t), in_param_size);
    return -1;
  }

  if (!mod->enable) {
    ISP_DBG(ISP_MOD_COLOR_CORRECT, "%s: CC not enabled", __func__);
    return 0;
  }
  type = in_params->effects.effect_type_mask;
  SET_UNITY_MATRIX(mod->effects_matrix, 3);
  if (type & (1 << ISP_EFFECT_SATURATION)) {
    s = 2.0 * in_params->effects.saturation;
    if (F_EQUAL(in_params->effects.hue, 0))
      util_color_correct_populate_matrix(mod->effects_matrix, s);
  }
  if (type & (1 << ISP_EFFECT_HUE)) {
    s = 2.0 * in_params->effects.hue;
    if (!F_EQUAL(in_params->effects.saturation, .5))
      util_color_correct_populate_matrix(mod->effects_matrix, s);
  }
  mod->hw_update_pending = TRUE;
  return 0;
} /*color_correct_set_effect*/
Beispiel #3
0
/*===========================================================================
 * FUNCTION      vfe_wb_trigger_update
 *
 * DESCRIPTION
 *==========================================================================*/
vfe_status_t vfe_wb_trigger_update(int mod_id, void *mod_wb, void *vparms)
{
  vfe_status_t status = VFE_SUCCESS;
  wb_mod_t* mod = (wb_mod_t*)mod_wb;
  vfe_params_t* params = (vfe_params_t*)vparms;

  int is_snap = IS_SNAP_MODE(params);
  int index = (is_snap) ? SNAP : PREV;
  int update = FALSE;
  if (!mod->enable) {
    CDBG("%s: WB not enabled", __func__);
    return VFE_SUCCESS;
  }

  if (!mod->trigger_enable) {
    CDBG("%s: WB trigger not enabled", __func__);
    return VFE_SUCCESS;
  }

  if (params->demosaic_wb_not_present && is_snap) {
    CDBG("%s: WB update not required in snapshot, hardcode the values",
      __func__);
    INIT_WB_GAIN(mod->awb_gain[SNAP], 1.0, 1.0, 1.0);
    return VFE_SUCCESS;
  }

  CDBG("%s: snap %d old %f %f %f new %f %f %f", __func__, is_snap,
    mod->awb_gain[index].g_gain,
    mod->awb_gain[index].b_gain,
    mod->awb_gain[index].r_gain,
    params->awb_params.gain.g_gain,
    params->awb_params.gain.b_gain,
    params->awb_params.gain.r_gain);

  if ((is_snap || !IS_MANUAL_WB(params)) &&
    !WB_GAIN_EQUAL(params->awb_params.gain, mod->awb_gain[index])
    && !WB_GAIN_EQ_ZERO(params->awb_params.gain)) {
    mod->awb_gain[index].g_gain = params->awb_params.gain.g_gain;
    mod->awb_gain[index].b_gain = params->awb_params.gain.b_gain;
    mod->awb_gain[index].r_gain = params->awb_params.gain.r_gain;
    params->awb_gain_update = TRUE;
    update = TRUE;
  } 

  if (!F_EQUAL(params->aec_gain_adj.wb_gain_adj,
    mod->dig_gain[index])) {
    mod->dig_gain[index] = params->aec_gain_adj.wb_gain_adj;
    update = TRUE;
  } 

  if (!update) {
    CDBG("%s: No update required", __func__);
    return VFE_SUCCESS;
  }

  mod->update = TRUE;
  CDBG("%s: updated", __func__);
  return status;
} /* vfe_wb_trigger_update */
Beispiel #4
0
// Utility function giving in order solutions of a 2nd degree polynom
void sol2ndDegree(float a, float b, float c, float& sMin, float& sMax) {
	bool aIsNull = F_EQUAL(a, 0);
	float delta = b * b - 4 * a *c;
	if (delta < 0 || (aIsNull && F_EQUAL(b, 0))) {
		TRACE_("ERROR: no solution in \'sol2ndDegree\' with"
		<< "\n a = " << a
		<< "\n b = " << b
		<< "\n c = " << c);
		exit(13);
	}
	if (aIsNull) {
		sMin = sMax = c / b;
	} else {
		sMin = (-b - static_cast<float>(sqrt(delta))) / 2 / a;
		sMax = (-b + static_cast<float>(sqrt(delta))) / 2 / a;
	}
}
Beispiel #5
0
/** color_conversion_set_effect:
 *
 *    @mod:
 *    @in_params:
 *    @in_param_size:
 *
 * Set special effect
 *
 **/
static int color_conversion_set_effect(isp_color_conversion_mod_t *mod,
  isp_hw_pix_setting_params_t *in_params, uint32_t in_param_size)
{
  if (in_param_size != sizeof(isp_hw_pix_setting_params_t)) {
    CDBG_ERROR("%s: size mismatch, expecting = %d, received = %d",
      __func__, sizeof(isp_hw_pix_setting_params_t), in_param_size);
    return -1;
  }

  int i = 0, j = 0;
  ISP_DBG(ISP_MOD_COLOR_CONV, "%s",__func__);
  float hue_matrix[2][2];
  float sat_matrix[2][2];
  float s, hue_in_radian;
  int type;
  int status= 0;

  if (in_params->bestshot_mode != CAM_SCENE_MODE_OFF) {
    ISP_DBG(ISP_MOD_COLOR_CONV, "%s: Best shot enabled, skip set effect", __func__);
    return 0;
  }

  s = 2.0 * in_params->effects.saturation;
  hue_in_radian = DEGREE_TO_RADIAN(in_params->effects.hue * 10); //ryan need to define in pix_common.h

  type = in_params->effects.effect_type_mask;

  if(type & (1 << ISP_EFFECT_SPECIAL)) {
    status = color_conversion_set_spl_effect(mod, in_params, in_param_size);
    if (status)
      goto END;
  }

  if(type & (1 << ISP_EFFECT_SATURATION)) {
    SET_UNITY_MATRIX(mod->effects_matrix, 2);
    SET_SAT_MATRIX(sat_matrix, s);
  }

  if(type & (1 << ISP_EFFECT_HUE)) {
    if (F_EQUAL(in_params->effects.hue, 0)) {
      SET_UNITY_MATRIX(hue_matrix, 2);
    } else {
      SET_HUE_MATRIX(hue_matrix, hue_in_radian);
    }

    MATRIX_MULT(sat_matrix, hue_matrix, mod->effects_matrix, 2, 2, 2);
  }

#ifdef ENABLE_CV_LOGGING
  PRINT_2D_MATRIX(2, 2, mod->effects_matrix);
#endif

  mod->hw_update_pending = TRUE;

END:
  return status;
}/*color_conversion_set_effect*/
Beispiel #6
0
/** clf_chroma_trigger_update:
 *    @mod: CLF module instance
 *    @in_params: triger update data
 *    @in_param_size: update data size
 *
 *  This function runs in ISP HW thread context.
 *
 *  This function updates parametes and sets flag for hw update if needed
 *  for chroma filtering
 *
 *  Return:  0 - Success
 *          -1 - parameter size mismatch
 **/
static int clf_chroma_trigger_update(isp_clf_mod_t *mod,
  isp_pix_trigger_update_input_t *in_params, uint32_t in_param_size)
{
  chromatix_parms_type *chroma_ptr =
    (chromatix_parms_type *)in_params->cfg.chromatix_ptrs.chromatixPtr;
  chromatix_CL_filter_type *chromatix_CL_filter =
    &chroma_ptr->chromatix_VFE.chromatix_CL_filter;

  trigger_point_type  *p_trigger_point = NULL;
  int8_t is_burst = IS_BURST_STREAMING(&(in_params->cfg));
  tuning_control_type tuning_type;
  int8_t update_cf = FALSE;
  float ratio;
  Chroma_filter_type *p_cf_new = &(mod->clf_params.cf_param);
  Chroma_filter_type *p_cf = NULL;
  int8_t cf_enabled = mod->cf_enable && mod->cf_enable_trig;
  int status = 0;

  if (in_param_size != sizeof(isp_pix_trigger_update_input_t)) {
    /* size mismatch */
  CDBG_ERROR("%s: size mismatch, expecting = %d, received = %d",
      __func__, sizeof(isp_pix_trigger_update_input_t), in_param_size);
    return -1;
  }

  if (!cf_enabled) {
    ISP_DBG(ISP_MOD_CLF, "%s: Chroma filter trigger not enabled %d %d", __func__,
      mod->cf_enable, mod->cf_enable_trig);
    return 0;
  }

  mod->cf_update = FALSE;

  tuning_type = chromatix_CL_filter->control_chroma_filter;
  p_trigger_point = &chromatix_CL_filter->chroma_filter_trigger_lowlight;
  p_cf = chromatix_CL_filter->chroma_filter;

  ratio = isp_util_get_aec_ratio(mod->notify_ops->parent, tuning_type,
    p_trigger_point, &(in_params->trigger_input.stats_update.aec_update),
    is_burst);

  update_cf = (mod->old_streaming_mode != in_params->cfg.streaming_mode) ||
    !F_EQUAL(ratio, mod->cur_cf_aec_ratio);

  if (update_cf) {
    util_clf_chroma_interpolate(&p_cf[1], &p_cf[0], p_cf_new, ratio);
    mod->old_streaming_mode = in_params->cfg.streaming_mode;
    mod->cur_cf_aec_ratio = ratio;
    mod->cf_update = TRUE;
  }

  return status;
} /* clf_chroma_trigger_update */
Beispiel #7
0
/*===========================================================================
 * FUNCTION    - vfe_chroma_suppresion_trigger_update -
 *
 * DESCRIPTION:
 *==========================================================================*/
vfe_status_t vfe_chroma_suppresion_trigger_update(int mod_id, void *mod_csupp,
  void *parms)
{
  float lux_idx, ratio;
  int Diff, Q_slope;
  tuning_control_type *tc;
  trigger_point_type  *tp;
  cs_luma_threshold_type *cs_luma_threshold, *cs_luma_threshold_lowlight;
  VFE_ChromaSuppress_ConfigCmdType *chroma_supp_cmd;
  uint8_t update_cs = FALSE;
  chroma_supp_mod_t *mod = (chroma_supp_mod_t *)mod_csupp;
  vfe_params_t *p_obj = (vfe_params_t *)parms;

  tc = &(p_obj->chroma3a->control_cs);

  if (!mod->chroma_supp_enable) {
    CDBG("%s: Chroma Suppression not enabled", __func__);
    return VFE_SUCCESS;
  }
  if (!mod->chroma_supp_trigger) {
    CDBG("%s: Chroma Suppression trigger not enabled", __func__);
    return VFE_SUCCESS;
  }
  switch (p_obj->vfe_op_mode) {
    case VFE_OP_MODE_PREVIEW:
    case VFE_OP_MODE_VIDEO:
    case VFE_OP_MODE_ZSL:
      tp = &(p_obj->chroma3a->cs_lowlight_trigger);
      cs_luma_threshold = &(p_obj->chroma3a->cs_luma_threshold);
      cs_luma_threshold_lowlight =
        &(p_obj->chroma3a->cs_luma_threshold_lowlight);
      chroma_supp_cmd = &(mod->chroma_supp_video_cmd);
      break;
    case VFE_OP_MODE_SNAPSHOT:
    case VFE_OP_MODE_JPEG_SNAPSHOT:
      tp = &(p_obj->chroma3a->cs_snapshot_lowlight_trigger);
      cs_luma_threshold = &(p_obj->chroma3a->cs_luma_threshold_snapshot);
      cs_luma_threshold_lowlight =
        &(p_obj->chroma3a->cs_luma_threshold_snapshot_lowlight);
      chroma_supp_cmd = &(mod->chroma_supp_snap_cmd);
      break;
    default:
      CDBG_ERROR("%s, invalid mode = %d",__func__, p_obj->vfe_op_mode);
      return VFE_ERROR_GENERAL;
  }
  ratio = vfe_util_get_aec_ratio(*tc, tp, p_obj);
  if (ratio > 1.0)
    ratio = 1.0;
  else if (ratio < 0.0)
    ratio = 0.0;

  update_cs = ((mod->prev_mode != p_obj->vfe_op_mode) ||
    !F_EQUAL(mod->prev_aec_ratio, ratio));

  CDBG("%s: update_cs : %d\n", __func__, update_cs);
  if (!update_cs) {
    CDBG("%s: Chroma Suppression update not required", __func__);
    return VFE_SUCCESS;
  }

  mod->prev_mode = p_obj->vfe_op_mode;
  mod->prev_aec_ratio = ratio;

  /* luma threshold */
  chroma_supp_cmd->ySup1 = LINEAR_INTERPOLATION_INT(cs_luma_threshold->
    cs_luma_threshold1, cs_luma_threshold_lowlight->cs_luma_threshold1, ratio);
  chroma_supp_cmd->ySup2 = LINEAR_INTERPOLATION_INT(cs_luma_threshold->
    cs_luma_threshold2, cs_luma_threshold_lowlight->cs_luma_threshold2, ratio);

  Diff = chroma_supp_cmd->ySup2 - chroma_supp_cmd->ySup1;
  Diff = Clamp(Diff, 4, 127);
  chroma_supp_cmd->ySup2 = chroma_supp_cmd->ySup1 + Diff;

  Q_slope = (int)ceil(log((double)Diff) / log(2.0)) + 6;
  chroma_supp_cmd->ySupM1 = (1 << Q_slope) / Diff;
  chroma_supp_cmd->ySupS1 = Q_slope - 7;

  chroma_supp_cmd->ySup3 = LINEAR_INTERPOLATION_INT(cs_luma_threshold->
    cs_luma_threshold3, cs_luma_threshold_lowlight->cs_luma_threshold3, ratio);
  chroma_supp_cmd->ySup4 = LINEAR_INTERPOLATION_INT(cs_luma_threshold->
    cs_luma_threshold4, cs_luma_threshold_lowlight->cs_luma_threshold4, ratio);

  Diff = chroma_supp_cmd->ySup4 - chroma_supp_cmd->ySup3;
  Diff = Clamp(Diff, 4, 127);
  chroma_supp_cmd->ySup3 = chroma_supp_cmd->ySup4 - Diff;

  Q_slope = (int)ceil(log((double)Diff) / log(2.0)) + 6;
  chroma_supp_cmd->ySupM3 = (1 << Q_slope) / Diff;
  chroma_supp_cmd->ySupS3 = Q_slope - 7;

  /* chroma threshold */
  chroma_supp_cmd->cSup1 = LINEAR_INTERPOLATION_INT(cs_luma_threshold->
    cs_chroma_threshold1,
    cs_luma_threshold_lowlight->cs_chroma_threshold1, ratio);
  chroma_supp_cmd->cSup2 = LINEAR_INTERPOLATION_INT(cs_luma_threshold->
    cs_chroma_threshold2,
    cs_luma_threshold_lowlight->cs_chroma_threshold2, ratio);
  Diff = chroma_supp_cmd->cSup2 - chroma_supp_cmd->cSup1;
  Diff = Clamp(Diff, 4, 127);
  chroma_supp_cmd->cSup2 = chroma_supp_cmd->cSup1 + Diff;

  Q_slope = (int)ceil(log((double)Diff) / log(2.0)) + 6;
  chroma_supp_cmd->cSupM1 = (1 << Q_slope) / Diff;
  chroma_supp_cmd->cSupS1 = Q_slope - 7;

  mod->chroma_supp_update = TRUE;

  return VFE_SUCCESS;
} /* vfe_trigger_update_chroma_suppresion */
Beispiel #8
0
/** demux_trigger_update:
 *    @demux_mod: demux module instance
 *    @trigger_params: module trigger update params
 *    @in_param_size: enable parameter size
 *
 *  This function runs in ISP HW thread context.
 *
 *  This function checks and initiates triger update of module
 *
 *  Return:   0 - Success
 *           -1 - Parameters size mismatch
 **/
static int demux_trigger_update(isp_demux_mod_t *demux_mod,
  isp_pix_trigger_update_input_t *trigger_params, uint32_t in_param_size)
{
  isp_hw_pix_setting_params_t *pix_setting = &trigger_params->cfg;
  chromatix_parms_type *chromatix_ptr =
    pix_setting->chromatix_ptrs.chromatixPtr;
  chromatix_channel_balance_gains_type *chromatix_channel_balance_gains =
    &chromatix_ptr->chromatix_VFE.chromatix_channel_balance_gains;
  AEC_algo_struct_type *AEC_algo_data = &chromatix_ptr->AEC_algo_data;
  ISP_DemuxConfigCmdType* p_cmd = &demux_mod->ISP_DemuxConfigCmd;
  float max_gain = 0.0, gain = 0.0, new_dig_gain = 1.0;
  float max_ch_gain = 0.0;
  demux_mod->remaining_digital_gain = 1.0; /* set to unitity */

  if(!demux_mod->enable || !demux_mod->trigger_enable) {
    ISP_DBG(ISP_MOD_DEMUX, "%s: no trigger update for DEMUX, trigger_enable = %d, enable =%d\n",
         __func__, demux_mod->enable, demux_mod->trigger_enable);

    return 0;
  }

  ISP_DBG(ISP_MOD_DEMUX, "%s: dig gain %5.3f", __func__,
    trigger_params->trigger_input.digital_gain);
  if (trigger_params->trigger_input.digital_gain < 1.0)
    trigger_params->trigger_input.digital_gain = 1.0;

  max_ch_gain = MAX(chromatix_channel_balance_gains->green_odd,
      MAX(chromatix_channel_balance_gains->green_even,
      MAX(chromatix_channel_balance_gains->red,
        chromatix_channel_balance_gains->blue)));

  ISP_DBG(ISP_MOD_DEMUX, "%s: max_ch_gain %5.3f glob %5.3f", __func__, max_ch_gain,
    AEC_algo_data->color_correction_global_gain);
  max_gain = max_ch_gain * AEC_algo_data->color_correction_global_gain *
    trigger_params->trigger_input.digital_gain;

  ISP_DBG(ISP_MOD_DEMUX, "%s: max_gain_final %5.3f", __func__, max_gain);
  if (max_gain > MAX_DEMUX_GAIN) {
    new_dig_gain = MAX_DEMUX_GAIN/
      (AEC_algo_data->color_correction_global_gain * max_ch_gain);
    demux_mod->remaining_digital_gain = max_gain/MAX_DEMUX_GAIN;
  } else {
    new_dig_gain = max_gain/
      (AEC_algo_data->color_correction_global_gain * max_ch_gain);
  }

  ISP_DBG(ISP_MOD_DEMUX, "%s: dig_gain_old %5.3f new %5.3f", __func__, demux_mod->dig_gain,
    new_dig_gain);
  if (F_EQUAL(demux_mod->dig_gain, new_dig_gain)
    && (pix_setting->streaming_mode == demux_mod->old_streaming_mode)) {
    ISP_DBG(ISP_MOD_DEMUX, "%s: No update required", __func__);

    return 0;
  }

  demux_mod->old_streaming_mode = pix_setting->streaming_mode;
  demux_mod->dig_gain = new_dig_gain;

  gain = AEC_algo_data->color_correction_global_gain * demux_mod->dig_gain;
  demux_mod->gain.green_odd = gain * chromatix_channel_balance_gains->green_odd;
  demux_mod->gain.green_even = gain *
    chromatix_channel_balance_gains->green_even;
  demux_mod->gain.red = gain *
    chromatix_channel_balance_gains->red;
  demux_mod->gain.blue = gain *
    chromatix_channel_balance_gains->blue;

  p_cmd->ch0EvenGain = DEMUX_GAIN(demux_mod->gain.green_even);
  p_cmd->ch0OddGain = DEMUX_GAIN(demux_mod->gain.green_odd);
  p_cmd->ch1Gain = DEMUX_GAIN(demux_mod->gain.blue);
  p_cmd->ch2Gain = DEMUX_GAIN(demux_mod->gain.red);

  /* 3D is not supported. */
  if (demux_mod->is_3d)
    demux_r_image_gain_update(demux_mod);

  demux_mod->hw_update_pending = TRUE;

  return 0;
}/*demux_trigger_update*/
Beispiel #9
0
/** color_conversion_trigger_update:
 *
 *    @mod:
 *    @in_params:
 *    @in_param_size:
 *
 * enable color_conversion trigger update feature
 *
 **/
static int color_conversion_trigger_update(isp_color_conversion_mod_t *mod,
  isp_pix_trigger_update_input_t *in_params, uint32_t in_param_size)
{
  int rc = 0;

  chromatix_parms_type *chromatix_ptr =
    in_params->cfg.chromatix_ptrs.chromatixPtr;
  chromatix_CV_type *chromatix_CV_ptr =
      &chromatix_ptr->chromatix_VFE.chromatix_CV;
  chromatix_gamma_type *chromatix_gamma =
    &(chromatix_ptr->chromatix_VFE.chromatix_gamma);
  int8_t update_cv = FALSE;
  aec_update_t *aec_params = &(in_params->trigger_input.stats_update.aec_update);
  trigger_ratio_t trigger_ratio;
  int is_burst = IS_BURST_STREAMING(&in_params->cfg);


  if (in_param_size != sizeof(isp_pix_trigger_update_input_t)) {
    /* size mismatch */
    CDBG_ERROR("%s: size mismatch, expecting = %d, received = %d",
      __func__, sizeof(isp_pix_trigger_update_input_t), in_param_size);
    return -1;
  }

  if (!mod->enable || !isp_util_aec_check_settled(aec_params) ||
      !mod->trigger_enable ||
      in_params->trigger_input.stats_update.awb_update.color_temp == 0) {
    ISP_DBG(ISP_MOD_COLOR_CONV, "%s: CV no trigger update required, enable = %d,"
      "trigger_enable = %d, aec_settled? %d\n", __func__, mod->enable,
      mod->trigger_enable, isp_util_aec_check_settled(aec_params));
    return 0;
  }

  /* Decide the trigger ratio for current lighting condition */
  rc = isp_util_get_aec_ratio2(mod->notify_ops->parent,
         chromatix_CV_ptr->control_cv,
         &(chromatix_gamma->gamma_outdoor_trigger),
         &(chromatix_CV_ptr->cv_trigger), aec_params, is_burst,
         &trigger_ratio);

  if (rc != 0)
    CDBG_ERROR("%s: get aec ratio error", __func__);

  update_cv = ((mod->old_streaming_mode != in_params->cfg.streaming_mode)
    || !F_EQUAL(trigger_ratio.ratio, mod->aec_ratio.ratio)
    || (trigger_ratio.lighting != mod->aec_ratio.lighting)
    || (mod->color_temp != in_params->trigger_input.stats_update.awb_update.color_temp));

  ISP_DBG(ISP_MOD_COLOR_CONV, "%s: update_cv %d ratio %f lighting %d colortemp %u", __func__,
    update_cv, trigger_ratio.ratio, trigger_ratio.lighting,
    in_params->trigger_input.stats_update.awb_update.color_temp);

  if (update_cv) {
    mod->cv_data = *(mod->p_cv);

    if(!IS_MANUAL_WB(in_params) && !F_EQUAL(trigger_ratio.ratio, 0.0))
      util_color_conversion_awb_update(mod, in_params, &mod->cv_data);

    util_color_conversion_aec_update(mod, in_params, &mod->cv_data, &trigger_ratio);
    mod->aec_ratio = trigger_ratio;
    mod->color_temp = in_params->trigger_input.stats_update.awb_update.color_temp;
    mod->old_streaming_mode = in_params->cfg.streaming_mode;
  }

  util_color_conversion_cmd_config(mod);
  mod->hw_update_pending = TRUE;

  return 0;
} /* color_conversion_trigger_update */
Beispiel #10
0
/** bpc_trigger_update
 *    @mod: bpc module control struct
 *    @in_params: input config params including chromatix ptr
 *    @in_param_size: input params struct size
 *
 *  BPC module modify reg settings as per new input params and
 *  trigger hw update
 *
 * Return: 0 - success and negative value - failure
 **/
static int bpc_trigger_update(isp_bpc_mod_t *mod,
  isp_pix_trigger_update_input_t *in_params, uint32_t in_param_size)
{
  int rc = 0;
  chromatix_parms_type *chromatix_ptr =
    in_params->cfg.chromatix_ptrs.chromatixPtr;
  chromatix_BPC_type *chromatix_BPC =
    &chromatix_ptr->chromatix_VFE.chromatix_BPC;
  chromatix_CS_MCE_type *chromatix_CS_MCE =
    &chromatix_ptr->chromatix_VFE.chromatix_CS_MCE;

  float aec_ratio;
  uint8_t update_bpc = TRUE;
  uint8_t Fmin, Fmin_lowlight, Fmax, Fmax_lowlight;
  tuning_control_type tunning_control;
  bpc_4_offset_type *bpc_normal_input_offset = NULL;
  bpc_4_offset_type *bpc_lowlight_input_offset = NULL;
  trigger_point_type *trigger_point = NULL;
  int is_snapmode, update_cs;

  if (in_param_size != sizeof(isp_pix_trigger_update_input_t)) {
    /* size mismatch */
    CDBG_ERROR("%s: size mismatch, expecting = %d, received = %d",
      __func__, sizeof(isp_pix_trigger_update_input_t), in_param_size);
    return -1;
  }

  if (!mod->enable || !mod->trigger_enable || mod->skip_trigger) {
    ISP_DBG(ISP_MOD_BPC, "%s: Skip Trigger update. enable %d, trig_enable %d, skip_trigger %d",
      __func__, mod->enable, mod->trigger_enable, mod->skip_trigger);
    return rc;
  }

  is_snapmode = IS_BURST_STREAMING(&in_params->cfg);
  if (!is_snapmode && !isp_util_aec_check_settled(
         &(in_params->trigger_input.stats_update.aec_update))) {
    ISP_DBG(ISP_MOD_BPC, "%s: AEC not settled", __func__);
    return rc;
  }

  ISP_DBG(ISP_MOD_BPC, "%s: Calculate table with AEC", __func__);
  if ((chromatix_BPC->bpc_Fmin > chromatix_BPC->bpc_Fmax) ||
      (chromatix_BPC->bpc_Fmin_lowlight > chromatix_BPC->bpc_Fmax_lowlight)) {
    CDBG_ERROR("%s: Error min>max: %d/%d; %d/%d\n", __func__,
      chromatix_BPC->bpc_Fmin, chromatix_BPC->bpc_Fmax,
      chromatix_BPC->bpc_Fmin_lowlight, chromatix_BPC->bpc_Fmax_lowlight);
    return -1;
  }

  trigger_point = &(chromatix_BPC->bpc_lowlight_trigger);
  Fmin = chromatix_BPC->bpc_Fmin;
  Fmax = chromatix_BPC->bpc_Fmax;
  Fmin_lowlight = chromatix_BPC->bpc_Fmin_lowlight;
  Fmax_lowlight = chromatix_BPC->bpc_Fmax_lowlight;
  bpc_normal_input_offset = &(chromatix_BPC->bpc_4_offset[BPC_NORMAL_LIGHT]);
  bpc_lowlight_input_offset = &(chromatix_BPC->bpc_4_offset[BPC_LOW_LIGHT]);

  tunning_control = chromatix_BPC->control_bpc;
  aec_ratio = isp_util_get_aec_ratio(mod->notify_ops->parent,
                chromatix_BPC->control_bpc, trigger_point,
                &(in_params->trigger_input.stats_update.aec_update),
                is_snapmode);
  update_cs = ((mod->old_streaming_mode != in_params->cfg.streaming_mode) ||
    !F_EQUAL(mod->aec_ratio, aec_ratio));

  if (!update_cs) {
    ISP_DBG(ISP_MOD_BPC, "%s: update not required", __func__);
    return 0;
  }

  if (F_EQUAL(aec_ratio, 0.0)) {
    ISP_DBG(ISP_MOD_BPC, "%s: Low Light \n", __func__);
    mod->p_params.p_input_offset = bpc_lowlight_input_offset;
    mod->p_params.p_Fmin = &(Fmin_lowlight);
    mod->p_params.p_Fmax = &(Fmax_lowlight);
    util_bpc_cmd_config(mod);
  } else if (F_EQUAL(aec_ratio, 1.0)) {
    ISP_DBG(ISP_MOD_BPC, "%s: Normal Light \n", __func__);
    mod->p_params.p_input_offset = bpc_normal_input_offset;
    mod->p_params.p_Fmin = &(Fmin);
    mod->p_params.p_Fmax = &(Fmax);
    util_bpc_cmd_config(mod);
  } else {
    ISP_DBG(ISP_MOD_BPC, "%s: Interpolate between Nomal and Low Light \n", __func__);
  /* Directly configure reg cmd.*/
    Fmin = (uint8_t)Round(LINEAR_INTERPOLATION(Fmin, Fmin_lowlight, aec_ratio));
    mod->RegCmd.fminThreshold = Fmin;

    Fmax = (uint8_t)Round(LINEAR_INTERPOLATION(Fmax, Fmax_lowlight, aec_ratio));
    mod->RegCmd.fmaxThreshold = Fmax;

    mod->RegCmd.rOffsetHi = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_r_hi,
      bpc_lowlight_input_offset->bpc_4_offset_r_hi, aec_ratio));
    mod->RegCmd.rOffsetLo = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_r_lo,
      bpc_lowlight_input_offset->bpc_4_offset_r_lo, aec_ratio));

    mod->RegCmd.bOffsetHi = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_b_hi,
      bpc_lowlight_input_offset->bpc_4_offset_b_hi, aec_ratio));
    mod->RegCmd.bOffsetLo = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_b_lo,
      bpc_lowlight_input_offset->bpc_4_offset_b_lo, aec_ratio));

    mod->RegCmd.grOffsetHi = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gr_hi,
      bpc_lowlight_input_offset->bpc_4_offset_gr_hi, aec_ratio));
    mod->RegCmd.grOffsetLo = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gr_lo,
      bpc_lowlight_input_offset->bpc_4_offset_gr_lo, aec_ratio));

    mod->RegCmd.gbOffsetHi = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gb_hi,
      bpc_lowlight_input_offset->bpc_4_offset_gb_hi, aec_ratio));
    mod->RegCmd.gbOffsetLo = (uint16_t)Round(LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gb_lo,
      bpc_lowlight_input_offset->bpc_4_offset_gb_lo, aec_ratio));
  }
  mod->aec_ratio = aec_ratio;

  util_bpc_cmd_debug(&(mod->RegCmd));
  mod->hw_update_pending = TRUE;
  return rc;
} /* bpc_trigger_update */
Beispiel #11
0
/** abf_trigger_update:
 *    @mod: pointer to instance private data
 *    @trigger_params: input data
 *    @in_params_size: size of input data
 *
 * Update configuration.
 *
 * This function executes in ISP thread context
 *
 * Return 0 on success.
 **/
static int abf_trigger_update(isp_abf_mod_t *mod,
  isp_pix_trigger_update_input_t *trigger_params, uint32_t in_param_size)
{
  int i = 0;
  chromatix_parms_type *chroma_ptr =
    trigger_params->cfg.chromatix_ptrs.chromatixPtr;
  chromatix_ABF2_type *chromatix_ABF2 =
    &chroma_ptr->chromatix_VFE.chromatix_ABF2;
  abf2_parms_t *abf2_parms = &(mod->abf2_parms);

  trigger_point_type *outdoor = NULL, *lowlight = NULL;
  trigger_ratio_t trigger_ratio;
  chromatix_adaptive_bayer_filter_data_type2 *p1 = NULL, *p2 = NULL,
      *abf2_normal, *abf2_outdoor, *abf2_lowlight;
  tuning_control_type tunning_control = chromatix_ABF2->control_abf2;
  uint8_t is_burst = IS_BURST_STREAMING((&trigger_params->cfg));

  if (!mod->enable || !mod->trigger_enable) {
    ISP_DBG(ISP_MOD_ABF, "%s: no trigger for ABF, enable = %d, trigger_ena = %d\n",
      __func__, mod->enable, mod->trigger_enable);
    return 0;
  }

  if (!isp_util_aec_check_settled(
    &trigger_params->trigger_input.stats_update.aec_update)) {
    ISP_DBG(ISP_MOD_ABF, "%s: AEC not settled", __func__);
    return 0;
  }

  outdoor = &(chromatix_ABF2->abf2_bright_light_trigger);
  lowlight = &(chromatix_ABF2->abf2_low_light_trigger);
  abf2_normal = &(chromatix_ABF2->abf2_config_normal_light);
  abf2_outdoor = &(chromatix_ABF2->abf2_config_bright_light);
  abf2_lowlight = &(chromatix_ABF2->abf2_config_low_light);

  /* Decide the trigger ratio for current lighting condition */
  if (isp_util_get_aec_ratio2(mod->notify_ops->parent, tunning_control,
        outdoor, lowlight,
        &trigger_params->trigger_input.stats_update.aec_update, is_burst,
         &trigger_ratio) != 0) {
    CDBG_HIGH("%s: get aec ratio error", __func__);
    return -1;
  }

  switch (trigger_ratio.lighting) {
  case TRIGGER_LOWLIGHT: {
    p1 = abf2_lowlight;
    p2 = abf2_normal;
  }
    break;

  case TRIGGER_OUTDOOR: {
    p1 = abf2_outdoor;
    p2 = abf2_normal;
  }
    break;

  default:
  case TRIGGER_NORMAL: {
    p1 = p2 = abf2_normal;
  }
    break;
  }

  if ((trigger_params->cfg.streaming_mode != mod->old_streaming_mode) ||
      (trigger_ratio.lighting != mod->aec_ratio.lighting) ||
      !F_EQUAL(trigger_ratio.ratio, mod->aec_ratio.ratio)) {
    /* Update abf2 */
    mod->hw_update_pending = 1;
    mod->old_streaming_mode = trigger_params->cfg.streaming_mode;
    mod->aec_ratio = trigger_ratio;

    if (!F_EQUAL(trigger_ratio.ratio, 0.0) &&
        !F_EQUAL(trigger_ratio.ratio, 1.0)) {
      abf_interpolate(p2, p1, abf2_parms, trigger_ratio.ratio);
    } else {
      memcpy(&abf2_parms->data, p1,
        sizeof(chromatix_adaptive_bayer_filter_data_type2));
    }

    abf_set_cmd_params2(&mod->RegCmd, abf2_parms);
  }

  return 0;
} /* abf_trigger_update */
Beispiel #12
0
/** mce_trigger_update:
 *    @mce_mod: pointer to instance private data
 *    @trigger_params: input data
 *    @in_params_size: size of input data
 *
 * Update configuration.
 *
 * This function executes in ISP thread context
 *
 * Return 0 on success.
 **/
static int mce_trigger_update(isp_mce_mod_t *mce_mod,
  isp_pix_trigger_update_input_t *trigger_params, uint32_t in_param_size)
{
  float ratio, fKg, fKb, fKr, max_boost;
  uint32_t dS1, dS3, QKg, QKb, QKr, Q_s1, Q_s3;
  ISP_MCE_ConfigCmdType *mce_config = &(mce_mod->mce_cmd);
  chromatix_parms_type *chromatix_ptr = trigger_params->cfg.chromatix_ptrs.chromatixPtr;
  chromatix_CS_MCE_type *pchromatix_CS_MCE =
    &chromatix_ptr->chromatix_VFE.chromatix_CS_MCE;
  ASD_struct_type *ASD_algo_data_ptr = &chromatix_ptr->ASD_algo_data;

  float landscape_green_boost_factor =
    ASD_algo_data_ptr->landscape_scene_detect.landscape_green_boost_factor;
  float landscape_blue_boost_factor =
    ASD_algo_data_ptr->landscape_scene_detect.landscape_blue_boost_factor;
  float landscape_red_boost_factor =
    ASD_algo_data_ptr->landscape_scene_detect.landscape_red_boost_factor;
  uint32_t landscape_severity = 0;
  float lux_idx;
  uint8_t update_mce = FALSE;

  if (in_param_size != sizeof(isp_pix_trigger_update_input_t)) {
    /* size mismatch */
    CDBG_ERROR("%s: size mismatch, expecting = %d, received = %d",
      __func__, sizeof(isp_pix_trigger_update_input_t), in_param_size);
    return -1;
  }

  lux_idx = trigger_params->trigger_input.stats_update.aec_update.lux_idx;

  /* check for trigger updation */
  update_mce = ((mce_mod->old_streaming_mode!= trigger_params->cfg.streaming_mode) ||
    !F_EQUAL(mce_mod->prev_lux_idx, lux_idx));
  if (!update_mce) {
    ISP_DBG(ISP_MOD_MCE, "%s: MCE update not required", __func__);
    return 0;
  } else {
    mce_mod->prev_lux_idx = lux_idx;
    mce_mod->old_streaming_mode = trigger_params->cfg.streaming_mode;
  }

  if (!mce_mod->mce_enable) {
    ISP_DBG(ISP_MOD_MCE, "%s: MCE not enabled", __func__);
    return 0;
  }
  if (mce_mod->mce_trigger_enable != TRUE) {
    ISP_DBG(ISP_MOD_MCE, "%s: MCE trigger not enabled\n", __func__);
    return 0;
  }
  if (!isp_util_aec_check_settled(
    &trigger_params->trigger_input.stats_update.aec_update)) {
    ISP_DBG(ISP_MOD_MCE, "%s: AEC not settled", __func__);
    return 0;
  }

  if (trigger_params->cfg.bestshot_mode == CAM_SCENE_MODE_LANDSCAPE)
    landscape_severity = 255; // 100 % severity
  else
    landscape_severity =
      MIN(255, trigger_params->trigger_input.stats_update.asd_update.landscape_severity);

  /* Compute MCE gains and Q_K first */
  /* Green */
  ratio = 1.0f - isp_util_calc_interpolation_weight(lux_idx,
      pchromatix_CS_MCE->mce_config.green_bright_index,
      pchromatix_CS_MCE->mce_config.green_dark_index);
  ISP_DBG(ISP_MOD_MCE, "ratio = %f, lux_idx %f\n", ratio, lux_idx);

  fKg = ratio * (pchromatix_CS_MCE->mce_config.green_boost_factor - 1.0f);
  /*add ratio for landscape severity  */
  ISP_DBG(ISP_MOD_MCE, "pre fKg =%f", fKg);
  fKg = ((fKg + 1) * (((float)landscape_severity / 255.0 *
    (landscape_green_boost_factor - 1)) + 1));

  max_boost = MAX(pchromatix_CS_MCE->mce_config.green_boost_factor,
      landscape_green_boost_factor);
  if (fKg > max_boost)
    fKg = max_boost;

  fKg = fKg - 1;
  ISP_DBG(ISP_MOD_MCE, "post fKg =%f", fKg);
  if (fKg > 0) {
    QKg = (uint8_t)ceil(log(4.0f / fKg) / log(2.0f)) + 6;
    while ((int32_t)(fKg * (1 << QKg)) > 383)
      QKg--;
  } else {
    fKg = 0;
    QKg = 15;
  }
  QKg = Clamp(QKg, 7, 15);

  /* Blue */
  ratio = 1.0f - isp_util_calc_interpolation_weight(lux_idx,
      pchromatix_CS_MCE->mce_config.blue_bright_index,
      pchromatix_CS_MCE->mce_config.blue_dark_index);
  fKb = ratio * (pchromatix_CS_MCE->mce_config.blue_boost_factor - 1.0f);
  /*add ratio for landscape severity */
  ISP_DBG(ISP_MOD_MCE, "pre fKb =%f", fKb);
  fKb = ((fKb + 1) * (((float)landscape_severity / 255.0 *
    (landscape_blue_boost_factor - 1)) + 1));

  max_boost = MAX(pchromatix_CS_MCE->mce_config.blue_boost_factor,
      landscape_blue_boost_factor);
  if (fKb > max_boost)
    fKb = max_boost;

  fKb = fKb - 1;
  ISP_DBG(ISP_MOD_MCE, "post fKb =%f", fKb);
  if (fKb > 0) {
    QKb = (uint8_t)ceil(log(4.0f / fKb) / log(2.0f)) + 6;
    while ((int32_t)(fKb * (1 << QKb)) > 383)
      QKb--;
  } else {
    fKb = 0;
    QKb = 15;
  }
  QKb = Clamp(QKb, 7, 15);

  /* Red */
  ratio = 1.0f - isp_util_calc_interpolation_weight(lux_idx,
      pchromatix_CS_MCE->mce_config.red_bright_index,
      pchromatix_CS_MCE->mce_config.red_dark_index);
  fKr = ratio * (pchromatix_CS_MCE->mce_config.red_boost_factor - 1.0f);
  ISP_DBG(ISP_MOD_MCE, "pre fKr =%f", fKr);
  /* add ratio for landscape severity */
  fKr = ((fKr + 1) * (((float)landscape_severity / 255.0 *
    (landscape_red_boost_factor - 1)) + 1));
  max_boost = MAX(pchromatix_CS_MCE->mce_config.red_boost_factor,
      landscape_red_boost_factor);
  if (fKr > max_boost)
    fKr = max_boost;

  fKr = fKr - 1;
  ISP_DBG(ISP_MOD_MCE, "post fKr =%f", fKr);
  if (fKr > 0) {
    QKr = (uint8_t)ceil(log(4.0f / fKr) / log(2.0f)) + 6;
    while ((int32_t)(fKr * (1 << QKr)) > 383)
      QKr--;
  } else {
    fKr = 0;
    QKr = 15;
  }
  QKr = Clamp(QKr, 7, 15);

  mce_mod->mce_mix_cmd_1.enable = mce_mod->mce_enable;
  /* Overall Q_K and gains */
  mce_mod->mce_mix_cmd_2.qk = MIN(MIN(QKg, QKb), QKr);
  mce_config->redCfg.K =
  (int32_t)(fKr * (1 << mce_mod->mce_mix_cmd_2.qk));
  mce_config->greenCfg.K =
  (int32_t)(fKg * (1 << mce_mod->mce_mix_cmd_2.qk));
  mce_config->blueCfg.K =
  (int32_t)(fKb * (1 << mce_mod->mce_mix_cmd_2.qk));

  /* Compute Y slopes */
  /* Green */

  dS1 = mce_config->greenCfg.y2 - mce_config->greenCfg.y1;
  dS3 = mce_config->greenCfg.y4 - mce_config->greenCfg.y3;

  if ((fKg > 0) && (dS1 > 0)) {
    Q_s1 = (int32_t)ceil(log(dS1 / fKg) / log(2.0f)) + 6;
    Q_s1 = Clamp(Q_s1, 7, 20);
    mce_config->greenCfg.yM1 = mce_config->greenCfg.K *
      (1 << (Q_s1 - mce_mod->mce_mix_cmd_2.qk)) / dS1;
  } else {
    Q_s1 = 20;
    mce_config->greenCfg.yM1 = 0;
  }

  mce_config->greenCfg.yS1 = Q_s1 - mce_mod->mce_mix_cmd_2.qk;
  if ((fKg > 0) && (dS3 > 0)) {
    Q_s3 = (int32_t)ceil(log(dS3 / fKg) / log(2.0f)) + 6;
    Q_s3 = Clamp(Q_s3, 7, 20);
    mce_config->greenCfg.yM3 = mce_config->greenCfg.K *
      (1 << (Q_s3 - mce_mod->mce_mix_cmd_2.qk)) / dS3;
  } else {
    Q_s3 = 20;
    mce_config->greenCfg.yM3 = 0;
  }

  mce_config->greenCfg.yS3 = Q_s3 - mce_mod->mce_mix_cmd_2.qk;
  /* Blue */
  dS1 = mce_config->blueCfg.y2 - mce_config->blueCfg.y1;
  dS3 = mce_config->blueCfg.y4 - mce_config->blueCfg.y3;

  if ((fKb > 0) && (dS1 > 0)) {
    Q_s1 = (int32_t)ceil(log(dS1 / fKb) / log(2.0f)) + 6;
    Q_s1 = Clamp(Q_s1, 7, 20);
    mce_config->blueCfg.yM1 = mce_config->blueCfg.K *
      (1 << (Q_s1 - mce_mod->mce_mix_cmd_2.qk)) / dS1;
  } else {
    Q_s1 = 20;
    mce_config->blueCfg.yM1 = 0;
  }
  mce_config->blueCfg.yS1 = Q_s1 - mce_mod->mce_mix_cmd_2.qk;

  if ((fKb > 0) && (dS3 > 0)) {
    Q_s3 = (int32_t)ceil(log(dS3 / fKb) / log(2.0f)) + 6;
    Q_s3 = Clamp(Q_s3, 7, 20);
    mce_config->blueCfg.yM3 = mce_config->blueCfg.K *
      (1 << (Q_s3 - mce_mod->mce_mix_cmd_2.qk)) / dS3;
  } else {
    Q_s3 = 20;
    mce_config->blueCfg.yM3 = 0;
  }

  mce_config->blueCfg.yS3 = Q_s3 - mce_mod->mce_mix_cmd_2.qk;
  /* Red */
  dS1 = mce_config->redCfg.y2 - mce_config->redCfg.y1;
  dS3 = mce_config->redCfg.y4 - mce_config->redCfg.y3;

  if ((fKr > 0) && (dS1 > 0)) {
    Q_s1 = (int32_t)ceil(log(dS1 / fKr) / log(2.0f)) + 6;
    Q_s1 = Clamp(Q_s1, 7, 20);
    mce_config->redCfg.yM1 = mce_config->redCfg.K *
      (1 << (Q_s1 - mce_mod->mce_mix_cmd_2.qk)) / dS1;
  } else {
    Q_s1 = 20;
    mce_config->redCfg.yM1 = 0;
  }
  mce_config->redCfg.yS1 = Q_s1 - mce_mod->mce_mix_cmd_2.qk;

  if ((fKr > 0) && (dS3 > 0)) {
    Q_s3 = (int32_t)ceil(log(dS3 / fKr) / log(2.0f)) + 6;
    Q_s3 = Clamp(Q_s3, 7, 20);
    mce_config->redCfg.yM3 = mce_config->redCfg.K *
      (1 << (Q_s3 - mce_mod->mce_mix_cmd_2.qk)) / dS3;
  } else {
    Q_s3 = 20;
    mce_config->redCfg.yM3 = 0;
  }
  mce_config->redCfg.yS3 = Q_s3 - mce_mod->mce_mix_cmd_2.qk;
  /* Compute C slopes */
  /* Green */
  mce_config->greenCfg.CBZone =
    pchromatix_CS_MCE->mce_config.green_cb_boundary;
  mce_config->greenCfg.CRZone =
    pchromatix_CS_MCE->mce_config.green_cr_boundary;
  mce_config->greenCfg.transWidth =
   (pchromatix_CS_MCE->mce_config.green_cb_transition_width +
   pchromatix_CS_MCE->mce_config.green_cr_transition_width) / 2;
  mce_config->greenCfg.transTrunc = (int32_t)ceil(log((float)(
    mce_config->greenCfg.transWidth)) / log(2.0f) ) + 4;
  mce_config->greenCfg.transTrunc =
    Clamp(mce_config->greenCfg.transTrunc, 6, 9);
  mce_config->greenCfg.transSlope =
  (1 << mce_config->greenCfg.transTrunc) /
  mce_config->greenCfg.transWidth;
  /* Blue */
  mce_config->blueCfg.CBZone = pchromatix_CS_MCE->mce_config.blue_cb_boundary;
  mce_config->blueCfg.CRZone = pchromatix_CS_MCE->mce_config.blue_cr_boundary;
  mce_config->blueCfg.transWidth =
    (pchromatix_CS_MCE->mce_config.blue_cb_transition_width +
    pchromatix_CS_MCE->mce_config.blue_cr_transition_width) / 2;
  mce_config->blueCfg.transTrunc = (int32_t)ceil(log((float)(
    mce_config->blueCfg.transWidth)) / log(2.0f)) + 4;
  mce_config->blueCfg.transTrunc =
  Clamp(mce_config->blueCfg.transTrunc, 6, 9);
  mce_config->blueCfg.transSlope =
  (1 << mce_config->blueCfg.transTrunc) /
  mce_config->blueCfg.transWidth;
  /* Red */
  mce_config->redCfg.CBZone =
    pchromatix_CS_MCE->mce_config.red_cb_boundary;
  mce_config->redCfg.CRZone =
  pchromatix_CS_MCE->mce_config.red_cr_boundary;
  mce_config->redCfg.transWidth =
    (pchromatix_CS_MCE->mce_config.red_cb_transition_width +
     pchromatix_CS_MCE->mce_config.red_cr_transition_width) / 2;
  mce_config->redCfg.transTrunc = (int32_t)ceil(log((float)(
    mce_config->redCfg.transWidth)) / log(2.0f)) + 4;
  mce_config->redCfg.transTrunc =
  Clamp(mce_config->redCfg.transTrunc, 6, 9);
  mce_config->redCfg.transSlope =
    (1 << mce_config->redCfg.transTrunc) / mce_config->redCfg.transWidth;

  mce_mod->mce_update = TRUE;

  if (mce_mod->cnt == 0) {
    ISP_DBG(ISP_MOD_MCE, "MCE_landscape_severity = %d\n", landscape_severity);
    ISP_DBG(ISP_MOD_MCE, "MCE aec ratio = %f, aec_out->lux_idx %f\n", ratio, lux_idx);
    mce_mod->hw_update_pending = TRUE;
  }
  mce_mod->cnt++;
  if (mce_mod->cnt == 6)
    mce_mod->cnt = 0;
  return 0;
} /* mce_trigger_update */
Beispiel #13
0
/** clf_luma_trigger_update:
 *    @mod: CLF module instance
 *    @in_params: triger update data
 *    @in_param_size: update data size
 *
 *  This function runs in ISP HW thread context.
 *
 *  This function updates parametes and sets flag for hw update if needed
 *  for luma filtering
 *
 *  Return:  0 - Success
 *           Otherwise - get AEC ratio failed
 **/
static int clf_luma_trigger_update(isp_clf_mod_t *mod,
  isp_pix_trigger_update_input_t *in_params, uint32_t in_param_size)
{
  trigger_point_type  *p_trigger_low = NULL, *p_trigger_bright = NULL;
  int8_t is_burst = IS_BURST_STREAMING(&(in_params->cfg));
  tuning_control_type tuning_type;
  int8_t update_lf = FALSE;
  float ratio;
  trigger_ratio_t trig_ratio;
  chromatix_parms_type *chroma_ptr =
    (chromatix_parms_type *)in_params->cfg.chromatix_ptrs.chromatixPtr;
  chromatix_ABF2_type *chromatix_ABF2 =
    &chroma_ptr->chromatix_VFE.chromatix_ABF2;
  int8_t lf_enabled = mod->lf_enable && mod->lf_enable_trig;
  int status = 0;

  if (!lf_enabled) {
    ISP_DBG(ISP_MOD_CLF, "%s: Luma filter trigger not enabled %d %d", __func__,
       mod->lf_enable, mod->lf_enable_trig);

    return status;
  }

  chromatix_adaptive_bayer_filter_data_type2 *p_lf_new =
    &(mod->clf_params.lf_param);
  chromatix_adaptive_bayer_filter_data_type2 *p_lf1 = NULL, *p_lf2 = NULL;

  mod->lf_update = FALSE;

  tuning_type = chromatix_ABF2->control_abf2;
  p_trigger_low = &chromatix_ABF2->abf2_low_light_trigger;
  p_trigger_bright = &chromatix_ABF2->abf2_bright_light_trigger;

  status = isp_util_get_aec_ratio2(mod->notify_ops->parent, tuning_type,
    p_trigger_bright, p_trigger_low,
    &(in_params->trigger_input.stats_update.aec_update), is_burst, &trig_ratio);

  if (status != 0)
    CDBG_HIGH("%s: get aec ratio failed", __func__);

  switch (trig_ratio.lighting) {
  case TRIGGER_LOWLIGHT:
    p_lf1 = &chromatix_ABF2->abf2_config_low_light;
    p_lf2 = &chromatix_ABF2->abf2_config_normal_light;
    break;

  case TRIGGER_OUTDOOR:
    p_lf1 = &chromatix_ABF2->abf2_config_bright_light;
    p_lf2 = &chromatix_ABF2->abf2_config_normal_light;
    break;

  case TRIGGER_NORMAL:
  default:
    p_lf1 = p_lf2 = &chromatix_ABF2->abf2_config_normal_light;
    break;
  }

  update_lf =
   (trig_ratio.lighting != mod->cur_lf_aec_ratio.lighting) ||
   (trig_ratio.ratio != mod->cur_lf_aec_ratio.ratio) ||
   (in_params->cfg.streaming_mode != mod->old_streaming_mode);

  ISP_DBG(ISP_MOD_CLF, "%s: update_lf %d ratio %f lighting %d", __func__, update_lf,
    trig_ratio.ratio, trig_ratio.lighting);
  if (update_lf) {
    if(F_EQUAL(trig_ratio.ratio, 0.0) || F_EQUAL(trig_ratio.ratio, 1.0))
      *p_lf_new = *p_lf1;
    else
      util_clf_luma_interpolate(p_lf2, p_lf1, p_lf_new, trig_ratio.ratio);

    mod->cur_lf_aec_ratio = trig_ratio;
    /* need to handle for luma case */
    mod->old_streaming_mode = in_params->cfg.streaming_mode;
    mod->lf_update = TRUE;
  }

  return status;
} /* clf_luma_trigger_update */
Beispiel #14
0
/*===========================================================================
 * FUNCTION      linearization_trigger_update
 *
 * DESCRIPTION
 *==========================================================================*/
static int linearization_trigger_update(isp_linear_mod_t *linear_mod,
                                        isp_pix_trigger_update_input_t *trigger_params, uint32_t in_param_size)
{
    int rc = 0;
    int is_burst = IS_BURST_STREAMING(&trigger_params->cfg);
    long bl_lux_index_end, bl_lux_index_start;
    long ll_lux_index_end, ll_lux_index_start;
    isp_linear_lux_t lux = LINEAR_AEC_NORMAL;
    awb_cct_type cct_type;
    chromatix_linearization_type output;
    uint8_t update_linear = FALSE;

    chromatix_parms_type *chroma3a =
        (chromatix_parms_type *)trigger_params->cfg.chromatix_ptrs.chromatixPtr;
    chromatix_black_level_type *pchromatix_black_level =
        &chroma3a->chromatix_VFE.chromatix_black_level;
    chromatix_VFE_common_type *pchromatix_common =
        (chromatix_VFE_common_type *)
        trigger_params->cfg.chromatix_ptrs.chromatixComPtr;
    chromatix_L_type *pchromatix_L =
        &pchromatix_common->chromatix_L;

    if (in_param_size != sizeof(isp_pix_trigger_update_input_t)) {
        /* size mismatch */
        CDBG_ERROR("%s: size mismatch, expecting = %d, received = %d",
                   __func__, sizeof(isp_pix_trigger_update_input_t), in_param_size);
        return -1;
    }

    if (!linear_mod->linear_enable) {
        ISP_DBG(ISP_MOD_LINEARIZATION , "%s: linearization not enabled", __func__);
        return 0;
    }

    if (!linear_mod->linear_trigger_enable) {
        ISP_DBG(ISP_MOD_LINEARIZATION , "%s: linearization tigger not enabled", __func__);
        return 0;
    }

    if ((!isp_util_aec_check_settled(
                &(trigger_params->trigger_input.stats_update.aec_update))) &&
            (trigger_params->trigger_input.flash_mode != CAM_FLASH_MODE_TORCH)) {
        ISP_DBG(ISP_MOD_LINEARIZATION , "%s: AEC not settled", __func__);
        return 0;
    }

    linear_mod->trigger_info.mired_color_temp =
        MIRED(trigger_params->trigger_input.stats_update.awb_update.color_temp);
    CALC_CCT_TRIGGER_MIRED(linear_mod->trigger_info.trigger_A,
                           pchromatix_L->linear_A_trigger);
    CALC_CCT_TRIGGER_MIRED(linear_mod->trigger_info.trigger_d65,
                           pchromatix_L->linear_D65_trigger);

    // get the cct type
    cct_type = isp_util_get_awb_cct_type(linear_mod->notify_ops->parent,
                                         &linear_mod->trigger_info, chroma3a);

    // get the low light trigger points
    ll_lux_index_end = pchromatix_L->linearization_lowlight_trigger.lux_index_end;
    ll_lux_index_start = pchromatix_L->linearization_lowlight_trigger.lux_index_start;

    // get the low light trigger points
    bl_lux_index_end =
        pchromatix_black_level->blk_lowlight_trigger.lux_index_end;
    bl_lux_index_start =
        pchromatix_black_level->blk_lowlight_trigger.lux_index_start;

    /*============================================*/
    /* AEC :Decision */
    /*============================================*/
    float lux_idx = trigger_params->trigger_input.stats_update.aec_update.lux_idx;

    if (lux_idx >= ll_lux_index_end)
        lux = LINEAR_AEC_LOW;
    else if (lux_idx < ll_lux_index_end  &&  lux_idx >= ll_lux_index_start)
        lux = LINEAR_AEC_NORMAL_LOW;
    else if (lux_idx < ll_lux_index_start)
        lux = LINEAR_AEC_NORMAL;
    else
        CDBG_HIGH("%s: Lux index is invalid\n", __func__);

    /* check for trigger updation */
    update_linear = ((linear_mod->old_streaming_mode != trigger_params->cfg.streaming_mode) ||
                     !F_EQUAL(linear_mod->prev_lux, lux) || !F_EQUAL(linear_mod->prev_cct_type, cct_type));

    if ((update_linear) || (!F_EQUAL(linear_mod->prev_lux_idx, lux_idx) &
                            ( lux == LINEAR_AEC_NORMAL_LOW ))) {
        select_linear_table(linear_mod, lux, cct_type, &output,
                            trigger_params);
        config_linearization_cmd(linear_mod, &output);
        linear_mod->hw_update_pending = TRUE;
        ISP_DBG(ISP_MOD_LINEARIZATION , "%s: color temp %d", __func__, trigger_params->trigger_input.
                stats_update.awb_update.color_temp);
        ISP_DBG(ISP_MOD_LINEARIZATION , "%s: lux index %f", __func__, trigger_params->trigger_input.
                stats_update.aec_update.lux_idx);
        ISP_DBG(ISP_MOD_LINEARIZATION , "%s: AEC type prev %s new %s", __func__,
                aec_debug_str[linear_mod->prev_lux],aec_debug_str[lux]);
        ISP_DBG(ISP_MOD_LINEARIZATION , "%s: AWB type prev %s new %s", __func__,
                awb_debug_str[linear_mod->prev_cct_type],
                awb_debug_str[cct_type]);
        linear_mod->old_streaming_mode = trigger_params->cfg.streaming_mode;
        linear_mod->prev_lux = lux;
        linear_mod->prev_cct_type = cct_type;
        linear_mod->prev_lux_idx = lux_idx;
    }
    return 0;

} /* linearization_trigger_update */
Beispiel #15
0
/*===========================================================================
 * FUNCTION    - vfe_demosaic_bpc_trigger_update -
 *
 * DESCRIPTION:
 *==========================================================================*/
vfe_status_t vfe_demosaic_bpc_trigger_update(bpc_mod_t *bpc_ctrl,
  vfe_params_t *vfe_params)
{

  uint8_t dbpcFmin, dbpcFmin_lowlight, dbpcFmax, dbpcFmax_lowlight;
  uint8_t dbccFmin, dbccFmin_lowlight, dbccFmax, dbccFmax_lowlight;
  tuning_control_type bpc_tuning_control, bcc_tuning_control;
  float new_bpc_trigger_ratio, new_bcc_trigger_ratio;
  VFE_DemosaicDBPC_CmdType *cmd = NULL;
  bpc_4_offset_type *bpc_normal_input_offset = NULL,
    *bcc_normal_input_offset = NULL;
  bpc_4_offset_type *bpc_lowlight_input_offset = NULL,
    *bcc_lowlight_input_offset = NULL;
  trigger_point_type *bpc_trigger_point = NULL, *bcc_trigger_point = NULL;
  chromatix_parms_type *chrPtr = vfe_params->chroma3a;

  static vfe_op_mode_t cur_mode = VFE_OP_MODE_INVALID;

  if (!bpc_ctrl->enable) {
    CDBG("%s: bpc is not enabled. Skip the config\n", __func__);
    return VFE_SUCCESS;
  }

  bpc_ctrl->trigger_update = FALSE;
  bpc_tuning_control = chrPtr->control_bpc;
  bcc_tuning_control = chrPtr->control_bcc;

  if (!bpc_ctrl->trigger_enable) {
    CDBG("%s: Trigger is disable. Skip the trigger update.\n", __func__);
    return VFE_SUCCESS;
  }

  if (IS_SNAP_MODE(vfe_params)) {
    bpc_trigger_point = &(chrPtr->bpc_snapshot_lowlight_trigger);
    bcc_trigger_point = &(chrPtr->bcc_snapshot_lowlight_trigger);

    dbpcFmin = chrPtr->bpc_Fmin_snapshot;
    dbpcFmax = chrPtr->bpc_Fmax_snapshot;
    dbpcFmin_lowlight = chrPtr->bpc_Fmin_snapshot_lowlight;
    dbpcFmax_lowlight = chrPtr->bpc_Fmax_snapshot_lowlight;

    dbccFmin = chrPtr->bcc_Fmin_snapshot;
    dbccFmax = chrPtr->bcc_Fmax_snapshot;
    dbccFmin_lowlight = chrPtr->bcc_Fmin_snapshot_lowlight;
    dbccFmax_lowlight = chrPtr->bcc_Fmax_snapshot_lowlight;

    bpc_normal_input_offset = &(chrPtr->bpc_4_offset_snapshot[BPC_NORMAL_LIGHT]);
    bpc_lowlight_input_offset = &(chrPtr->bpc_4_offset_snapshot[BPC_LOW_LIGHT]);
    bcc_normal_input_offset = &(chrPtr->bcc_4_offset_snapshot[BPC_NORMAL_LIGHT]);
    bcc_lowlight_input_offset = &(chrPtr->bcc_4_offset_snapshot[BPC_LOW_LIGHT]);
    cmd = &(bpc_ctrl->bpc_snap_cmd);
  } else {
    if (!vfe_util_aec_check_settled(&(vfe_params->aec_params))) {
      if (!bpc_ctrl->reload_params) {
        CDBG("%s: AEC is not setteled. Skip the trigger\n", __func__);
        return VFE_SUCCESS;
      }
    }

    bpc_trigger_point = &(chrPtr->bpc_lowlight_trigger);
    bcc_trigger_point = &(chrPtr->bcc_lowlight_trigger);

    dbpcFmin = chrPtr->bpc_Fmin_preview;
    dbpcFmax = chrPtr->bpc_Fmax_preview;
    dbpcFmin_lowlight = chrPtr->bpc_Fmin_preview_lowlight;
    dbpcFmax_lowlight = chrPtr->bpc_Fmax_preview_lowlight;

    dbccFmin = chrPtr->bcc_Fmin_preview;
    dbccFmax = chrPtr->bcc_Fmax_preview;
    dbccFmin_lowlight = chrPtr->bcc_Fmin_preview_lowlight;
    dbccFmax_lowlight = chrPtr->bcc_Fmax_preview_lowlight;

    bpc_normal_input_offset = &(chrPtr->bpc_4_offset[BPC_NORMAL_LIGHT]);
    bpc_lowlight_input_offset = &(chrPtr->bpc_4_offset[BPC_LOW_LIGHT]);
    bcc_normal_input_offset = &(chrPtr->bcc_4_offset[BPC_NORMAL_LIGHT]);
    bcc_lowlight_input_offset = &(chrPtr->bcc_4_offset[BPC_LOW_LIGHT]);
    cmd = &(bpc_ctrl->bpc_prev_cmd);
  }

  new_bpc_trigger_ratio = vfe_util_get_aec_ratio(bpc_tuning_control, bpc_trigger_point,
    vfe_params);
  new_bcc_trigger_ratio = vfe_util_get_aec_ratio(bcc_tuning_control, bcc_trigger_point,
    vfe_params);

  if (cur_mode != vfe_params->vfe_op_mode || bpc_ctrl->reload_params ||
    !F_EQUAL(new_bpc_trigger_ratio, bpc_ctrl->bpc_trigger_ratio) ||
    !F_EQUAL(new_bcc_trigger_ratio, bpc_ctrl->bcc_trigger_ratio)) {

    cmd->dbpcFmin = (uint8_t)LINEAR_INTERPOLATION(dbpcFmin, dbpcFmin_lowlight,
      new_bpc_trigger_ratio);
    cmd->dbpcFmax = (uint8_t)LINEAR_INTERPOLATION(dbpcFmax, dbpcFmax_lowlight,
      new_bpc_trigger_ratio);

    cmd->RdbpcOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_r_hi,
      bpc_lowlight_input_offset->bpc_4_offset_r_hi, new_bpc_trigger_ratio);
    cmd->RdbpcOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_r_lo,
      bpc_lowlight_input_offset->bpc_4_offset_r_lo, new_bpc_trigger_ratio);

    cmd->BdbpcOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_b_hi,
      bpc_lowlight_input_offset->bpc_4_offset_b_hi, new_bpc_trigger_ratio);
    cmd->BdbpcOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_b_lo,
      bpc_lowlight_input_offset->bpc_4_offset_b_lo, new_bpc_trigger_ratio);

    cmd->GRdbpcOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gr_hi,
      bpc_lowlight_input_offset->bpc_4_offset_gr_hi, new_bpc_trigger_ratio);
    cmd->GRdbpcOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gr_lo,
      bpc_lowlight_input_offset->bpc_4_offset_gr_lo, new_bpc_trigger_ratio);

    cmd->GBdbpcOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gb_hi,
      bpc_lowlight_input_offset->bpc_4_offset_gb_hi, new_bpc_trigger_ratio);
    cmd->GBdbpcOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bpc_normal_input_offset->bpc_4_offset_gb_lo,
      bpc_lowlight_input_offset->bpc_4_offset_gb_lo, new_bpc_trigger_ratio);

    cmd->dbccFmin = (uint8_t)LINEAR_INTERPOLATION(dbccFmin, dbccFmin_lowlight,
      new_bcc_trigger_ratio);
    cmd->dbccFmax = (uint8_t)LINEAR_INTERPOLATION(dbccFmax, dbccFmax_lowlight,
      new_bcc_trigger_ratio);

    cmd->RdbccOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_r_hi,
      bcc_lowlight_input_offset->bpc_4_offset_r_hi, new_bcc_trigger_ratio);
    cmd->RdbccOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_r_lo,
      bcc_lowlight_input_offset->bpc_4_offset_r_lo, new_bcc_trigger_ratio);

    cmd->BdbpcOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_b_hi,
      bcc_lowlight_input_offset->bpc_4_offset_b_hi, new_bcc_trigger_ratio);
    cmd->BdbpcOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_b_lo,
      bcc_lowlight_input_offset->bpc_4_offset_b_lo, new_bcc_trigger_ratio);

    cmd->GRdbpcOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_gr_hi,
      bcc_lowlight_input_offset->bpc_4_offset_gr_hi, new_bcc_trigger_ratio);
    cmd->GRdbpcOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_gr_lo,
      bcc_lowlight_input_offset->bpc_4_offset_gr_lo, new_bcc_trigger_ratio);

    cmd->GBdbpcOffHi = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_gb_hi,
      bcc_lowlight_input_offset->bpc_4_offset_gb_hi, new_bcc_trigger_ratio);
    cmd->GBdbpcOffLo = (uint16_t)LINEAR_INTERPOLATION(
      bcc_normal_input_offset->bpc_4_offset_gb_lo,
      bcc_lowlight_input_offset->bpc_4_offset_gb_lo, new_bcc_trigger_ratio);

    cur_mode = vfe_params->vfe_op_mode;
    bpc_ctrl->bpc_trigger_ratio = new_bpc_trigger_ratio;
    bpc_ctrl->bcc_trigger_ratio = new_bcc_trigger_ratio;
    bpc_ctrl->trigger_update = TRUE;
    bpc_ctrl->reload_params = FALSE;
  } else {
    CDBG("%s: No update required.\n", __func__);
  }

  return VFE_SUCCESS;
} /* vfe_demosaic_bpc_trigger_update */
Beispiel #16
0
/** vfe_sce_trigger_update
 *
 * DESCRIPTION: trigger update by aec/awb trigger event
 *
 **/
static int sce_trigger_update( isp_sce_mod_t *sce_mod,
  isp_pix_trigger_update_input_t *trigger_params,
  uint32_t in_param_size)
{
  uint8_t update_sce = FALSE;
  chromatix_parms_type *chroma_ptr =
     (chromatix_parms_type *)trigger_params->cfg.chromatix_ptrs.chromatixPtr;
  chromatix_SCE_type *chromatix_SCE = &chroma_ptr->chromatix_VFE.chromatix_SCE;
  float aec_ratio = 0.0;
  tuning_control_type *tc = &(chromatix_SCE->control_SCE);
  trigger_point_type  *tp = &(chromatix_SCE->SCE_trigger);
  uint8_t is_burst = IS_BURST_STREAMING((&trigger_params->cfg));

  if (!sce_mod->sce_enable) {
    ISP_DBG(ISP_MOD_SCE, "%s: SCE not enabled", __func__);
    return 0;
  }
  if (!sce_mod->sce_trigger_enable) {
    ISP_DBG(ISP_MOD_SCE, "%s: SCE trigger not enabled", __func__);
    return 0;
  }
  if (trigger_params->trigger_input.stats_update.awb_update.color_temp == 0) {
    ISP_DBG(ISP_MOD_SCE, "%s: SCE zero color temperature", __func__);
    return 0;
  }

  sce_mod->trigger_info.mired_color_temp =
    MIRED(trigger_params->trigger_input.stats_update.awb_update.color_temp);

  CALC_CCT_TRIGGER_MIRED(sce_mod->trigger_info.trigger_A,
    chromatix_SCE->SCE_A_trigger);
  CALC_CCT_TRIGGER_MIRED(sce_mod->trigger_info.trigger_d65,
    chromatix_SCE->SCE_D65_trigger);

  awb_cct_type cct_type = isp_util_get_awb_cct_type(sce_mod->notify_ops->parent,
    &sce_mod->trigger_info, chroma_ptr);
  aec_ratio = isp_util_get_aec_ratio(sce_mod->notify_ops->parent,*tc, tp,
    &trigger_params->trigger_input.stats_update.aec_update, is_burst);

  /* check for trigger updation */
  update_sce = ((sce_mod->old_streaming_mode != trigger_params->cfg.streaming_mode) ||
    (sce_mod->prev_sce_adj != sce_mod->sce_adjust_factor) ||
    !F_EQUAL(sce_mod->prev_aec_ratio, aec_ratio) || !F_EQUAL(sce_mod->prev_cct_type, cct_type));

  if(update_sce) {
    ISP_DBG(ISP_MOD_SCE, "Prev SCE Adj factor: %lf new: %lf", sce_mod->prev_sce_adj,
      sce_mod->sce_adjust_factor);
    ISP_DBG(ISP_MOD_SCE, "Prev mode: %d new: %d", sce_mod->old_streaming_mode, trigger_params->cfg.streaming_mode);
    ISP_DBG(ISP_MOD_SCE, "Prev aec ratio %f new %f", sce_mod->prev_aec_ratio, aec_ratio);
    ISP_DBG(ISP_MOD_SCE, "Prev cct type %d new %d", sce_mod->prev_cct_type, cct_type);
    trigger_sce_get_triangles(sce_mod, trigger_params, aec_ratio, cct_type);
    config_sce_cmd(sce_mod, trigger_params);
    sce_mod->old_streaming_mode = trigger_params->cfg.streaming_mode;
    sce_mod->prev_aec_ratio = aec_ratio;
    sce_mod->prev_cct_type = cct_type;
    sce_mod->prev_sce_adj = sce_mod->sce_adjust_factor;
    sce_mod->hw_update_pending = TRUE;
  } else {
      ISP_DBG(ISP_MOD_SCE, "%s: no updates\n",__func__);
  }

  return 0;
} /* vfe_sce_trigger_update */