/* * aiq3a_util.cpp - aiq 3a utility: * * Copyright (c) 2015 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: Wind Yuan * Author: Shincy Tu */ #include "aiq3a_utils.h" #include "x3a_isp_config.h" #include "x3a_statistics_queue.h" #include "cam_types.h" namespace XCam { bool translate_3a_stats (XCam3AStats *from, struct cifisp_stat_buffer *to) { XCAM_ASSERT (from); XCAM_ASSERT (to); XCamGridStat *standard_data = from->stats; for (uint32_t i = 0; i < 5; ++i) { for (uint32_t j = 0; j < 5; ++j) { to->params.ae.exp_mean[i * 5 + j] = standard_data[i * 5 + j].avg_y; } } #if RKISP to->params.awb.awb_mean[0].mean_y_or_g = standard_data[0].mean_y_or_g; to->params.awb.awb_mean[0].mean_cr_or_r = standard_data[0].mean_cr_or_r; to->params.awb.awb_mean[0].mean_cb_or_b = standard_data[0].mean_cb_or_b; #else to->params.awb.awb_mean[0].mean_r = standard_data[0].mean_cr_or_r; to->params.awb.awb_mean[0].mean_g = standard_data[0].mean_y_or_g; to->params.awb.awb_mean[0].mean_b = standard_data[0].mean_cb_or_b; to->params.awb.awb_mean[0].mean_y = standard_data[0].mean_y_or_g; to->params.awb.awb_mean[0].mean_cb = standard_data[0].mean_cb_or_b; to->params.awb.awb_mean[0].mean_cr = standard_data[0].mean_cr_or_r; to->params.awb.awb_mean[0].cnt = standard_data[0].valid_wb_count; #endif uint32_t hist_bins = 16; uint32_t *hist_y = from->hist_y; for (uint32_t i = 0; i < hist_bins; i++) { to->params.hist.hist_bins[i] = hist_y[i]; } return true; } static void matrix_3x3_mutiply (double *dest, const double *src1, const double *src2) { dest[0] = src1[0] * src2[0] + src1[1] * src2[3] + src1[2] * src2[6]; dest[1] = src1[0] * src2[1] + src1[1] * src2[4] + src1[2] * src2[7]; dest[2] = src1[0] * src2[2] + src1[1] * src2[5] + src1[2] * src2[8]; dest[3] = src1[3] * src2[0] + src1[4] * src2[3] + src1[5] * src2[6]; dest[4] = src1[3] * src2[1] + src1[4] * src2[4] + src1[5] * src2[7]; dest[5] = src1[3] * src2[2] + src1[4] * src2[5] + src1[5] * src2[8]; dest[6] = src1[6] * src2[0] + src1[7] * src2[3] + src1[8] * src2[6]; dest[7] = src1[6] * src2[1] + src1[7] * src2[4] + src1[8] * src2[7]; dest[8] = src1[6] * src2[2] + src1[7] * src2[5] + src1[8] * src2[8]; } static uint32_t translate_rkisp_parameters ( const struct rkisp_parameters &rkisp_params, XCam3aResultHead *results[], uint32_t max_count) { uint32_t result_count = 0; double coefficient = 0.0; XCAM_ASSERT (result_count < max_count); XCam3aResultAll *all = xcam_malloc0_type (XCam3aResultAll); all->head.type = XCAM_3A_RESULT_ALL; all->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; all->head.version = xcam_version (); all->active_configs = rkisp_params.active_configs; all->dpcc_config = rkisp_params.dpcc_config; all->bls_config = rkisp_params.bls_config; all->sdg_config = rkisp_params.sdg_config; all->hst_config = rkisp_params.hst_config; all->lsc_config = rkisp_params.lsc_config; all->awb_gain_config = rkisp_params.awb_gain_config; all->awb_meas_config = rkisp_params.awb_meas_config; all->flt_config = rkisp_params.flt_config; all->bdm_config = rkisp_params.bdm_config; all->ctk_config = rkisp_params.ctk_config; all->goc_config = rkisp_params.goc_config; all->cproc_config = rkisp_params.cproc_config; all->aec_config = rkisp_params.aec_config; all->afc_config = rkisp_params.afc_config; all->ie_config = rkisp_params.ie_config; all->dpf_config = rkisp_params.dpf_config; all->dpf_strength_config = rkisp_params.dpf_strength_config; all->aec_config = rkisp_params.aec_config; all->flt_denoise_level= rkisp_params.flt_denoise_level; all->flt_sharp_level= rkisp_params.flt_sharp_level; for (int i=0; i < HAL_ISP_MODULE_MAX_ID_ID + 1; i++) { all->enabled[i] = rkisp_params.enabled[i]; } results[result_count++] = (XCam3aResultHead*)all; #if 0 /* Translation for white balance */ XCAM_ASSERT (result_count < max_count); if (rkisp_params.wb_config) { XCam3aResultWhiteBalance *wb = xcam_malloc0_type (XCam3aResultWhiteBalance); XCAM_ASSERT (wb); wb->head.type = XCAM_3A_RESULT_WHITE_BALANCE; wb->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; wb->head.version = xcam_version (); coefficient = pow (2, (16 - rkisp_params.wb_config->integer_bits)); wb->r_gain = rkisp_params.wb_config->r / coefficient; wb->gr_gain = rkisp_params.wb_config->gr / coefficient; wb->gb_gain = rkisp_params.wb_config->gb / coefficient; wb->b_gain = rkisp_params.wb_config->b / coefficient; results[result_count++] = (XCam3aResultHead*)wb; } /* Translation for black level correction */ XCAM_ASSERT (result_count < max_count); if (rkisp_params.ob_config) { XCam3aResultBlackLevel *blc = xcam_malloc0_type (XCam3aResultBlackLevel); XCAM_ASSERT (blc); blc->head.type = XCAM_3A_RESULT_BLACK_LEVEL; blc->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; blc->head.version = xcam_version (); if (rkisp_params.ob_config->mode == rkisp_ob_mode_fixed) { blc->r_level = rkisp_params.ob_config->level_r / (double)65536; blc->gr_level = rkisp_params.ob_config->level_gr / (double)65536; blc->gb_level = rkisp_params.ob_config->level_gb / (double)65536; blc->b_level = rkisp_params.ob_config->level_b / (double)65536; } results[result_count++] = (XCam3aResultHead*)blc; } /* Translation for color correction */ XCAM_ASSERT (result_count < max_count); if (rkisp_params.yuv2rgb_cc_config) { static const double rgb2yuv_matrix [XCAM_COLOR_MATRIX_SIZE] = { 0.299, 0.587, 0.114, -0.14713, -0.28886, 0.436, 0.615, -0.51499, -0.10001 }; static const double r_ycgco_matrix [XCAM_COLOR_MATRIX_SIZE] = { 0.25, 0.5, 0.25, -0.25, 0.5, -0.25, 0.5, 0, -0.5 }; double tmp_matrix [XCAM_COLOR_MATRIX_SIZE] = {0.0}; double cc_matrix [XCAM_COLOR_MATRIX_SIZE] = {0.0}; XCam3aResultColorMatrix *cm = xcam_malloc0_type (XCam3aResultColorMatrix); XCAM_ASSERT (cm); cm->head.type = XCAM_3A_RESULT_RGB2YUV_MATRIX; cm->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; cm->head.version = xcam_version (); coefficient = pow (2, rkisp_params.yuv2rgb_cc_config->fraction_bits); for (int i = 0; i < XCAM_COLOR_MATRIX_SIZE; i++) { tmp_matrix [i] = rkisp_params.yuv2rgb_cc_config->matrix [i] / coefficient; } matrix_3x3_mutiply (cc_matrix, tmp_matrix, r_ycgco_matrix); matrix_3x3_mutiply (cm->matrix, rgb2yuv_matrix, cc_matrix); //results = yuv2rgb_matrix * tmp_matrix * r_ycgco_matrix results[result_count++] = (XCam3aResultHead*)cm; } /* Translation for gamma table */ XCAM_ASSERT (result_count < max_count); if (rkisp_params.g_gamma_table) { XCam3aResultGammaTable *gt = xcam_malloc0_type (XCam3aResultGammaTable); XCAM_ASSERT (gt); gt->head.type = XCAM_3A_RESULT_G_GAMMA; gt->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; gt->head.version = xcam_version (); for (int i = 0; i < XCAM_GAMMA_TABLE_SIZE; i++) { gt->table[i] = (double)rkisp_params.g_gamma_table->data.vamem_2[i] / 16; } results[result_count++] = (XCam3aResultHead*)gt; } /* Translation for macc matrix table */ XCAM_ASSERT (result_count < max_count); if (rkisp_params.macc_config) { XCam3aResultMaccMatrix *macc = xcam_malloc0_type (XCam3aResultMaccMatrix); XCAM_ASSERT (macc); macc->head.type = XCAM_3A_RESULT_MACC; macc->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; macc->head.version = xcam_version (); coefficient = pow (2, (13 - rkisp_params.macc_config->color_effect)); for (int i = 0; i < XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE; i++) { macc->table[i] = (double)rkisp_params.macc_table->data[i] / coefficient; } results[result_count++] = (XCam3aResultHead*)macc; } /* Translation for defect pixel correction */ XCAM_ASSERT (result_count < max_count); if (rkisp_params.dp_config) { XCam3aResultDefectPixel *dpc = xcam_malloc0_type (XCam3aResultDefectPixel); XCAM_ASSERT (dpc); dpc->head.type = XCAM_3A_RESULT_DEFECT_PIXEL_CORRECTION; dpc->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; dpc->head.version = xcam_version (); coefficient = pow (2, 16); dpc->gr_threshold = rkisp_params.dp_config->threshold / coefficient; dpc->r_threshold = rkisp_params.dp_config->threshold / coefficient; dpc->b_threshold = rkisp_params.dp_config->threshold / coefficient; dpc->gb_threshold = rkisp_params.dp_config->threshold / coefficient; results[result_count++] = (XCam3aResultHead*)dpc; } /* OCL has defined BNR config, no need to translate ISP BNR config */ #if 0 /* Translation for bnr config */ XCAM_ASSERT (result_count < max_count); if (rkisp_params.nr_config) { XCam3aResultBayerNoiseReduction *bnr = xcam_malloc0_type (XCam3aResultBayerNoiseReduction); XCAM_ASSERT (bnr); bnr->head.type = XCAM_3A_RESULT_BAYER_NOISE_REDUCTION; bnr->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; bnr->head.version = xcam_version (); bnr->bnr_gain = (double)rkisp_params.nr_config->bnr_gain / pow(2, 16); bnr->direction = (double)rkisp_params.nr_config->direction / pow(2, 16); results[result_count++] = (XCam3aResultHead*)bnr; } #endif #endif return result_count; } uint32_t translate_3a_results_to_xcam (X3aResultList &list, XCam3aResultHead *results[], uint32_t max_count) { uint32_t result_count = 0; for (X3aResultList::iterator iter = list.begin (); iter != list.end (); ++iter) { SmartPtr &isp_result = *iter; switch (isp_result->get_type()) { case X3aIspConfig::IspExposureParameters: { SmartPtr isp_exposure = isp_result.dynamic_cast_ptr (); XCAM_ASSERT (isp_exposure.ptr ()); const XCam3aResultExposure &exposure = isp_exposure->get_standard_result (); XCam3aResultExposure *new_exposure = xcam_malloc0_type (XCam3aResultExposure); XCAM_ASSERT (new_exposure); *new_exposure = exposure; new_exposure->head.type = XCAM_3A_RESULT_EXPOSURE; new_exposure->head.process_type = XCAM_IMAGE_PROCESS_ALWAYS; new_exposure->head.version = xcam_version (); results[result_count++] = (XCam3aResultHead*)new_exposure; break; } case X3aIspConfig::IspAllParameters: { SmartPtr isp_3a_all = isp_result.dynamic_cast_ptr (); XCAM_ASSERT (isp_3a_all.ptr ()); const struct rkisp_parameters &rkisp_params = isp_3a_all->get_isp_config (); XCAM_LOG_ERROR ("translate active_configs: %x", rkisp_params.active_configs); result_count += translate_rkisp_parameters (rkisp_params, &results[result_count], max_count - result_count); break; } case XCAM_3A_RESULT_BRIGHTNESS: { SmartPtr xcam_brightness = isp_result.dynamic_cast_ptr(); const XCam3aResultBrightness &brightness = xcam_brightness->get_standard_result(); XCam3aResultBrightness *new_brightness = xcam_malloc0_type(XCam3aResultBrightness); XCAM_ASSERT (new_brightness); *new_brightness = brightness; results[result_count++] = (XCam3aResultHead*)new_brightness; break; } case XCAM_3A_RESULT_3D_NOISE_REDUCTION: case XCAM_3A_RESULT_TEMPORAL_NOISE_REDUCTION_YUV: { SmartPtr xcam_tnr = isp_result.dynamic_cast_ptr (); const XCam3aResultTemporalNoiseReduction &tnr = xcam_tnr->get_standard_result(); XCam3aResultTemporalNoiseReduction *new_tnr = xcam_malloc0_type(XCam3aResultTemporalNoiseReduction); XCAM_ASSERT (new_tnr); *new_tnr = tnr; results[result_count++] = (XCam3aResultHead*)new_tnr; break; } case XCAM_3A_RESULT_EDGE_ENHANCEMENT: { SmartPtr xcam_ee = isp_result.dynamic_cast_ptr (); const XCam3aResultEdgeEnhancement &ee = xcam_ee->get_standard_result(); XCam3aResultEdgeEnhancement *new_ee = xcam_malloc0_type(XCam3aResultEdgeEnhancement); XCAM_ASSERT (new_ee); *new_ee = ee; results[result_count++] = (XCam3aResultHead*)new_ee; break; } case XCAM_3A_RESULT_BAYER_NOISE_REDUCTION: { SmartPtr xcam_bnr = isp_result.dynamic_cast_ptr (); const XCam3aResultBayerNoiseReduction &bnr = xcam_bnr->get_standard_result(); XCam3aResultBayerNoiseReduction *new_bnr = xcam_malloc0_type(XCam3aResultBayerNoiseReduction); XCAM_ASSERT (new_bnr); *new_bnr = bnr; results[result_count++] = (XCam3aResultHead*)new_bnr; break; } case XCAM_3A_RESULT_WAVELET_NOISE_REDUCTION: { SmartPtr xcam_wavelet = isp_result.dynamic_cast_ptr (); const XCam3aResultWaveletNoiseReduction &wavelet = xcam_wavelet->get_standard_result(); XCam3aResultWaveletNoiseReduction *new_wavelet = xcam_malloc0_type(XCam3aResultWaveletNoiseReduction); XCAM_ASSERT (new_wavelet); *new_wavelet = wavelet; results[result_count++] = (XCam3aResultHead*)new_wavelet; break; } default: { XCAM_LOG_WARNING ("unknown type(%d) in translation", isp_result->get_type()); break; } } } return result_count; } void free_3a_result (XCam3aResultHead *result) { xcam_free (result); } }