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