/****************************************************************************** * * Copyright 2019, Fuzhou Rockchip Electronics Co.Ltd. All rights reserved. * No part of this work may be reproduced, modified, distributed, transmitted, * transcribed, or translated into any language or computer format, in any form * or by any means without written permission of: * Fuzhou Rockchip Electronics Co.Ltd . * * *****************************************************************************/ /** * @file ahdr.cpp * * @brief * ADD_DESCRIPTION_HERE * *****************************************************************************/ #include "math.h" #include "rk_aiq_types_amerge_algo_int.h" #include "rk_aiq_types_amerge_algo_prvt.h" #include "xcam_log.h" /****************************************************************************** * AmergeStart() *****************************************************************************/ RESULT AmergeStart ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); // initial checks if (pAmergeCtx == NULL) { return (AMERGE_RET_WRONG_HANDLE); } if ((AMERGE_STATE_RUNNING == pAmergeCtx->state) || (AMERGE_STATE_LOCKED == pAmergeCtx->state)) { return (AMERGE_RET_WRONG_STATE); } pAmergeCtx->state = AMERGE_STATE_RUNNING; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); return (AMERGE_RET_SUCCESS); } /****************************************************************************** * AmergeStop() *****************************************************************************/ RESULT AmergeStop ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); // initial checks if (pAmergeCtx == NULL) { return (AMERGE_RET_WRONG_HANDLE); } // before stopping, unlock the AHDR if locked if (AMERGE_STATE_LOCKED == pAmergeCtx->state) { return (AMERGE_RET_WRONG_STATE); } pAmergeCtx->state = AMERGE_STATE_STOPPED; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); return (AMERGE_RET_SUCCESS); } /****************************************************************************** * GetCurrPara() *****************************************************************************/ float GetCurrPara ( float inPara, float* inMatrixX, float* inMatrixY, int Max_Knots ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); float x1 = 0.0f; float x2 = 0.0f; float value1 = 0.0f; float value2 = 0.0f; float outPara = 0.0f; if(inPara < inMatrixX[0]) outPara = inMatrixY[0]; else if (inPara >= inMatrixX[Max_Knots - 1]) outPara = inMatrixY[Max_Knots - 1]; else for(int i = 0; i < Max_Knots - 1; i++) { if(inPara >= inMatrixX[i] && inPara < inMatrixX[i + 1]) { x1 = inMatrixX[i]; x2 = inMatrixX[i + 1]; value1 = inMatrixY[i]; value2 = inMatrixY[i + 1]; outPara = value1 + (inPara - x1) * (value1 - value2) / (x1 - x2); break; } else continue; } return outPara; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeConfig() *set default Config data *****************************************************************************/ void AmergeConfig ( AmergeHandle_t pAmergeCtx ) { LOG1_ATMO( "%s:enter!\n", __FUNCTION__); // initial checks DCT_ASSERT(pAmergeCtx != NULL); //config default PrevData data pAmergeCtx->PrevData.CtrlData.EnvLv = 0; pAmergeCtx->PrevData.CtrlData.MoveCoef = 0; pAmergeCtx->PrevData.CtrlData.ApiMode = MERGE_OPMODE_API_OFF; pAmergeCtx->PrevData.HandleData.MergeMode = 1; pAmergeCtx->PrevData.HandleData.OECurve_smooth = 80; pAmergeCtx->PrevData.HandleData.OECurve_offset = 210; pAmergeCtx->PrevData.HandleData.MDCurveLM_smooth = 80; pAmergeCtx->PrevData.HandleData.MDCurveLM_offset = 38; pAmergeCtx->PrevData.HandleData.MDCurveMS_smooth = 80; pAmergeCtx->PrevData.HandleData.MDCurveMS_offset = 38; //set default ctrl info pAmergeCtx->mergeAttr.CtlInfo.Envlv = 1.0; pAmergeCtx->mergeAttr.CtlInfo.MoveCoef = 0.0; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } void AmergeGetAeResult ( AmergeHandle_t pAmergeCtx, AecPreResult_t AecHdrPreResult ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); //get Ae Pre Result pAmergeCtx->AeResult.GlobalEnvLv = AecHdrPreResult.GlobalEnvLv[AecHdrPreResult.NormalIndex]; pAmergeCtx->AeResult.M2S_Ratio = AecHdrPreResult.M2S_ExpRatio; pAmergeCtx->AeResult.M2S_Ratio = pAmergeCtx->AeResult.M2S_Ratio < 1 ? 1 : pAmergeCtx->AeResult.M2S_Ratio; pAmergeCtx->AeResult.L2M_Ratio = AecHdrPreResult.L2M_ExpRatio; pAmergeCtx->AeResult.L2M_Ratio = pAmergeCtx->AeResult.L2M_Ratio < 1 ? 1 : pAmergeCtx->AeResult.L2M_Ratio; //transfer AeResult data into AhdrHandle switch (pAmergeCtx->FrameNumber) { case 1: pAmergeCtx->CurrData.CtrlData.LExpo = AecHdrPreResult.LinearExp.exp_real_params.analog_gain * AecHdrPreResult.LinearExp.exp_real_params.integration_time; pAmergeCtx->CurrData.CtrlData.L2S_Ratio = 1; pAmergeCtx->CurrData.CtrlData.L2M_Ratio = 1; pAmergeCtx->CurrData.CtrlData.L2L_Ratio = 1; pAmergeCtx->AeResult.GlobalEnvLv = AecHdrPreResult.GlobalEnvLv[0]; break; case 2: pAmergeCtx->CurrData.CtrlData.L2S_Ratio = pAmergeCtx->AeResult.M2S_Ratio; pAmergeCtx->CurrData.CtrlData.L2M_Ratio = 1; pAmergeCtx->CurrData.CtrlData.L2L_Ratio = 1; pAmergeCtx->CurrData.CtrlData.LExpo = AecHdrPreResult.HdrExp[1].exp_real_params.analog_gain * AecHdrPreResult.HdrExp[1].exp_real_params.integration_time; pAmergeCtx->AeResult.GlobalEnvLv = AecHdrPreResult.GlobalEnvLv[1]; break; case 3: pAmergeCtx->CurrData.CtrlData.L2S_Ratio = pAmergeCtx->AeResult.L2M_Ratio * pAmergeCtx->AeResult.M2S_Ratio; pAmergeCtx->CurrData.CtrlData.L2M_Ratio = pAmergeCtx->AeResult.L2M_Ratio; pAmergeCtx->CurrData.CtrlData.L2L_Ratio = 1; pAmergeCtx->CurrData.CtrlData.LExpo = AecHdrPreResult.HdrExp[2].exp_real_params.analog_gain * AecHdrPreResult.HdrExp[2].exp_real_params.integration_time; pAmergeCtx->AeResult.GlobalEnvLv = AecHdrPreResult.GlobalEnvLv[2]; break; default: LOGE_AMERGE("%s: Wrong frame number in HDR mode!!!\n", __FUNCTION__); break; } //Normalize the current envLv for AEC float maxEnvLuma = 65 / 10; float minEnvLuma = 0; pAmergeCtx->CurrData.CtrlData.EnvLv = (pAmergeCtx->AeResult.GlobalEnvLv - minEnvLuma) / (maxEnvLuma - minEnvLuma); pAmergeCtx->CurrData.CtrlData.EnvLv = LIMIT_VALUE(pAmergeCtx->CurrData.CtrlData.EnvLv, ENVLVMAX, ENVLVMIN); LOGD_AMERGE("%s: Current CtrlData.L2S_Ratio:%f CtrlData.L2M_Ratio:%f CtrlData.L2L_Ratio:%f\n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.L2S_Ratio, pAmergeCtx->CurrData.CtrlData.L2M_Ratio, pAmergeCtx->CurrData.CtrlData.L2L_Ratio); LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } void GetCurrMergeData ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); //get Current merge OECurve pAmergeCtx->CurrData.HandleData.OECurve_smooth = GetCurrPara(pAmergeCtx->CurrData.CtrlData.EnvLv, pAmergeCtx->Config.EnvLv, pAmergeCtx->Config.OECurve_smooth, pAmergeCtx->Config.MaxEnvLvKnots); pAmergeCtx->CurrData.HandleData.OECurve_offset = GetCurrPara(pAmergeCtx->CurrData.CtrlData.EnvLv, pAmergeCtx->Config.EnvLv, pAmergeCtx->Config.OECurve_offset, pAmergeCtx->Config.MaxEnvLvKnots); //get Current merge MDCurve pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveLM_smooth, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.HandleData.MDCurveLM_offset = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveLM_offset, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveMS_smooth, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.HandleData.MDCurveMS_offset = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveMS_offset, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.CtrlData.MergeOEDamp = pAmergeCtx->Config.OECurve_damp; pAmergeCtx->CurrData.CtrlData.MergeMDDampLM = pAmergeCtx->Config.MDCurveLM_damp; pAmergeCtx->CurrData.CtrlData.MergeMDDampMS = pAmergeCtx->Config.MDCurveMS_damp; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } void AmergeGetSensorInfo ( AmergeHandle_t pAmergeCtx, AecProcResult_t AecHdrProcResult ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); pAmergeCtx->SensorInfo.LongFrmMode = AecHdrProcResult.LongFrmMode && (pAmergeCtx->FrameNumber != 1); for(int i = 0; i < 3; i++) { pAmergeCtx->SensorInfo.HdrMinGain[i] = AecHdrProcResult.HdrMinGain[i]; pAmergeCtx->SensorInfo.HdrMaxGain[i] = AecHdrProcResult.HdrMaxGain[i]; pAmergeCtx->SensorInfo.HdrMinIntegrationTime[i] = AecHdrProcResult.HdrMinIntegrationTime[i]; pAmergeCtx->SensorInfo.HdrMaxIntegrationTime[i] = AecHdrProcResult.HdrMaxIntegrationTime[i]; } if(pAmergeCtx->FrameNumber == 2) { pAmergeCtx->SensorInfo.MaxExpoL = pAmergeCtx->SensorInfo.HdrMaxGain[1] * pAmergeCtx->SensorInfo.HdrMaxIntegrationTime[1]; pAmergeCtx->SensorInfo.MinExpoL = pAmergeCtx->SensorInfo.HdrMinGain[1] * pAmergeCtx->SensorInfo.HdrMinIntegrationTime[1]; pAmergeCtx->SensorInfo.MaxExpoM = 0; pAmergeCtx->SensorInfo.MinExpoM = 0; } else if(pAmergeCtx->FrameNumber == 3) { pAmergeCtx->SensorInfo.MaxExpoL = pAmergeCtx->SensorInfo.HdrMaxGain[2] * pAmergeCtx->SensorInfo.HdrMaxIntegrationTime[2]; pAmergeCtx->SensorInfo.MinExpoL = pAmergeCtx->SensorInfo.HdrMinGain[2] * pAmergeCtx->SensorInfo.HdrMinIntegrationTime[2]; pAmergeCtx->SensorInfo.MaxExpoM = pAmergeCtx->SensorInfo.HdrMaxGain[1] * pAmergeCtx->SensorInfo.HdrMaxIntegrationTime[1]; pAmergeCtx->SensorInfo.MinExpoM = pAmergeCtx->SensorInfo.HdrMinGain[1] * pAmergeCtx->SensorInfo.HdrMinIntegrationTime[1]; } pAmergeCtx->SensorInfo.MaxExpoS = pAmergeCtx->SensorInfo.HdrMaxGain[0] * pAmergeCtx->SensorInfo.HdrMaxIntegrationTime[0]; pAmergeCtx->SensorInfo.MinExpoS = pAmergeCtx->SensorInfo.HdrMinGain[0] * pAmergeCtx->SensorInfo.HdrMinIntegrationTime[0]; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeIQUpdate() * *****************************************************************************/ void AmergeIQUpdate(AmergeHandle_t pAmergeCtx) { LOG1_AMERGE("%s:enter!\n", __FUNCTION__); //get Current merge OECurve pAmergeCtx->CurrData.HandleData.OECurve_smooth = GetCurrPara(pAmergeCtx->CurrData.CtrlData.EnvLv, pAmergeCtx->Config.EnvLv, pAmergeCtx->Config.OECurve_smooth, pAmergeCtx->Config.MaxEnvLvKnots); pAmergeCtx->CurrData.HandleData.OECurve_offset = GetCurrPara(pAmergeCtx->CurrData.CtrlData.EnvLv, pAmergeCtx->Config.EnvLv, pAmergeCtx->Config.OECurve_offset, pAmergeCtx->Config.MaxEnvLvKnots); //get Current merge MDCurve pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveLM_smooth, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.HandleData.MDCurveLM_offset = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveLM_offset, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveMS_smooth, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.HandleData.MDCurveMS_offset = GetCurrPara(pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->Config.MoveCoef, pAmergeCtx->Config.MDCurveMS_offset, pAmergeCtx->Config.MaxMoveCoefKnots); pAmergeCtx->CurrData.CtrlData.MergeOEDamp = pAmergeCtx->Config.OECurve_damp; pAmergeCtx->CurrData.CtrlData.MergeMDDampLM = pAmergeCtx->Config.MDCurveLM_damp; pAmergeCtx->CurrData.CtrlData.MergeMDDampMS = pAmergeCtx->Config.MDCurveMS_damp; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeTranferData2Api() * *****************************************************************************/ void AmergeTranferData2Api ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE("%s:enter!\n", __FUNCTION__); //transfer control data to api pAmergeCtx->mergeAttr.CtlInfo.Envlv = pAmergeCtx->CurrData.CtrlData.EnvLv; pAmergeCtx->mergeAttr.CtlInfo.MoveCoef = pAmergeCtx->CurrData.CtrlData.MoveCoef; //transfer register data to api pAmergeCtx->mergeAttr.RegInfo.OECurve_smooth = pAmergeCtx->CurrData.HandleData.OECurve_smooth; pAmergeCtx->mergeAttr.RegInfo.OECurve_offset = pAmergeCtx->CurrData.HandleData.OECurve_offset; pAmergeCtx->mergeAttr.RegInfo.MDCurveLM_smooth = pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth; pAmergeCtx->mergeAttr.RegInfo.MDCurveLM_offset = pAmergeCtx->CurrData.HandleData.MDCurveLM_offset; pAmergeCtx->mergeAttr.RegInfo.MDCurveMS_smooth = pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth; pAmergeCtx->mergeAttr.RegInfo.MDCurveMS_offset = pAmergeCtx->CurrData.HandleData.MDCurveMS_offset; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeApiAutoUpdate() * *****************************************************************************/ void AmergeApiAutoUpdate ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE("%s:enter!\n", __FUNCTION__); if (pAmergeCtx->mergeAttr.stAuto.bUpdateMge == true) { //get oe cruve pAmergeCtx->CurrData.HandleData.OECurve_smooth = LIMIT_PARA(pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stCoef, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stSmthMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stSmthMin, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stCoefMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stCoefMin); pAmergeCtx->CurrData.HandleData.OECurve_offset = LIMIT_PARA(pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stCoef, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stOfstMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stOfstMin, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stCoefMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stOECurve.stCoefMin); //get md cruve ms pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth = LIMIT_PARA(pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stCoef, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stSmthMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stSmthMin, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stCoefMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stCoefMin); pAmergeCtx->CurrData.HandleData.MDCurveMS_offset = LIMIT_PARA(pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stCoef, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stOfstMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stOfstMin, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stCoefMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveMS.stCoefMin); //get md cruve lm pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth = LIMIT_PARA(pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stCoef, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stSmthMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stSmthMin, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stCoefMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stCoefMin); pAmergeCtx->CurrData.HandleData.MDCurveLM_offset = LIMIT_PARA(pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stCoef, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stOfstMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stOfstMin, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stCoefMax, pAmergeCtx->mergeAttr.stAuto.stMgeAuto.stMDCurveLM.stCoefMin); } else GetCurrMergeData(pAmergeCtx); //paras after updating LOGD_AMERGE("%s: Current MDCurveMS_smooth:%f MDCurveMS_offset:%f MDCurveLM_smooth:%f MDCurveLM_offset:%f OECurve_smooth:%f OECurve_offset:%f\n", __FUNCTION__, pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth, pAmergeCtx->CurrData.HandleData.MDCurveMS_offset, pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth, pAmergeCtx->CurrData.HandleData.MDCurveLM_offset, pAmergeCtx->CurrData.HandleData.OECurve_smooth, pAmergeCtx->CurrData.HandleData.OECurve_offset); LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeApiManualUpdate() * *****************************************************************************/ void AmergeApiManualUpdate ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE("%s:enter!\n", __FUNCTION__); //update merge data in manual mode if (pAmergeCtx->mergeAttr.stManual.bUpdateMge == true) { pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth = pAmergeCtx->mergeAttr.stManual.stMgeManual.MDCurveMS_smooth * MDCURVESMOOTHMAX; pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth = LIMIT_VALUE(pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth, MDCURVESMOOTHMAX, MDCURVESMOOTHMIN); pAmergeCtx->CurrData.HandleData.MDCurveMS_offset = pAmergeCtx->mergeAttr.stManual.stMgeManual.MDCurveMS_offset * MDCURVEOFFSETMAX; pAmergeCtx->CurrData.HandleData.MDCurveMS_offset = LIMIT_VALUE(pAmergeCtx->CurrData.HandleData.MDCurveMS_offset, MDCURVEOFFSETMAX, MDCURVEOFFSETMIN); pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth = pAmergeCtx->mergeAttr.stManual.stMgeManual.MDCurveLM_smooth * MDCURVESMOOTHMAX; pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth = LIMIT_VALUE(pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth, MDCURVESMOOTHMAX, MDCURVESMOOTHMIN); pAmergeCtx->CurrData.HandleData.MDCurveLM_offset = pAmergeCtx->mergeAttr.stManual.stMgeManual.MDCurveLM_offset * MDCURVEOFFSETMAX; pAmergeCtx->CurrData.HandleData.MDCurveLM_offset = LIMIT_VALUE(pAmergeCtx->CurrData.HandleData.MDCurveLM_offset, MDCURVEOFFSETMAX, MDCURVEOFFSETMIN); pAmergeCtx->CurrData.HandleData.OECurve_smooth = pAmergeCtx->mergeAttr.stManual.stMgeManual.OECurve_smooth * OECURVESMOOTHMAX; pAmergeCtx->CurrData.HandleData.OECurve_smooth = LIMIT_VALUE(pAmergeCtx->CurrData.HandleData.OECurve_smooth, OECURVESMOOTHMAX, OECURVESMOOTHMIN); pAmergeCtx->CurrData.HandleData.OECurve_offset = pAmergeCtx->mergeAttr.stManual.stMgeManual.OECurve_offset; pAmergeCtx->CurrData.HandleData.OECurve_offset = LIMIT_VALUE(pAmergeCtx->CurrData.HandleData.OECurve_offset, OECURVEOFFSETMAX, OECURVEOFFSETMIN); pAmergeCtx->CurrData.CtrlData.MergeOEDamp = pAmergeCtx->mergeAttr.stManual.stMgeManual.dampOE; pAmergeCtx->CurrData.CtrlData.MergeMDDampLM = pAmergeCtx->mergeAttr.stManual.stMgeManual.dampMDLM; pAmergeCtx->CurrData.CtrlData.MergeMDDampMS = pAmergeCtx->mergeAttr.stManual.stMgeManual.dampMDMS; } else GetCurrMergeData(pAmergeCtx); //paras after updating LOGD_AMERGE("%s: Current MDCurveMS_smooth:%f MDCurveMS_offset:%f MDCurveLM_smooth:%f MDCurveLM_offset:%f OECurve_smooth:%f OECurve_offset:%f\n", __FUNCTION__, pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth, pAmergeCtx->CurrData.HandleData.MDCurveMS_offset, pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth, pAmergeCtx->CurrData.HandleData.MDCurveLM_offset, pAmergeCtx->CurrData.HandleData.OECurve_smooth, pAmergeCtx->CurrData.HandleData.OECurve_offset); LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * MergeNewMalloc() ***************************************************************************/ void MergeNewMalloc ( AmergeConfig_t* pAmergeConfig, CalibDbV2_merge_t* pCalibDb ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); // initial checks DCT_ASSERT(pAmergeConfig != NULL); DCT_ASSERT(pCalibDb != NULL); LOGD_AMERGE( "%s: Pre MaxEnvLvKnots:%d Cur MaxEnvLvKnots:%d\n", __FUNCTION__, pAmergeConfig->MaxEnvLvKnots, pCalibDb->MergeTuningPara.OECurve.EnvLv_len); LOGD_AMERGE( "%s: Pre MaxMoveCoefKnots:%d Cur MaxMoveCoefKnots:%d\n", __FUNCTION__, pAmergeConfig->MaxMoveCoefKnots, pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len); if(pAmergeConfig->MaxEnvLvKnots != pCalibDb->MergeTuningPara.OECurve.EnvLv_len) { free(pAmergeConfig->EnvLv); free(pAmergeConfig->OECurve_smooth); free(pAmergeConfig->OECurve_offset); pAmergeConfig->MaxEnvLvKnots = pCalibDb->MergeTuningPara.OECurve.EnvLv_len; pAmergeConfig->EnvLv = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.OECurve.EnvLv_len)); pAmergeConfig->OECurve_smooth = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.OECurve.EnvLv_len)); pAmergeConfig->OECurve_offset = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.OECurve.EnvLv_len)); } if(pAmergeConfig->MaxMoveCoefKnots != pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len) { free(pAmergeConfig->MoveCoef); free(pAmergeConfig->MDCurveLM_smooth); free(pAmergeConfig->MDCurveLM_offset); free(pAmergeConfig->MDCurveMS_smooth); free(pAmergeConfig->MDCurveMS_offset); pAmergeConfig->MaxMoveCoefKnots = pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len; pAmergeConfig->MoveCoef = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeConfig->MDCurveLM_smooth = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeConfig->MDCurveLM_offset = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeConfig->MDCurveMS_smooth = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeConfig->MDCurveMS_offset = (float*)malloc(sizeof(float) * (pCalibDb->MergeTuningPara.MDCurve.MoveCoef_len)); } LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeUpdateConfig() *transfer html parameter into handle ***************************************************************************/ void AmergeUpdateConfig ( AmergeHandle_t pAmergeCtx, CalibDbV2_merge_t* pCalibDb ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); // initial checks DCT_ASSERT(pAmergeCtx != NULL); DCT_ASSERT(pCalibDb != NULL); pAmergeCtx->Config.ByPassThr = LIMIT_VALUE(pCalibDb->MergeTuningPara.ByPassThr, DAMPMAX, DAMPMIN); pAmergeCtx->Config.OECurve_damp = LIMIT_VALUE(pCalibDb->MergeTuningPara.OECurve_damp, DAMPMAX, DAMPMIN); pAmergeCtx->Config.MDCurveLM_damp = LIMIT_VALUE(pCalibDb->MergeTuningPara.MDCurveLM_damp, DAMPMAX, DAMPMIN); pAmergeCtx->Config.MDCurveMS_damp = LIMIT_VALUE(pCalibDb->MergeTuningPara.MDCurveMS_damp, DAMPMAX, DAMPMIN); for (int i = 0; i < pAmergeCtx->Config.MaxEnvLvKnots; i++ ) { pAmergeCtx->Config.EnvLv[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.OECurve.EnvLv[i], ENVLVMAX, ENVLVMIN); pAmergeCtx->Config.OECurve_smooth[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.OECurve.Smooth[i], IQPARAMAX, IQPARAMIN); pAmergeCtx->Config.OECurve_offset[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.OECurve.Offset[i], OECURVEOFFSETMAX, OECURVEOFFSETMIN); } for (int i = 0; i < pAmergeCtx->Config.MaxMoveCoefKnots; i++ ) { pAmergeCtx->Config.MoveCoef[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.MDCurve.MoveCoef[i], MOVECOEFMAX, MOVECOEFMIN); pAmergeCtx->Config.MDCurveLM_smooth[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.MDCurve.LM_smooth[i], IQPARAMAX, IQPARAMIN); pAmergeCtx->Config.MDCurveLM_offset[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.MDCurve.LM_offset[i], IQPARAMAX, IQPARAMIN); pAmergeCtx->Config.MDCurveMS_smooth[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.MDCurve.MS_smooth[i], IQPARAMAX, IQPARAMIN); pAmergeCtx->Config.MDCurveMS_offset[i] = LIMIT_VALUE(pCalibDb->MergeTuningPara.MDCurve.MS_offset[i], IQPARAMAX, IQPARAMIN); } LOG1_AMERGE( "%s:EnvLv len:%d MoveCoef len:%d \n", __FUNCTION__, pAmergeCtx->Config.MaxEnvLvKnots, pAmergeCtx->Config.MaxMoveCoefKnots); for(int i = 0; i < pAmergeCtx->Config.MaxEnvLvKnots; i++) LOG1_AMERGE("%s: EnvLv[%d]:%f OEcurve_smooth[%d]:%f OEcurve_offset[%d]:%f OECurve_damp:%f\n", __FUNCTION__, i, pAmergeCtx->Config.EnvLv[i], i, pAmergeCtx->Config.OECurve_smooth[i], i, pAmergeCtx->Config.OECurve_offset[i], pAmergeCtx->Config.OECurve_damp); for(int i = 0; i < pAmergeCtx->Config.MaxMoveCoefKnots; i++) LOG1_AMERGE("%s: MoveCoef[%d]:%f MDCurveMS_smooth[%d]:%f MDCurveMS_offset[%d]:%f MDCurveMS_damp:%f\n", __FUNCTION__, i, pAmergeCtx->Config.MoveCoef[i], i, pAmergeCtx->Config.MDCurveMS_smooth[i], i, pAmergeCtx->Config.MDCurveMS_offset[i], pAmergeCtx->Config.MDCurveMS_damp); for(int i = 0; i < pAmergeCtx->Config.MaxMoveCoefKnots; i++) LOG1_AMERGE("%s: MoveCoef[%d]:%f MDCurveLM_smooth[%d]:%f MDCurveLM_offset[%d]:%f MDCurveLM_damp:%f\n", __FUNCTION__, i, pAmergeCtx->Config.MoveCoef[i], i, pAmergeCtx->Config.MDCurveLM_smooth[i], i, pAmergeCtx->Config.MDCurveLM_offset[i], pAmergeCtx->Config.MDCurveLM_damp); //turn the IQ paras into algo paras for(int i = 0; i < 13; i++) { pAmergeCtx->Config.OECurve_smooth[i] = pAmergeCtx->Config.OECurve_smooth[i] * OECURVESMOOTHMAX; pAmergeCtx->Config.OECurve_smooth[i] = LIMIT_VALUE(pAmergeCtx->Config.OECurve_smooth[i], OECURVESMOOTHMAX, OECURVESMOOTHMIN) ; pAmergeCtx->Config.MDCurveLM_smooth[i] = pAmergeCtx->Config.MDCurveLM_smooth[i] * MDCURVESMOOTHMAX; pAmergeCtx->Config.MDCurveLM_smooth[i] = LIMIT_VALUE(pAmergeCtx->Config.MDCurveLM_smooth[i], MDCURVESMOOTHMAX, MDCURVESMOOTHMIN) ; pAmergeCtx->Config.MDCurveLM_offset[i] = pAmergeCtx->Config.MDCurveLM_offset[i] * MDCURVEOFFSETMAX; pAmergeCtx->Config.MDCurveLM_offset[i] = LIMIT_VALUE(pAmergeCtx->Config.MDCurveLM_offset[i], MDCURVEOFFSETMAX, MDCURVEOFFSETMIN) ; pAmergeCtx->Config.MDCurveMS_smooth[i] = pAmergeCtx->Config.MDCurveMS_smooth[i] * MDCURVESMOOTHMAX; pAmergeCtx->Config.MDCurveMS_smooth[i] = LIMIT_VALUE(pAmergeCtx->Config.MDCurveMS_smooth[i], MDCURVESMOOTHMAX, MDCURVESMOOTHMIN) ; pAmergeCtx->Config.MDCurveMS_offset[i] = pAmergeCtx->Config.MDCurveMS_offset[i] * MDCURVEOFFSETMAX; pAmergeCtx->Config.MDCurveMS_offset[i] = LIMIT_VALUE(pAmergeCtx->Config.MDCurveMS_offset[i], MDCURVEOFFSETMAX, MDCURVEOFFSETMIN) ; } LOG1_AMERGE("%s: Merge algo OECurve_smooth:%f %f %f %f %f %f:\n", __FUNCTION__, pAmergeCtx->Config.OECurve_smooth[0], pAmergeCtx->Config.OECurve_smooth[1], pAmergeCtx->Config.OECurve_smooth[2], pAmergeCtx->Config.OECurve_smooth[3], pAmergeCtx->Config.OECurve_smooth[4], pAmergeCtx->Config.OECurve_smooth[5]); LOG1_AMERGE("%s: Merge algo MDCurveLM_smooth:%f %f %f %f %f %f:\n", __FUNCTION__, pAmergeCtx->Config.MDCurveLM_smooth[0], pAmergeCtx->Config.MDCurveLM_smooth[1], pAmergeCtx->Config.MDCurveLM_smooth[2], pAmergeCtx->Config.MDCurveLM_smooth[3], pAmergeCtx->Config.MDCurveLM_smooth[4], pAmergeCtx->Config.MDCurveLM_smooth[5]); LOG1_AMERGE("%s: Merge algo MDCurveLM_offset:%f %f %f %f %f %f:\n", __FUNCTION__, pAmergeCtx->Config.MDCurveLM_offset[0], pAmergeCtx->Config.MDCurveLM_offset[1], pAmergeCtx->Config.MDCurveLM_offset[2], pAmergeCtx->Config.MDCurveLM_offset[3], pAmergeCtx->Config.MDCurveLM_offset[4], pAmergeCtx->Config.MDCurveLM_offset[5]); LOG1_AMERGE("%s: Merge algo MDCurveMS_smooth:%f %f %f %f %f %f:\n", __FUNCTION__, pAmergeCtx->Config.MDCurveMS_smooth[0], pAmergeCtx->Config.MDCurveMS_smooth[1], pAmergeCtx->Config.MDCurveMS_smooth[2], pAmergeCtx->Config.MDCurveMS_smooth[3], pAmergeCtx->Config.MDCurveMS_smooth[4], pAmergeCtx->Config.MDCurveMS_smooth[5]); LOG1_AMERGE("%s: Merge algo MDCurveMS_offset:%f %f %f %f %f %f:\n", __FUNCTION__, pAmergeCtx->Config.MDCurveMS_offset[0], pAmergeCtx->Config.MDCurveMS_offset[1], pAmergeCtx->Config.MDCurveMS_offset[2], pAmergeCtx->Config.MDCurveMS_offset[3], pAmergeCtx->Config.MDCurveMS_offset[4], pAmergeCtx->Config.MDCurveMS_offset[5]); LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * CalibrateOECurve() *****************************************************************************/ void CalibrateOECurve ( float smooth, float offset, unsigned short *OECurve ) { LOG1_AMERGE("%s:Enter!\n", __FUNCTION__); int step = 32 ; float curve = 0; float k = 511; for(int i = 0; i < 17; ++i) { curve = 1 + exp(-smooth * (k / 1023 - offset / 256)); curve = 1024 / curve ; OECurve[i] = round(curve) ; OECurve[i] = MIN(OECurve[i], 1023); k += step ; } LOG1_AMERGE("%s:Eixt!\n", __FUNCTION__); } /****************************************************************************** * CalibrateMDCurve() *****************************************************************************/ void CalibrateMDCurve ( float smooth, float offset, unsigned short *MDCurve ) { LOG1_AMERGE("%s:Enter!\n", __FUNCTION__); int step = 16; float curve; float k = 0; for (int i = 0; i < 17; ++i) { curve = 1 + exp(-smooth * (k / 1023 - offset / 256)); curve = 1024 / curve ; MDCurve[i] = round(curve) ; MDCurve[i] = MIN(MDCurve[i], 1023); k += step ; } LOG1_AMERGE("%s:Eixt!\n", __FUNCTION__); } /****************************************************************************** * GetCurrIOData() *****************************************************************************/ void MergeGetCurrIOData ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE("%s:Enter!\n", __FUNCTION__); int OECurve[17]; pAmergeCtx->ProcRes.Res.sw_hdrmge_mode = pAmergeCtx->CurrData.HandleData.MergeMode; if(pAmergeCtx->HWversion == AMERGE_ISP21) pAmergeCtx->ProcRes.Res.sw_hdrmge_mode = LIMIT_VALUE(pAmergeCtx->ProcRes.Res.sw_hdrmge_mode, 1, 0); pAmergeCtx->ProcRes.Res.sw_hdrmge_lm_dif_0p9 = 230; pAmergeCtx->ProcRes.Res.sw_hdrmge_ms_dif_0p8 = 205; pAmergeCtx->ProcRes.Res.sw_hdrmge_lm_dif_0p15 = (int)pAmergeCtx->CurrData.HandleData.MDCurveLM_offset; pAmergeCtx->ProcRes.Res.sw_hdrmge_ms_dif_0p15 = (int)pAmergeCtx->CurrData.HandleData.MDCurveMS_offset; CalibrateOECurve(pAmergeCtx->CurrData.HandleData.OECurve_smooth, pAmergeCtx->CurrData.HandleData.OECurve_offset, pAmergeCtx->ProcRes.Res.sw_hdrmge_e_y) ; CalibrateMDCurve(pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth, pAmergeCtx->CurrData.HandleData.MDCurveLM_offset, pAmergeCtx->ProcRes.Res.sw_hdrmge_l1_y); CalibrateMDCurve(pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth, pAmergeCtx->CurrData.HandleData.MDCurveMS_offset, pAmergeCtx->ProcRes.Res.sw_hdrmge_l0_y); if(pAmergeCtx->SensorInfo.LongFrmMode == true) { for(int i = 0; i < 17; i++) pAmergeCtx->ProcRes.Res.sw_hdrmge_e_y[i] = 0; } //when gainX = 1, gainX_inv = 1/gainX -1 pAmergeCtx->ProcRes.Res.sw_hdrmge_gain0 = (int)SHIFT6BIT(pAmergeCtx->CurrData.CtrlData.L2S_Ratio); if(pAmergeCtx->CurrData.CtrlData.L2S_Ratio == 1) pAmergeCtx->ProcRes.Res.sw_hdrmge_gain0_inv = (int)(SHIFT12BIT(1 / pAmergeCtx->CurrData.CtrlData.L2S_Ratio) - 1); else pAmergeCtx->ProcRes.Res.sw_hdrmge_gain0_inv = (int)SHIFT12BIT(1 / pAmergeCtx->CurrData.CtrlData.L2S_Ratio); pAmergeCtx->ProcRes.Res.sw_hdrmge_gain1 = (int)SHIFT6BIT(pAmergeCtx->CurrData.CtrlData.L2M_Ratio); if(pAmergeCtx->CurrData.CtrlData.L2M_Ratio == 1) pAmergeCtx->ProcRes.Res.sw_hdrmge_gain1_inv = (int)(SHIFT12BIT(1 / pAmergeCtx->CurrData.CtrlData.L2M_Ratio) - 1); else pAmergeCtx->ProcRes.Res.sw_hdrmge_gain1_inv = (int)SHIFT12BIT(1 / pAmergeCtx->CurrData.CtrlData.L2M_Ratio); pAmergeCtx->ProcRes.Res.sw_hdrmge_gain2 = (int)SHIFT6BIT(pAmergeCtx->CurrData.CtrlData.L2L_Ratio); LOGV_AMERGE("%s: Merge set IOdata to register:\n", __FUNCTION__); LOGV_AMERGE("%s: sw_hdrmge_mode:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_mode); LOGV_AMERGE("%s: sw_hdrmge_ms_dif_0p8:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_ms_dif_0p8); LOGV_AMERGE("%s: sw_hdrmge_lm_dif_0p9:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_lm_dif_0p9); LOGV_AMERGE("%s: sw_hdrmge_ms_dif_0p15:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_ms_dif_0p15); LOGV_AMERGE("%s: sw_hdrmge_gain1:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_gain1); LOGV_AMERGE("%s: sw_hdrmge_gain1_inv:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_gain1_inv); LOGV_AMERGE("%s: sw_hdrmge_gain2:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_gain2); LOGV_AMERGE("%s: sw_hdrmge_gain0:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_gain0); LOGV_AMERGE("%s: sw_hdrmge_gain0_inv:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_gain0_inv); LOGV_AMERGE("%s: sw_hdrmge_lm_dif_0p15:%d \n", __FUNCTION__, pAmergeCtx->ProcRes.Res.sw_hdrmge_lm_dif_0p15); for(int i = 0; i < 17; i++) LOGV_AMERGE("%s: sw_hdrmge_e_y[%d]:%d \n", __FUNCTION__, i, pAmergeCtx->ProcRes.Res.sw_hdrmge_e_y[i]); for(int i = 0; i < 17; i++) LOGV_AMERGE("%s: sw_hdrmge_l0_y[%d]:%d \n", __FUNCTION__, i, pAmergeCtx->ProcRes.Res.sw_hdrmge_l0_y[i]); for(int i = 0; i < 17; i++) LOGV_AMERGE("%s: sw_hdrmge_l1_y[%d]:%d \n", __FUNCTION__, i, pAmergeCtx->ProcRes.Res.sw_hdrmge_l1_y[i]); LOG1_AMERGE("%s:Eixt!\n", __FUNCTION__); } /****************************************************************************** * MergeDamping() *****************************************************************************/ RESULT MergeDamping ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE("%s:Enter!\n", __FUNCTION__); RESULT result = AMERGE_RET_SUCCESS; float OEDamp = pAmergeCtx->CurrData.CtrlData.MergeOEDamp; float MDDampLM = pAmergeCtx->CurrData.CtrlData.MergeMDDampLM; float MDDampMS = pAmergeCtx->CurrData.CtrlData.MergeMDDampMS; bool ifHDRModeChange = pAmergeCtx->CurrData.HandleData.MergeMode == pAmergeCtx->PrevData.HandleData.MergeMode ? false : true; //get finnal current data if (pAmergeCtx->mergeAttr.opMode == MERGE_OPMODE_API_OFF && pAmergeCtx->frameCnt != 0 && !ifHDRModeChange) { pAmergeCtx->CurrData.HandleData.OECurve_smooth = OEDamp * pAmergeCtx->CurrData.HandleData.OECurve_smooth + (1 - OEDamp) * pAmergeCtx->PrevData.HandleData.OECurve_smooth; pAmergeCtx->CurrData.HandleData.OECurve_offset = OEDamp * pAmergeCtx->CurrData.HandleData.OECurve_offset + (1 - OEDamp) * pAmergeCtx->PrevData.HandleData.OECurve_offset; pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth = MDDampLM * pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth + (1 - MDDampLM) * pAmergeCtx->PrevData.HandleData.MDCurveLM_smooth; pAmergeCtx->CurrData.HandleData.MDCurveLM_offset = MDDampLM * pAmergeCtx->CurrData.HandleData.MDCurveLM_offset + (1 - MDDampLM) * pAmergeCtx->PrevData.HandleData.MDCurveLM_offset; pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth = MDDampMS * pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth + (1 - MDDampMS) * pAmergeCtx->PrevData.HandleData.MDCurveMS_smooth; pAmergeCtx->CurrData.HandleData.MDCurveMS_offset = MDDampMS * pAmergeCtx->CurrData.HandleData.MDCurveMS_offset + (1 - MDDampMS) * pAmergeCtx->PrevData.HandleData.MDCurveMS_offset; } LOGD_AMERGE("%s: Current damp OECurve_smooth:%f OECurve_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.HandleData.OECurve_smooth, pAmergeCtx->CurrData.HandleData.OECurve_offset); LOGD_AMERGE("%s: Current damp MDCurveLM_smooth:%f MDCurveLM_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth, pAmergeCtx->CurrData.HandleData.MDCurveLM_offset); LOGD_AMERGE("%s: Current damp MDCurveMS_smooth:%f MDCurveMS_offset:%f\n", __FUNCTION__, pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth , pAmergeCtx->CurrData.HandleData.MDCurveMS_offset); LOG1_AMERGE("%s:Eixt!\n", __FUNCTION__); return(result); } /****************************************************************************** * AmergeGetProcRes() *****************************************************************************/ void AmergeGetProcRes ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); //merge damp MergeDamping(pAmergeCtx); //get current IO data MergeGetCurrIOData(pAmergeCtx); // store current handle data to pre data for next loop pAmergeCtx->PrevData.HandleData.MergeMode = pAmergeCtx->CurrData.HandleData.MergeMode; pAmergeCtx->PrevData.CtrlData.L2S_ratio = pAmergeCtx->CurrData.CtrlData.L2S_Ratio; pAmergeCtx->PrevData.CtrlData.LExpo = pAmergeCtx->CurrData.CtrlData.LExpo; pAmergeCtx->PrevData.CtrlData.EnvLv = pAmergeCtx->CurrData.CtrlData.EnvLv; pAmergeCtx->PrevData.CtrlData.MoveCoef = pAmergeCtx->CurrData.CtrlData.MoveCoef; memcpy(&pAmergeCtx->PrevData.HandleData, &pAmergeCtx->CurrData.HandleData, sizeof(MergeHandleData_s)); ++pAmergeCtx->frameCnt; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeProcessing() *get handle para by config and current variate *****************************************************************************/ void AmergeProcessing ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE("%s:enter!\n", __FUNCTION__); LOGD_AMERGE("%s: Amerge Current frame cnt:%d:\n", __FUNCTION__, pAmergeCtx->frameCnt); if(pAmergeCtx->mergeAttr.opMode == MERGE_OPMODE_API_OFF) { LOGD_AMERGE("%s: Amerge api OFF!! Current Handle data:\n", __FUNCTION__); AmergeIQUpdate(pAmergeCtx); //log after updating LOGD_AMERGE("%s: Current CtrlData.EnvLv:%f OECurve_smooth:%f OECurve_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.EnvLv, pAmergeCtx->CurrData.HandleData.OECurve_smooth, pAmergeCtx->CurrData.HandleData.OECurve_offset); LOGD_AMERGE("%s: Current CtrlData.MoveCoef:%f MDCurveLM_smooth:%f MDCurveLM_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth, pAmergeCtx->CurrData.HandleData.MDCurveLM_offset); LOGD_AMERGE("%s: Current CtrlData.MoveCoef:%f MDCurveMS_smooth:%f MDCurveMS_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth, pAmergeCtx->CurrData.HandleData.MDCurveMS_offset); } else if(pAmergeCtx->mergeAttr.opMode == MERGE_OPMODE_AUTO) { LOGD_AMERGE("%s: Amerge api Auto!! Current Handle data:\n", __FUNCTION__); AmergeApiAutoUpdate(pAmergeCtx); } else if(pAmergeCtx->mergeAttr.opMode == MERGE_OPMODE_MANU) { LOGD_AMERGE("%s: Amerge api Manual!! Current Handle data:\n", __FUNCTION__); AmergeApiManualUpdate(pAmergeCtx); } else if(pAmergeCtx->mergeAttr.opMode == MERGE_OPMODE_TOOL) { LOGD_AMERGE("%s: Amerge api Tool!! Current Handle data:\n", __FUNCTION__); AmergeIQUpdate(pAmergeCtx); //log after updating LOGD_AMERGE("%s: Current EnvLv:%f OECurve_smooth:%f OECurve_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.EnvLv, pAmergeCtx->CurrData.HandleData.OECurve_smooth, pAmergeCtx->CurrData.HandleData.OECurve_offset); LOGD_AMERGE("%s: Current MoveCoef:%f MDCurveLM_smooth:%f MDCurveLM_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->CurrData.HandleData.MDCurveLM_smooth, pAmergeCtx->CurrData.HandleData.MDCurveLM_offset); LOGD_AMERGE("%s: Current MoveCoef:%f MDCurveMS_smooth:%f MDCurveMS_offset:%f \n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.MoveCoef, pAmergeCtx->CurrData.HandleData.MDCurveMS_smooth, pAmergeCtx->CurrData.HandleData.MDCurveMS_offset); } else LOGE_AMERGE("%s: Amerge wrong mode!!!\n", __FUNCTION__); //transfer data to api AmergeTranferData2Api(pAmergeCtx); //merge get proc res AmergeGetProcRes(pAmergeCtx); LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); } /****************************************************************************** * AmergeByPassProcessing() *get handle para by config and current variate *****************************************************************************/ bool AmergeByPassProcessing ( AmergeHandle_t pAmergeCtx, AecPreResult_t AecHdrPreResult ) { LOG1_AMERGE("%s:enter!\n", __FUNCTION__); bool bypass = false; float diff = 0.0; if(pAmergeCtx->frameCnt <= 2) //start frame bypass = false; else if(pAmergeCtx->mergeAttr.opMode > MERGE_OPMODE_API_OFF)//api bypass = false; if(pAmergeCtx->mergeAttr.opMode != pAmergeCtx->PrevData.CtrlData.ApiMode)//api change bypass = false; else { //EvnLv change //get Current hdr mode pAmergeCtx->CurrData.HandleData.MergeMode = pAmergeCtx->FrameNumber - 1; LOGD_AMERGE("%s: Current MergeMode: %d \n", __FUNCTION__, pAmergeCtx->CurrData.HandleData.MergeMode); //get current ae data from AecPreRes AmergeGetAeResult(pAmergeCtx, AecHdrPreResult); //transfer ae data to CurrHandle pAmergeCtx->CurrData.CtrlData.EnvLv = LIMIT_VALUE(pAmergeCtx->CurrData.CtrlData.EnvLv, ENVLVMAX, ENVLVMIN); pAmergeCtx->CurrData.CtrlData.MoveCoef = 1; pAmergeCtx->CurrData.CtrlData.MoveCoef = LIMIT_VALUE(pAmergeCtx->CurrData.CtrlData.MoveCoef, MOVECOEFMAX, MOVECOEFMIN); //use Envlv for now diff = pAmergeCtx->PrevData.CtrlData.EnvLv - pAmergeCtx->CurrData.CtrlData.EnvLv; if(pAmergeCtx->PrevData.CtrlData.EnvLv == 0.0) { diff = pAmergeCtx->CurrData.CtrlData.EnvLv; if(diff == 0.0) bypass = true; else bypass = false; } else { diff /= pAmergeCtx->PrevData.CtrlData.EnvLv; if(diff >= pAmergeCtx->Config.ByPassThr || diff <= (0 - pAmergeCtx->Config.ByPassThr)) bypass = false; else bypass = true; } } LOG1_AMERGE( "%s:CtrlEnvLv:%f PrevEnvLv:%f diff:%f ByPassThr:%f opMode:%d bypass:%d!\n", __FUNCTION__, pAmergeCtx->CurrData.CtrlData.EnvLv, pAmergeCtx->PrevData.CtrlData.EnvLv, diff, pAmergeCtx->Config.ByPassThr, pAmergeCtx->mergeAttr.opMode, bypass); LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); return bypass; } /****************************************************************************** * AmergeInit() *****************************************************************************/ RESULT AmergeInit ( AmergeInstanceConfig_t* pInstConfig, CamCalibDbV2Context_t* pCalibV2 ) { AmergeContext_s *pAmergeCtx; LOG1_AMERGE("%s:enter!\n", __FUNCTION__); RESULT result = AMERGE_RET_SUCCESS; // initial checks if (pInstConfig == NULL) return (AMERGE_RET_INVALID_PARM); // allocate AMERGE control context pAmergeCtx = (AmergeContext_s*)malloc(sizeof(AmergeContext_s)); if (NULL == pAmergeCtx) { LOGE_AMERGE( "%s: Can't allocate AMERGE context\n", __FUNCTION__); return (AMERGE_RET_OUTOFMEM); } CalibDbV2_merge_t* calibv2_amerge_calib = (CalibDbV2_merge_t*)(CALIBDBV2_GET_MODULE_PTR(pCalibV2, amerge_calib)); // pre-initialize context memset(pAmergeCtx, 0x00, sizeof(AmergeContext_s)); pAmergeCtx->Config.MaxEnvLvKnots = calibv2_amerge_calib->MergeTuningPara.OECurve.EnvLv_len; pAmergeCtx->Config.EnvLv = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.OECurve.EnvLv_len)); pAmergeCtx->Config.OECurve_smooth = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.OECurve.EnvLv_len)); pAmergeCtx->Config.OECurve_offset = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.OECurve.EnvLv_len)); pAmergeCtx->Config.MaxMoveCoefKnots = calibv2_amerge_calib->MergeTuningPara.MDCurve.MoveCoef_len; pAmergeCtx->Config.MoveCoef = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeCtx->Config.MDCurveLM_smooth = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeCtx->Config.MDCurveLM_offset = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeCtx->Config.MDCurveMS_smooth = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeCtx->Config.MDCurveMS_offset = (float*)malloc(sizeof(float) * (calibv2_amerge_calib->MergeTuningPara.MDCurve.MoveCoef_len)); pAmergeCtx->state = AMERGE_STATE_INITIALIZED; pAmergeCtx->mergeAttr.opMode = MERGE_OPMODE_API_OFF; if(CHECK_ISP_HW_V20()) pAmergeCtx->HWversion = AMERGE_ISP20; else if(CHECK_ISP_HW_V21()) pAmergeCtx->HWversion = AMERGE_ISP21; AmergeConfig(pAmergeCtx); //set default para memcpy(&pAmergeCtx->pCalibDB, calibv2_amerge_calib, sizeof(CalibDbV2_merge_t));//load iq paras memcpy(&pAmergeCtx->mergeAttr.stTool, calibv2_amerge_calib, sizeof(CalibDbV2_merge_t));//load iq paras to stTool pAmergeCtx->frameCnt = 0; pInstConfig->hAmerge = (AmergeHandle_t)pAmergeCtx; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); return (AMERGE_RET_SUCCESS); } /****************************************************************************** * AmergeRelease() *****************************************************************************/ RESULT AmergeRelease ( AmergeHandle_t pAmergeCtx ) { LOG1_AMERGE( "%s:enter!\n", __FUNCTION__); RESULT result = AMERGE_RET_SUCCESS; // initial checks if (NULL == pAmergeCtx) { return (AMERGE_RET_WRONG_HANDLE); } result = AmergeStop(pAmergeCtx); if (result != AMERGE_RET_SUCCESS) { LOGE_AMERGE( "%s: Amerge Stop() failed!\n", __FUNCTION__); return (result); } // check state if ((AMERGE_STATE_RUNNING == pAmergeCtx->state) || (AMERGE_STATE_LOCKED == pAmergeCtx->state)) { return (AMERGE_RET_BUSY); } free(pAmergeCtx->Config.EnvLv); free(pAmergeCtx->Config.OECurve_smooth); free(pAmergeCtx->Config.OECurve_offset); free(pAmergeCtx->Config.MoveCoef); free(pAmergeCtx->Config.MDCurveLM_smooth); free(pAmergeCtx->Config.MDCurveLM_offset); free(pAmergeCtx->Config.MDCurveMS_smooth); free(pAmergeCtx->Config.MDCurveMS_offset); memset(pAmergeCtx, 0, sizeof(AmergeContext_s)); free(pAmergeCtx); pAmergeCtx = NULL; LOG1_AMERGE( "%s:exit!\n", __FUNCTION__); return (AMERGE_RET_SUCCESS); }