/**
 * @file hv_app_PQ.c
 * @brief  dpu PQ app source file
 * @details This file provides the following functions: \n
 *          (1) dpu operation function \n
 *          (2) init handle \n
 *          (3) Feed functions \n
 *
 * @bug 1.bug1 \n
 * @todo 1.todo1 \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-25
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author                         <th>Date         <th>Change Description
 * <tr><td>Hiview SoC Software Team       <td>2022-08-25   <td>init
 * </table>
*/

#include <string.h>
#include "hv_comm_DataBase.h"
#include "hv_comm_Assert.h"
#include "hv_comm_MemParser.h"

#include "hv_mw_PQ.h"
#include "hv_app_PQ.h"
#include "hv_drv_PQ.h"

#include "hv_app_Function.h"
#include "hv_mw_Channel_Manager.h"
#include "hv_mw_SystemManager.h"

#include "hv_mw_OsdEvent.h"
#include "hv_mw_AmbientLight.h"
/* 初始化bin文件的长度 */
#define INIT_BIN_SIZE(x)  ((sizeof(x) / 4) / 3)

#define PQ_BRIGHTNESS_DEFAULTVALUE          (HV_COMMON_DATABASE_GET(UserData, ucBrightness))
#define PQ_CONTRAST_DEFAULTVALUE            (HV_COMMON_DATABASE_GET(UserData, ucContrast))
#define PQ_SATURATION_DEFAULTVALUE          (HV_COMMON_DATABASE_GET(UserData, ucSaturation))
#define PQ_HUE_DEFAULTVALUE                 (HV_COMMON_DATABASE_GET(UserData, ucHue))
#define PQ_SHARPNESS_DEFAULTVALUE           (HV_COMMON_DATABASE_GET(UserData, ucSharpness))
#define PQ_REDGAIN_DEFAULTVALUE             (50)
#define PQ_GREENGAIN_DEFAULTVALUE           (50)
#define PQ_BLUEGAIN_DEFAULTVALUE            (50)
#define PQ_GAMMA_DEFAULTINDEX               (HV_COMMON_DATABASE_GET(UserData, ucGamma))
#define PQ_DARKSTABLIZER_DEFAULTVALUE       (HV_COMMON_DATABASE_GET(UserData, ucDarkStabilizer))
#define PQ_DYNAMICCONTRAST_DEFAULTVALUE     (HV_COMMON_DATABASE_GET(UserData, ucDcr))
#define PQ_DYNAMICBACKLIGHT_DEFAULTVALUE    (HV_COMMON_DATABASE_GET(UserData, bVariableBackLight))
#define PQ_HDRSWITCH_DEFAULTVALUE           (HV_COMMON_DATABASE_GET(UserData, enHdrSwitch))
#define PQ_LOWBLUELIGHT_DEFAULTVALUE        (HV_COMMON_DATABASE_GET(UserData, ucLowBlueLight))
#define PQ_COLORTEMP_DEFAULTVALUE           (HV_COMMON_DATABASE_GET(UserData, ucColorTemperature))
#define PQ_OD_DEFAULTVALUE                  (HV_COMMON_DATABASE_GET(UserData, ucResponseTime))

#define PQ_Full_Range                   (0)
#define PQ_LIMIT_Range                  (1)

static const UINT32 auiCscInitBin[] =
{
    #include"hv_Database_Pq_Cscmtx.h"
};
static const UINT32 auiCscMainhdb[] =
{
    #include"hv_Database_Pq_Maincsccfg.h"
};
static const UINT32 auiCscSubhdb[] =
{
    #include"hv_Database_Pq_Subcsccfg.h"
};

static const UINT32 auiPqCommonBase[] =
{
    #include"hv_Database_Pq_Commonreg.h"
};

static const UINT32 auiYccmInitArr[] =
{
    #include "hv_Database_Pq_Yccmreg.h"
};
//for yccm, will be modified when setting changed
UINT32 __attribute__((aligned(512))) auiYccmLut2[7168] = {0};

static const UINT32 auiWcgGamutHdb[] =
{
    #include"hv_Database_Pq_Wcggamut.h"
};
static const UINT32 auiWcgInitBin[] =
{
    #include"hv_Database_Pq_Wcgreg.h"
};

static const UINT32 auiSharpnessParam[] =
{
    #include"hv_Database_Pq_Sharpnesscfg.h"
};
static const UINT32 auiSharpnessbin[] =
{
    #include"hv_Database_Pq_Sharpnessreg.h"
};

static const UINT32 auiDitherLdgbin[] =
{
    #include"hv_Database_Pq_Ldgditherreg.h"
};
static const UINT32 auiDitherSrpbin[] =
{
    #include"hv_Database_Pq_Srpditherreg.h"
};


//256+32, for global contrast, will be modified when setting changed
UINT32 __attribute__((aligned(512))) auiGcLut1[288] = {0};

static const UINT32 auiGcbin[] =
{
    #include"hv_Database_Pq_Gcreg.h"
};

static const UINT32 auiLdcbin[] =
{
    #include"hv_Database_Pq_Ldcreg.h"
};

static const UINT32 auiLdcLut[] =
{
#if (HV_PROJECT_CONFIG_FULL_LOCALDIMMING == HV_CONFIG_OFF)
    #include"hv_Database_Pq_Ldclut0.h"
#else
    #include"hv_Database_Pq_Ldclut.h"
#endif
};

static const UINT32 auiGammabin[]=
{
    #include"hv_Database_Pq_Gammareg.h"
};

/*
static const UINT32 auiGammadefault[]=
{
    #include"hv_Database_Pq_Gammaluts.h"
};
*/

/*
static const UINT32 __attribute__((aligned(512))) auiHdrLut0[] =
{
    #include"hv_Database_Pq_Hdrlut.h"
};
*/
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
static const UINT32 __attribute__((aligned(512))) auiHdrLut1[] = 
{
    #include"hv_Database_Pq_Hdrlut1.h"
};
#endif
static const UINT32 __attribute__((aligned(512))) auiScalerDownLut[] =
{
    #include"hv_Database_Pq_Scalerlut.h"
};

static const UINT32 uiFramerateDetThreshold[ ] = 
{
    #include"hv_Database_DispCtrl_Framerate_48_180.h"
};

static const UINT32 uiODLut0[ ] = 
{
    #include"hv_Database_DispCtrl_OD_Lut0.h"
};


static const UINT32 uiODLut1[ ] = 
{
    #include"hv_Database_DispCtrl_OD_Lut1.h"
};


static const UINT32 uiDispCtrlGammaVrrLut[] = 
{
    #include"hv_Database_DispCtrl_GammaVrr.h"
};

#if 1
static USHORT16 s_pausPattern1[]  =
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0828, 0x07fc, 0x0828,
0x07dc, 0x0828, 0x07fc, 0x0758, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0a6c, 0x0a90, 0x0dbc, 0x0a10,
0x06c4, 0x0b58, 0x0a6c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0ae4, 0x0fac, 0x0f64, 0x0d24, 0x0f44, 0x0b18, 0x0a48,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x09a0, 0x0af0, 0x0c6c, 0x09e0, 0x0c94, 0x0c78, 0x0888, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0c08, 0x0c6c, 0x0f08, 0x0ba4, 0x0f38, 0x0b7c, 0x0a9c, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0b7c, 0x0b78, 0x0af0, 0x0fa8, 0x0b9c, 0x0c58, 0x0a90, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
/*avec full full*/
static USHORT16 s_pausPattern2[]  = {
0x09f4, 0x0a20, 0x0a04, 0x09f4, 0x0a20, 0x0a68, 0x0a34, 0x0a80, 0x0a04, 0x09f4, 0x0b38, 0x0a04, 0x0a04, 0x0a30, 0x0a14, 0x0a04, 0x0a30,
0x0a14, 0x0a00, 0x0a30, 0x0a20, 0x0a04, 0x0a30, 0x0a14, 0x0a1c, 0x0a4c, 0x0ffc, 0x0f0c, 0x0ffc, 0x0f10, 0x0ff8, 0x0f98, 0x0ef0, 0x0ff0,
0x0008, 0x0a30, 0x0a1c, 0x0a4c, 0x0168, 0x0424, 0x05bc, 0x0700, 0x0850, 0x0a1c, 0x0bd0, 0x0dd4, 0x0fac, 0x0a30, 0x09f4, 0x0a20, 0x09bc, 0x09a4,
0x0980, 0x0e6c, 0x0d28, 0x0cf0, 0x09dc, 0x09b8, 0x09bc, 0x0a04, 0x0a04, 0x0a30, 0x0ff8, 0x0ff4, 0x0ff4, 0x0ff0, 0x0fec,
0x0fe8, 0x0fe8, 0x0e04, 0x0dd8, 0x0a14, 0x0ad4, 0x0a4c, 0x0f7c, 0x0f60, 0x0f70, 0x0f70, 0x0f08, 0x0c0c, 0x08c8, 0x0500, 0x0130, 0x0a30, 0x0a1c,
0x0a4c, 0x0a30, 0x0a1c, 0x0a88, 0x0a30, 0x0a1c, 0x0a4c, 0x0a90, 0x0a1c, 0x0a4c, 0x0a30,
};
/*hdr 5.2*/
static USHORT16 s_pausPattern3[]  = {
0x04d4, 0x0504, 0x05bc, 0x05a0, 0x0008, 0x0000, 0x05bc, 0x05a0, 0x0008, 0x0000, 0x05bc, 0x05a0, 0x04f8, 0x04fc, 0x05bc, 0x05a0, 0x0008, 0x0000, 0x05bc, 0x05a0, 0x0008, 0x0000, 0x05bc,
0x05a0, 0x05b4, 0x05bc, 0x0010, 0x0008, 0x05d0, 0x07d4, 0x0010, 0x0388, 0x05d0, 0x05bc, 0x0010, 0x0008, 0x0598, 0x05a0, 0x0008, 0x0000, 0x05bc, 0x05a0, 0x0008, 0x0000, 0x05bc,
0x05a0, 0x0008, 0x0000, 0x0008, 0x0008, 0x05d0, 0x05bc, 0x0010, 0x0388, 0x05d0, 0x07d4, 0x0010, 0x0008, 0x05d0, 0x05bc, 0x0000, 0x0000, 0x05bc, 0x05a0, 0x0008, 0x0000, 0x05bc,
0x05a0, 0x0008, 0x0000, 0x05bc, 0x05a0, 0x05b4, 0x05bc, 0x0010, 0x0008, 0x05d0, 0x05bc, 0x0010, 0x0008, 0x05d0, 0x05bc, 0x0010, 0x0008, 0x0598, 0x05a0, 0x0008,
0x0000, 0x05bc, 0x05a0, 0x0008, 0x0000, 0x05bc, 0x05a0, 0x0008, 0x0000,
};
#endif


static USHORT16 PQValueMapHandler_Sharpness(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    if(usValue <= PQ_SHARPNESS_OSD_MIDDLE)
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_SHARPNESS_OSD_START, PQ_SHARPNESS_OSD_MIDDLE, 
                PQ_SHARPNESS_DRV_FOR_OSD_SET_START, PQ_SHARPNESS_DRV_FOR_OSD_SET_MIDDLE);
    }
    else
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_SHARPNESS_OSD_START, PQ_SHARPNESS_OSD_END, 
                PQ_SHARPNESS_DRV_FOR_OSD_SET_MIDDLE, PQ_SHARPNESS_DRV_FOR_OSD_SET_END);
    }

    return usRet;
}

static USHORT16 PQValueMapHandler_Contrast(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    if(usValue <= PQ_CONTRAST_OSD_MIDDLE)
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_CONTRAST_OSD_START, PQ_CONTRAST_OSD_MIDDLE, 
                PQ_CONTRAST_DRV_FOR_OSD_SET_START, PQ_CONTRAST_DRV_FOR_OSD_SET_MIDDLE);
    }
    else
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_CONTRAST_OSD_MIDDLE, PQ_CONTRAST_OSD_END, 
                PQ_CONTRAST_DRV_FOR_OSD_SET_MIDDLE, PQ_CONTRAST_DRV_FOR_OSD_SET_END);
    }

    return usRet;
}

static USHORT16 PQValueMapHandler_Saturation(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    usRet = LINEAR_MAPPING_VALUE(usValue, PQ_SATURATION_OSD_START, PQ_SATURATION_OSD_END, 
            PQ_SATURATION_DRV_FOR_OSD_SET_START, PQ_SATURATION_DRV_FOR_OSD_SET_END);

    return usRet;
}

static USHORT16 PQValueMapHandler_Brightness(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    if(usValue <= PQ_BRIGHTNESS_OSD_MIDDLE)
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_BRIGHTNESS_OSD_START, PQ_BRIGHTNESS_OSD_MIDDLE, 
                PQ_BRIGHTNESS_DRV_FOR_OSD_SET_START, PQ_BRIGHTNESS_DRV_FOR_OSD_SET_MIDDLE);
    }
    else
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_BRIGHTNESS_OSD_MIDDLE, PQ_BRIGHTNESS_OSD_END, 
                PQ_BRIGHTNESS_DRV_FOR_OSD_SET_MIDDLE, PQ_BRIGHTNESS_DRV_FOR_OSD_SET_END);
    }

    return usRet;
}

static USHORT16 PQValueMapHandler_Hdr(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    if(usValue <= PQ_BRIGHTNESS_OSD_MIDDLE)
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_BRIGHTNESS_OSD_START, PQ_BRIGHTNESS_OSD_MIDDLE, 
                PQ_BRIGHTNESS_DRV_FOR_OSD_SET_START, PQ_BRIGHTNESS_DRV_FOR_OSD_SET_MIDDLE);
    }
    else
    {
        usRet = LINEAR_MAPPING_VALUE(usValue, PQ_BRIGHTNESS_OSD_MIDDLE, PQ_BRIGHTNESS_OSD_END, 
                PQ_BRIGHTNESS_DRV_FOR_OSD_SET_MIDDLE, PQ_BRIGHTNESS_DRV_FOR_HDR_MAX);
    }

    return usRet;
}

static USHORT16 PQValueMapHandler_RgbGain(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    usRet = LINEAR_MAPPING_VALUE(usValue, PQ_RGBGAIN_OSD_START, PQ_RGBGAIN_OSD_END, 
            PQ_RGBGAIN_DRV_FOR_OSD_SET_START, PQ_RGBGAIN_DRV_FOR_OSD_SET_END);//default 100
    CHECK_MAX_RANGE(usRet, PQ_RGBGAIN_DRV_FOR_OSD_SET_END);

    return usRet;
}

static USHORT16 PQValueMapHandler_RgbFac(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    usRet = LINEAR_MAPPING_VALUE(usValue, PQ_RGBGAIN_FAC_OSD_START, PQ_RGBGAIN_FAC_OSD_END, 
            PQ_RGBGAIN_FAC_DRV_FOR_OSD_SET_START, PQ_RGBGAIN_FAC_DRV_FOR_OSD_SET_END);
    CHECK_MAX_RANGE(usRet, PQ_DRV_RGBGAIN_MAX);

    return usRet;
}

static USHORT16 PQValueMapHandler_RgbOffset(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    usRet = LINEAR_MAPPING_VALUE(usValue, PQ_RGBOFFSET_OSD_START, PQ_RGBOFFSET_OSD_END, 
            PQ_RGBOFFSET_DRV_FOR_OSD_SET_START, PQ_RGBOFFSET_DRV_FOR_OSD_SET_END);//default 100
    CHECK_MAX_RANGE(usRet, PQ_RGBOFFSET_DRV_FOR_OSD_SET_END);

    return usRet;
}

static USHORT16 PQValueMapHandler_Hue(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    usRet = LINEAR_MAPPING_VALUE(usValue, PQ_HUE_OSD_START, PQ_HUE_OSD_END, 
            PQ_HUE_DRV_FOR_OSD_SET_START, PQ_HUE_DRV_FOR_OSD_SET_END);
    CHECK_MAX_RANGE(usRet, PQ_DRV_HUE_MAX);

    return usRet;
}

static USHORT16 PQValueMapHandler_BlackLevel(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    usRet = LINEAR_MAPPING_VALUE(usValue, 0, 100, 200, 310);
    CHECK_MAX_RANGE(usRet, PQ_DRV_BLACKLEVEL_MAX);

    return usRet;
}

static USHORT16 PQValueMapHandler_BlackStablizer(USHORT16 usValue)
{
    USHORT16 usRet = 0;

    usRet = LINEAR_MAPPING_VALUE(usValue, 0, USERDATA_DARKSTABILIZER_MAX, 0, PQ_DRV_DARKSTABILIZER_MAX);
    CHECK_MAX_RANGE(usRet, PQ_DRV_DARKSTABILIZER_MAX);

    return usRet;
}

static const PQValueMap s_astPQValueMap[] = 
{
    {PQ_SHARPNESS,         PQValueMapHandler_Sharpness},
    {PQ_CONTRAST,          PQValueMapHandler_Contrast},
    {PQ_SATURATION,        PQValueMapHandler_Saturation},
    {PQ_BRIGHTNESS,        PQValueMapHandler_Brightness},
    {PQ_BRIGHTNESS_HDR,    PQValueMapHandler_Hdr},
    {PQ_RGBGAIN,           PQValueMapHandler_RgbGain},
    {PQ_RGBGAIN_FAC,       PQValueMapHandler_RgbFac},
    {PQ_HUE,               PQValueMapHandler_Hue},
    {PQ_RGBOFFSET,         PQValueMapHandler_RgbOffset},
    {PQ_BLACKSTABLIZER,    PQValueMapHandler_BlackStablizer},
    {PQ_BLACKLEVEL,        PQValueMapHandler_BlackLevel},

};

static Status SendNotifyMessageToOsdTask(SettingParamId enParamId, UINT32 uiValue)
{
    HV_VOS_QUEUE_S *pOsdQueue = Hv_Mw_System_GetOsdQueue();
    HV_ASSERT_VALID_PTR(pOsdQueue);
    OsdEvent stOsdEvent;
    HV_MEMSET(&stOsdEvent, 0 ,sizeof(stOsdEvent));
    stOsdEvent.usEventId = enParamId;
    stOsdEvent.usValue = 0;
    HV_ASSERT_TRUE(Hv_Vos_QueueSend(pOsdQueue, &stOsdEvent));

    return HV_SUCCESS;
}

//In case there is Pic_Curve in Factory Mode, always get RealValue here
USHORT16 Hv_App_PQ_GetRealValue(USHORT16 usValue, UCHAR8 ucModule)
{
    USHORT16 usRet = usValue;
    for (UCHAR8 ucIndex = 0; ucIndex < ARRAY_SIZE(s_astPQValueMap); ++ucIndex)
    {
        if (ucModule == s_astPQValueMap[ucIndex].ucModule)
        {
            usRet = s_astPQValueMap[ucIndex].pfActionHandle(usValue);
        }
    }

    return usRet;
}

VOID Hv_App_PQ_Init(VOID)
{
    /*Common register init*/
    Hv_App_PQ_CommonRegInit(); 
    Hv_App_PQ_CscInit();
    Hv_App_PQ_WcgInit();
    Hv_App_PQ_CMInit();
    Hv_App_PQ_SharpnessInit();
    Hv_App_PQ_DitherInit();
    Hv_App_PQ_GammaInit();
    Hv_App_PQ_GcInit();
    Hv_App_PQ_HdrInit();
     /*scaler down lut*/
    Hv_App_PQ_ScalerUpLutInit();
    Hv_App_PQ_LdcInit();
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_AMBIENT_LIGHT)
    Hv_Mw_PQ_BulbInit();
#endif
    //USHORT16 * pausAddr[3]={NULL};
    //pausAddr[0] = s_pausPattern1;
    //pausAddr[1] = s_pausPattern2;
    //pausAddr[2] = s_pausPattern3;
    //Hv_Mw_PQ_PatDetInit(pausAddr, 3, 12, 8);
    
    return;
}

VOID Hv_App_PQ_SetDefaultValue(VOID)
{
    /* 进行userdata的PQ初始化 */
    Hv_App_PQ_SetBrightness(PQ_BRIGHTNESS_DEFAULTVALUE);
    Hv_App_PQ_SetContrast(PQ_CONTRAST_DEFAULTVALUE);
    Hv_App_PQ_DarkStablizer(PQ_DARKSTABLIZER_DEFAULTVALUE);
    if(0 == PQ_DARKSTABLIZER_DEFAULTVALUE)
    {
        Hv_App_PQ_DynamicContrastEnable(PQ_DYNAMICCONTRAST_DEFAULTVALUE);
    }
#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_FULL_LOCALDIMMING)
    Hv_App_PQ_LdcSetMode(PQ_DYNAMICBACKLIGHT_DEFAULTVALUE);
#else
    Hv_App_PQ_SetDCR(PQ_DYNAMICBACKLIGHT_DEFAULTVALUE);
#endif
    Hv_App_PQ_SetSaturation(PQ_SATURATION_DEFAULTVALUE);
    Hv_App_PQ_SetHue(PQ_HUE_DEFAULTVALUE);
    Hv_App_PQ_SetGamma(PQ_GAMMA_DEFAULTINDEX);
    Hv_App_PQ_SetSharpness(PQ_SHARPNESS_DEFAULTVALUE);
    Hv_App_PQ_ForceSwitchHdr(PQ_HDRSWITCH_DEFAULTVALUE);
    Hv_App_PQ_SetColorTemp(PQ_COLORTEMP_DEFAULTVALUE, PQ_LOWBLUELIGHT_DEFAULTVALUE);
    Hv_App_PQ_SetODLevel(PQ_OD_DEFAULTVALUE);
    /* set pq dma latch，reg setting will active in next vsync */
    Hv_Mw_PQ_DmaSetlatch();
    Hv_Mw_PQ_DmaWorkaround();

    return;
}

VOID Hv_App_PQ_CommonRegInit(VOID)
{
    Hv_Mw_PQ_DpuPQ_CommonRegInit(auiPqCommonBase, INIT_BIN_SIZE(auiPqCommonBase));
    return;
}

VOID Hv_App_PQ_CMInit(VOID)
{
    Hv_Mw_PQ_CMInit(auiYccmInitArr, INIT_BIN_SIZE(auiYccmInitArr));
    UINT32 uiAddr = 0;
    UINT32 uiLen = 0;
    Hv_Pq_GetTable(TABLE_PQ_YCCM, 1, &uiAddr, &uiLen);
    HV_LOG_DEBUG(PQ, "CMINIT %x %x", uiAddr, uiLen);
    if(uiAddr == 0)
    {
        Hv_Mw_PQ_PQBypass(0);
        HV_LOG_INFO(PQ, "ERROR, CM");
        return;
    } 
    UINT32 *pAddr = NULL;
    pAddr = (UINT32*)uiAddr;
    Hv_Mw_PQ_CMLutInit(pAddr, auiYccmLut2);

    return;
}

VOID Hv_App_PQ_GammaInit(VOID)
{
    UINT32 uiAddr = 0;
    UINT32 uiLen = 0;
    UINT32 *pAddrGamma = NULL;
    UINT32 *pAddrOsdGmi = NULL;
    UINT32 *pAddrOsdGmd = NULL;

    Hv_Mw_PQ_GammaInit(auiGammabin, INIT_BIN_SIZE(auiGammabin));

    Hv_Pq_GetTable(TABLE_PQ_GAMMA_D, 1, &uiAddr, &uiLen);
    if(uiAddr == 0)
    {
        Hv_Mw_PQ_PQBypass(0);
        HV_LOG_INFO(PQ, "GAMA ERROR");
        return;
    }
    HV_LOG_DEBUG(PQ, "Gamma %x %x", uiAddr, uiLen);
    pAddrGamma = (UINT32*)uiAddr;
    Hv_Mw_PQ_GammaLutInit(pAddrGamma);

    Hv_Pq_GetTable(TABLE_PQ_OSD_GMI, 1, &uiAddr, &uiLen);
    pAddrOsdGmi = (UINT32*)uiAddr;
    Hv_Pq_GetTable(TABLE_PQ_OSD_GMD, 1, &uiAddr, &uiLen);
    pAddrOsdGmd = (UINT32*)uiAddr;
    Hv_Mw_PQ_OsdGammaLutInit(pAddrOsdGmi, pAddrOsdGmd);

    return;
}

VOID Hv_App_PQ_SetGamma(UCHAR8 ucGammaIndex)
{
    HV_LOG_DEBUG(PQ, "Set Gamma %u", ucGammaIndex);
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucGamma, ucGammaIndex);
    Hv_Mw_PQ_SetGamma(ucGammaIndex);

    return;
}

UCHAR8 Hv_App_PQ_GetGamma(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucGamma);
}

VOID Hv_App_PQ_SharpnessInit(VOID)
{
    Hv_Mw_PQ_SharpnessInit(auiSharpnessbin, INIT_BIN_SIZE(auiSharpnessbin), auiSharpnessParam);
    return;
}

VOID Hv_App_PQ_SetSharpness(UCHAR8 ucSharpness)
{
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucSharpness, ucSharpness);
    HV_LOG_DEBUG(PQ, "sharpness %d", ucSharpness);
    HV_PQ_DATABASE_SET(DiagData, ucDBSharpness, ucSharpness);
    ucSharpness = Hv_App_PQ_GetRealValue(ucSharpness, PQ_SHARPNESS);

    Hv_Mw_PQ_SetSharpness(ucSharpness);
    return;
}

UCHAR8 Hv_App_PQ_GetSharpness(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucSharpness);
}

VOID Hv_App_PQ_GcInit(VOID)
{
    Hv_Mw_PQ_GcInit(auiGcbin, INIT_BIN_SIZE(auiGcbin));
    UINT32 uiAddr = 0;
    UINT32 uiLen = 0;
    Hv_Pq_GetTable(TABLE_PQ_CONTRAST, 1, &uiAddr, &uiLen);
    if(uiAddr == 0)
    {
        Hv_Mw_PQ_PQBypass(0);
        HV_LOG_INFO(PQ, "ERROR GC");
        return;
    }
    HV_LOG_DEBUG(PQ, "GC INIT %x %x", uiAddr, uiLen);
    UINT32 *pAddr = NULL;
    pAddr = (UINT32*)uiAddr;
    Hv_Mw_PQ_GcLutInit(pAddr, auiGcLut1);

    return;
}

VOID Hv_App_PQ_DarkStablizer(UCHAR8 ucCurBlkSta)
{
    HV_LOG_DEBUG(PQ, "Dark %d", ucCurBlkSta);
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucDarkStabilizer, ucCurBlkSta);
    ucCurBlkSta= Hv_App_PQ_GetRealValue(ucCurBlkSta, PQ_BLACKSTABLIZER);
    UCHAR8 ucGcMode = GC_DARKSTABLIZER;
    Hv_Mw_PQ_GcModeSwitch(ucGcMode, ucCurBlkSta);
    HV_PQ_DATABASE_SET(DiagData, ucDBGcMode, ucGcMode);
    HV_PQ_DATABASE_SET(DiagData, ucDBGcBlack, ucCurBlkSta);

    return;
}

UCHAR8 Hv_App_PQ_GetDarkStablizer(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucDarkStabilizer);
}

VOID Hv_App_PQ_DynamicContrastEnable(UCHAR8 ucEn)
{
    UCHAR8 ucGcMode = GC_DYNAMICCONTRAST;
    HV_LOG_DEBUG(PQ, "GC %d", ucEn);
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucDcr, ucEn);
    if(ucEn == HV_TRUE)
    {
        ucGcMode = GC_DYNAMICCONTRAST;
        Hv_Mw_PQ_GcModeSwitch(ucGcMode, 0);
        HV_PQ_DATABASE_SET(DiagData, ucDBGcMode, ucGcMode);
    }
    else
    {
        ucGcMode = GC_DARKSTABLIZER;
        Hv_Mw_PQ_GcModeSwitch(ucGcMode, HV_PQ_DATABASE_GET(DiagData, ucDBGcMode));
        HV_PQ_DATABASE_SET(DiagData, ucDBGcMode, ucGcMode);
    }

    return;
}

UCHAR8 Hv_App_PQ_GetDynamicContrast(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucDcr);
}

VOID Hv_App_PQ_HdrInit(VOID)
{
    UINT32 uiAddr = 0;
    UINT32 uiLen = 0;
    Hv_Pq_GetTable(TABLE_PQ_HDR, 1, &uiAddr, &uiLen);
    if(uiAddr == 0)
    {
        Hv_Mw_PQ_PQBypass(0);
        HV_LOG_INFO(PQ, "HDR ERROR");
        return;
    }
    HV_LOG_DEBUG(PQ, "HDR %x %x", uiAddr, uiLen);
    UINT32 *pAddr = NULL;
    pAddr = (UINT32*)uiAddr;
    Hv_Mw_PQ_HdrInit(pAddr, CHANNEL_MAIN);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_HdrInit(auiHdrLut1, CHANNEL_SUB);
#endif

    return;
}

static const UINT32 __attribute__((aligned(512))) pucLdData[4096]={0
};

VOID Hv_App_PQ_LdcInit(VOID)
{
    HV_LOG_DEBUG(PQ,"LDC init lut %x  config %x\n", auiLdcLut, auiLdcbin);
    Hv_Mw_PQ_LdcInit(auiLdcbin, INIT_BIN_SIZE(auiLdcbin));
    Hv_Mw_PQ_LdcLutInit(auiLdcLut, (UINT32*)pucLdData);

    return;
}

VOID Hv_App_PQ_SetMaxBl(UCHAR8 ucMaxBl)
{
    ucMaxBl = Hv_App_PQ_GetRealValue(ucMaxBl, PQ_BACKLIGHT);
    return Hv_Mw_PQ_SetMaxBl(ucMaxBl);
}

VOID Hv_App_PQ_ForceSwitchHdr(UCHAR8 ucSwitch)
{
    const ChannelManager *pstChannelManager = Hv_Mw_Channel_GetManager();
    UCHAR8 ucMainHdrType = 0;
    UCHAR8 ucSubHdrType = 0;

    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, enHdrSwitch, ucSwitch);
#if (HV_PROJECT_CONFIG_PQ_HDR_CHANGEEDID == HV_CONFIG_ON)
    HV_LOG_INFO(PQ, "Hv_Mw_Video_SetEdidHdrSwitch %d", ucSwitch);
    Hv_Mw_Video_SetEdidHdrSwitch(ucSwitch);
#else
    ucMainHdrType = pstChannelManager->astChannelData[CHANNEL_MAIN].stVideoConfigParams.stHdrParam.xType;
    const HDRParam* pstHdrParam = &pstChannelManager->astChannelData[CHANNEL_MAIN].stVideoConfigParams.stHdrParam;
    /*if Force off, don't care current input is hdr or not*/
    if(ucSwitch == UD_HDR_V_OFF)/*Hdr force off*/
    {
        Hv_Mw_PQ_HDREnable(CHANNEL_MAIN, HV_DISABLE);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
        Hv_Mw_PQ_HDREnable(CHANNEL_SUB, HV_DISABLE);
#endif
    }
    else/*if auto, checkout current input*/
    {
        if(ucMainHdrType != SDR_TYPE)
        {
            Hv_Mw_PQ_HDREnable(CHANNEL_MAIN, HV_ENABLE);
            Hv_Mw_PQ_SetHdrMode(CHANNEL_MAIN, ucMainHdrType, pstHdrParam);
        }
        else
        {
            Hv_Mw_PQ_SetHDREnableFlag(CHANNEL_MAIN, HV_ENABLE);
            /*set to auto when input is not HDR, do nothing*/
        }
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
        ucSubHdrType  = pstChannelManager->astChannelData[CHANNEL_SUB].stVideoConfigParams.stHdrParam.xType;
        if(ucSubHdrType != SDR_TYPE)
        {
            Hv_Mw_PQ_SetHdrMode(CHANNEL_SUB, ucSubHdrType, pstHdrParam);
        }
        else
        {
            /*set to auto when input is not HDR, do nothing*/
        }
#endif
    }
#endif

    return;
}

UCHAR8 Hv_App_PQ_GetHdrSwitch(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, enHdrSwitch);
}

VOID Hv_App_PQ_WcgInit(VOID)
{
    UINT32 uiAddr = 0;
    UINT32 uiLen = 0;
    UINT32 *pAddrWcgGmi = NULL;
    UINT32 *pAddrWcgGmd = NULL;
    UINT32 *pAddrWcgCm= NULL;

    Hv_Pq_GetTable(TABLE_PQ_WCG_GMI, 1, &uiAddr, &uiLen);
    pAddrWcgGmi = (UINT32*)uiAddr;
    Hv_Pq_GetTable(TABLE_PQ_WCG_GMD, 1, &uiAddr, &uiLen);
    pAddrWcgGmd = (UINT32*)uiAddr;
    Hv_Pq_GetTable(TABLE_PQ_WCG_CM, 1,  &uiAddr, &uiLen);
    pAddrWcgCm = (UINT32*)uiAddr;
    if((pAddrWcgGmi == NULL)||(pAddrWcgGmd == NULL)||(pAddrWcgCm ==NULL))//pq bin data error
    {
        HV_LOG_ERROR(PQ, "WCG Init Error");
        Hv_Mw_PQ_PQBypass(0);
    }

 
    Hv_Mw_PQ_WcgInit(auiWcgInitBin, INIT_BIN_SIZE(auiWcgInitBin));
    Hv_Mw_PQ_WcgLutInit(pAddrWcgGmi , pAddrWcgCm, pAddrWcgGmd);
    Hv_Mw_PQ_WcgEnable(HV_ENABLE);
    HV_LOG_DEBUG(PQ, "WCG  OK");

    return;
}

VOID Hv_App_PQ_CscInit(VOID)
{
    HV_LOG_DEBUG(PQ,"Hv_Mw_Video_Csc %x  %d",auiCscInitBin, INIT_BIN_SIZE(auiCscInitBin));
    Hv_Mw_PQ_CscInit(auiCscInitBin, INIT_BIN_SIZE(auiCscInitBin));
    HV_LOG_DEBUG(VIDEO,"Hv_Mw_Video_Csc hdb  %x %x",auiCscMainhdb, auiCscSubhdb);
    Hv_Mw_PQ_CscConfigAddr(auiCscMainhdb, auiCscSubhdb);

    return;
}

#if (HV_PROJECT_CONFIG_COLOR_FILTER == HV_CONFIG_ON)
const static UINT32 __attribute__((aligned(512))) s_auiWcgRgbLutProtanopia[] = {
#include"hv_Database_Pq_Wcgrgblut_Protanopia.h"
};
const static UINT32 __attribute__((aligned(512))) s_auiWcgRgbLutDeuteranopia[] = {
#include"hv_Database_Pq_Wcgrgblut_Deuteranopia.h"
};
const static UINT32 __attribute__((aligned(512))) s_auiWcgRgbLutTrianopia[] = {
#include"hv_Database_Pq_Wcgrgblut_Trianopia.h"
};

const static GamutSet s_stGamutInvertParam =
{
    0xF000, 0, 0,
    0, 0xF000, 0,
    0, 0, 0xF000,
};

const static GamutSet s_stGamutGrayParam =
{
    0x4F0, 0x9C0, 0x150,
    0x4F0, 0x9C0, 0x150,
    0x4F0, 0x9C0, 0x150,
};

const static GamutOffset s_stGamutInvertOffset =
{
    0x1FFFFFFF, 0x1FFFFFFF, 0x1FFFFFFF,
};

const static GamutOffset s_stGamutGrayOffset =
{
    0, 0, 0,
};

VOID Hv_App_PQ_SetWCGColorFilter(WCGColorFilterType enType)
{
    UINT32 uiAddr = 0;
    UINT32 uiLen = 0;
    UINT32 *pAddrWcgCm= NULL;
    Hv_Pq_GetTable(TABLE_PQ_WCG_CM, 1,  &uiAddr, &uiLen);
    pAddrWcgCm = (UINT32*)uiAddr;
 
    switch (enType)
    {
        case COLOR_FILTER_NONE:
        {
            Hv_Mw_PQ_LoadWCGLUT(pAddrWcgCm);
            Hv_Mw_PQ_SetGamutOffset(&s_stGamutGrayOffset);
            break;
        }
        case COLOR_FILTER_INVERT:
        {
            Hv_Mw_PQ_LoadWCGLUT(pAddrWcgCm);
            Hv_Mw_PQ_SetGamutEnable();
            Hv_Mw_PQ_SetGamutParam(&s_stGamutInvertParam);
            Hv_Mw_PQ_SetGamutOffset(&s_stGamutInvertOffset);
            break;
        }
        case COLOR_FILTER_GRAY:
        {
            Hv_Mw_PQ_LoadWCGLUT(pAddrWcgCm);
            Hv_Mw_PQ_SetGamutEnable();
            Hv_Mw_PQ_SetGamutParam(&s_stGamutGrayParam);
            Hv_Mw_PQ_SetGamutOffset(&s_stGamutGrayOffset);
            break;
        }
        case COLOR_FILTER_PROTANOPIA:
        {
            Hv_Mw_PQ_SetWCGLutEnable();
            Hv_Mw_PQ_LoadWCGLUT(s_auiWcgRgbLutProtanopia);
            break;
        }
        case COLOR_FILTER_DEUTERANOPIA:
        {
            Hv_Mw_PQ_SetWCGLutEnable();
            Hv_Mw_PQ_LoadWCGLUT(s_auiWcgRgbLutDeuteranopia);
            break;
        }
        case COLOR_FILTER_TRIANOPIA:
        {
            Hv_Mw_PQ_SetWCGLutEnable();
            Hv_Mw_PQ_LoadWCGLUT(s_auiWcgRgbLutTrianopia);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

VOID Hv_App_PQ_SetColorFilterType(WCGColorFilterType enType)
{
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucColorFilter, enType);
    Hv_App_PQ_SetWCGColorFilter(enType);

    switch (enType)
    {
        case COLOR_FILTER_NONE:
        case COLOR_FILTER_PROTANOPIA:
        case COLOR_FILTER_DEUTERANOPIA:
        case COLOR_FILTER_TRIANOPIA:
        {
            UCHAR8 ucSpace = HV_PQ_DATABASE_GET(UserData, ucColorSpace);
            Hv_App_PQ_SetGamut(ucSpace);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

UCHAR8 Hv_App_PQ_GetColorFilterType(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucColorFilter);
}
#endif

VOID Hv_App_PQ_SetGamut(PQGamutType enType)
{
    GamutSet stGamut = {
    0x1000, 0, 0, 
    0, 0x1000, 0,
    0, 0, 0x1000,
    0x1000, 0, 0, 
    0, 0x1000, 0,
    0, 0, 0x1000
    };
    UCHAR8 ucPxp = 0;
    UCHAR8 ucMagnifyGlass = 0;
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucColorSpace, enType);
    HV_LOG_DEBUG(PQ,"Hv_Mw_Video_SetGamutnew %x ", enType);
    Hv_Mw_PQ_CMEnable(HV_DISABLE);
    if(enType == PQ_GAMUT_709)
    {
        stGamut = HV_PQ_DATABASE_GET(FactoryData, stGamut709);
    }
    else if(enType == PQ_GAMUT_SRGB)
    {
        stGamut = HV_PQ_DATABASE_GET(FactoryData, stGamutSrgb);
    }
    else if(enType == PQ_GAMUT_P3)
    {
        stGamut = HV_PQ_DATABASE_GET(FactoryData, stGamutP3);
    }
    else if(enType == PQ_GAMUT_ADOBE)
    {
        stGamut = HV_PQ_DATABASE_GET(FactoryData, stGamutAdobe);
    }

    else if(enType == PQ_GAMUT_2020)/*2020 HDR*/
    {
        stGamut = HV_PQ_DATABASE_GET(FactoryData, stGamutHdr);
    }
    else if(enType == PQ_GAMUT_NATIVE)
    {
    #if (HV_CONFIG_ON == HV_PROJECT_CONFIG_PXP)
        ucPxp = HV_PQ_DATABASE_GET(UserData, ucPxPMode);
    #endif
    #if (HV_CONFIG_ON == HV_PROJECT_CONFIG_MAGNIFY)
        ucMagnifyGlass = HV_PQ_DATABASE_GET(UserData, bMagnifyGlassSw);
    #endif
        //Hv_Mw_PQ_SetGamutNative();
        stGamut = HV_PQ_DATABASE_GET(FactoryData, stGamutNative);
#if (HV_PROJECT_CONFIG_COLOR_FILTER == HV_CONFIG_ON)
        Hv_Mw_PQ_SetGamutOffset(&s_stGamutGrayOffset);
#endif
        //Hv_Drv_PQ_SetOsdGamutNative();
        HV_PQ_DATABASE_SET(DiagData, ucDBGamut, enType);
        //return;
    }
    else
    {
        //input error
    }
    enType = Hv_App_PQ_GetRealValue(enType, PQ_GAMUT);

    HV_LOG_DEBUG(PQ,"Hv_Mw_Video_SetGamut %x %u", auiWcgGamutHdb, enType);

    Hv_Mw_PQ_SetGamutFac(&stGamut);
#if (HV_PROJECT_CONFIG_COLOR_FILTER == HV_CONFIG_ON)
    Hv_Mw_PQ_SetGamutOffset(&s_stGamutGrayOffset);
#endif

    HV_PQ_DATABASE_SET(DiagData, ucDBGamut, enType);

    return;
}

UCHAR8 Hv_App_PQ_GetGamut(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucColorSpace);
}

VOID Hv_App_PQ_SetContrast(UCHAR8 ucContrast)
{
    HV_LOG_DEBUG(PQ, "Set contrast %d", ucContrast);
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucContrast, ucContrast);
    UINT32 uiContrast = 0;
    HV_PQ_DATABASE_SET(DiagData, uiDBContrast, ucContrast);
    uiContrast = Hv_App_PQ_GetRealValue(ucContrast, PQ_CONTRAST);
    HV_LOG_DEBUG(PQ, "Set contrast %d", uiContrast);
    Hv_Mw_PQ_SetContrast(CHANNEL_MAIN, uiContrast);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetContrast(CHANNEL_SUB, uiContrast);
#endif

    return;
}

UCHAR8 Hv_App_PQ_GetContrast(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucContrast);
}

VOID Hv_App_PQ_SetHue(UCHAR8 ucHue)
{
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucHue, ucHue);
    HV_LOG_DEBUG(PQ, "Set HUE %d", ucHue);
    HV_PQ_DATABASE_SET(DiagData, ucDBHue, ucHue);
    ucHue = Hv_App_PQ_GetRealValue(ucHue, PQ_HUE);
    Hv_Mw_PQ_SetHue(CHANNEL_MAIN, ucHue);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetHue(CHANNEL_SUB, ucHue);
#endif

    return;
}

UCHAR8 Hv_App_PQ_GetHue(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucHue);
}

VOID Hv_App_PQ_SetRGBGainFac(UCHAR8 ucRed, UCHAR8 ucGreen, UCHAR8 ucBlue)
{
    USHORT16 usR = 0;
    USHORT16 usG = 0;
    USHORT16 usB = 0;
    HV_LOG_DEBUG(PQ, "FAC Set RGB %d %d %d", ucRed, ucGreen, ucBlue);
    usR = Hv_App_PQ_GetRealValue(ucRed, PQ_RGBGAIN_FAC);
    usG = Hv_App_PQ_GetRealValue(ucGreen, PQ_RGBGAIN_FAC);
    usB = Hv_App_PQ_GetRealValue(ucBlue, PQ_RGBGAIN_FAC);

    HV_PQ_DATABASE_SET(DiagData, usDBRGain, ucRed * PQ_RGBGAIN_OSD_END / 255);
    HV_PQ_DATABASE_SET(DiagData, usDBGGain, ucGreen * PQ_RGBGAIN_OSD_END / 255);
    HV_PQ_DATABASE_SET(DiagData, usDBBGain, ucBlue * PQ_RGBGAIN_OSD_END / 255);
    Hv_Mw_PQ_SetRGBGain(CHANNEL_MAIN, usR, usG, usB);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBGain(CHANNEL_SUB, usR, usG, usB);
#endif

    return;
}

VOID Hv_App_PQ_SetRGBGain(UCHAR8 ucRed, UCHAR8 ucGreen, UCHAR8 ucBlue)
{
    USHORT16 usR = 0;
    USHORT16 usG = 0;
    USHORT16 usB = 0;
    HV_LOG_DEBUG(PQ, "Set RGB %d %d %d", ucRed, ucGreen, ucBlue);
    usR = Hv_App_PQ_GetRealValue(ucRed, PQ_RGBGAIN);
    usG = Hv_App_PQ_GetRealValue(ucGreen, PQ_RGBGAIN);
    usB = Hv_App_PQ_GetRealValue(ucBlue, PQ_RGBGAIN);
    HV_LOG_DEBUG(PQ, "Set RGB %d %d %d", usR, usG, usB);

    HV_PQ_DATABASE_SET(DiagData, usDBRGain, ucRed);
    HV_PQ_DATABASE_SET(DiagData, usDBGGain, ucGreen);
    HV_PQ_DATABASE_SET(DiagData, usDBBGain, ucBlue);
    Hv_Mw_PQ_SetRGBGain(CHANNEL_MAIN, usR, usG, usB);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBGain(CHANNEL_SUB, usR, usG, usB);
#endif

    return;
}

VOID Hv_App_PQ_SetRGain(UCHAR8 ucRed)
{
    USHORT16 usRed = 0;
    USHORT16 usGreen = 0;
    USHORT16 usBlue = 0;
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucRed, ucRed);
    HV_LOG_DEBUG(PQ, "Set R %d", ucRed);
    HV_PQ_DATABASE_SET(DiagData, usDBRGain, ucRed);
    usRed = Hv_App_PQ_GetRealValue(ucRed, PQ_RGBGAIN);
    usGreen = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBGGain), PQ_RGBGAIN);
    usBlue  = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBBGain), PQ_RGBGAIN);
    
    Hv_Mw_PQ_SetRGBGain(CHANNEL_MAIN, usRed, usGreen, usBlue);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBGain(CHANNEL_SUB, usRed, usGreen, usBlue);
#endif

    return;
}

UCHAR8 Hv_App_PQ_GetRGain(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucRed);
}

VOID Hv_App_PQ_SetGGain(UCHAR8 ucGreen)
{
    USHORT16 usRed = 0;
    USHORT16 usGreen = 0;
    USHORT16 usBlue = 0;
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucGreen, ucGreen);
    HV_LOG_DEBUG(PQ, "Set G %d", ucGreen);
    HV_PQ_DATABASE_SET(DiagData, usDBGGain, ucGreen);
    usGreen = Hv_App_PQ_GetRealValue(ucGreen, PQ_RGBGAIN);
    usRed =  Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBRGain), PQ_RGBGAIN);
    usBlue = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBBGain), PQ_RGBGAIN);
    
    Hv_Mw_PQ_SetRGBGain(CHANNEL_MAIN, usRed, usGreen, usBlue);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBGain(CHANNEL_SUB, usRed, usGreen, usBlue);
#endif

    return;
}

UCHAR8 Hv_App_PQ_GetGGain(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucGreen);
}

VOID Hv_App_PQ_SetBGain(UCHAR8 ucBlue)
{
    USHORT16 usRed = 0;
    USHORT16 usGreen = 0;
    USHORT16 usBlue = 0;
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucBlue, ucBlue);
    HV_LOG_DEBUG(PQ, "Set B %d", ucBlue);
    HV_PQ_DATABASE_SET(DiagData, usDBBGain, ucBlue);
    usBlue = Hv_App_PQ_GetRealValue(ucBlue, PQ_RGBGAIN);
    usRed =   Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBRGain), PQ_RGBGAIN);
    usGreen = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBGGain), PQ_RGBGAIN);
    Hv_Mw_PQ_SetRGBGain(CHANNEL_MAIN, usRed, usGreen, usBlue);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBGain(CHANNEL_SUB, usRed, usGreen, usBlue);
#endif

    return;
}

UCHAR8 Hv_App_PQ_GetBGain(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucBlue);
}

VOID Hv_App_PQ_SetRGBOffset(UCHAR8 ucRed, UCHAR8 ucGreen, UCHAR8 ucBlue)
{
    USHORT16 usR = 0;
    USHORT16 usG = 0;
    USHORT16 usB = 0;
    HV_LOG_DEBUG(PQ, "Set RGB %d %d %d", ucRed, ucGreen, ucBlue);
    usR = Hv_App_PQ_GetRealValue(ucRed, PQ_RGBOFFSET);
    usG = Hv_App_PQ_GetRealValue(ucGreen, PQ_RGBOFFSET);
    usB = Hv_App_PQ_GetRealValue(ucBlue, PQ_RGBOFFSET);
    HV_LOG_DEBUG(PQ, "Set RGB %d %d %d", usR, usG, usB);

    HV_PQ_DATABASE_SET(DiagData, usDBROffset, ucRed);
    HV_PQ_DATABASE_SET(DiagData, usDBGOffset, ucGreen);
    HV_PQ_DATABASE_SET(DiagData, usDBBOffset, ucBlue);
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_MAIN, usR, usG, usB);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_SUB, usR, usG, usB);
#endif

    return;
}

VOID Hv_App_PQ_SetROffset(UCHAR8 ucRed)
{
    USHORT16 usRed = 0;
    USHORT16 usGreen = 0;
    USHORT16 usBlue = 0;

    HV_LOG_DEBUG(PQ, "Set R %d", ucRed);
    HV_PQ_DATABASE_SET(DiagData, usDBROffset, ucRed);
    usRed = Hv_App_PQ_GetRealValue(ucRed, PQ_RGBOFFSET);
    usGreen = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBGOffset), PQ_RGBOFFSET);
    usBlue  = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBBOffset), PQ_RGBOFFSET);
    
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_MAIN, usRed, usGreen, usBlue);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_SUB, usRed, usGreen, usBlue);
#endif

    return;
}

VOID Hv_App_PQ_SetGOffset(UCHAR8 ucGreen)
{
    USHORT16 usRed = 0;
    USHORT16 usGreen = 0;
    USHORT16 usBlue = 0;

    HV_LOG_DEBUG(PQ, "Set G %d", ucGreen);
    HV_PQ_DATABASE_SET(DiagData, usDBGOffset, ucGreen);
    usGreen = Hv_App_PQ_GetRealValue(ucGreen, PQ_RGBOFFSET);
    usRed =  Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBROffset), PQ_RGBOFFSET);
    usBlue = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBBOffset), PQ_RGBOFFSET);
    
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_MAIN, usRed, usGreen, usBlue);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_SUB, usRed, usGreen, usBlue);
#endif

    return;
}

VOID Hv_App_PQ_SetBOffset(UCHAR8 ucBlue)
{
    USHORT16 usRed = 0;
    USHORT16 usGreen = 0;
    USHORT16 usBlue = 0;
    
    HV_LOG_DEBUG(PQ, "Set B %d", ucBlue);
    HV_PQ_DATABASE_SET(DiagData, usDBBOffset, ucBlue);
    usBlue = Hv_App_PQ_GetRealValue(ucBlue, PQ_RGBOFFSET);
    usRed =   Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBROffset), PQ_RGBOFFSET);
    usGreen = Hv_App_PQ_GetRealValue(HV_PQ_DATABASE_GET(DiagData, usDBGOffset), PQ_RGBOFFSET);
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_MAIN, usRed, usGreen, usBlue);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetRGBOffset(CHANNEL_SUB, usRed, usGreen, usBlue);
#endif

    return;
}
//AKA Brightness
VOID Hv_App_PQ_SetBlackLevel(UCHAR8 ucBlackLevel)
{
    USHORT16 usBlackLevel = 0;
    usBlackLevel = Hv_App_PQ_GetRealValue(ucBlackLevel, PQ_BLACKLEVEL);
    HV_LOG_DEBUG(PQ, "Set BlackLevel %d %d", ucBlackLevel, usBlackLevel);
    HV_PQ_DATABASE_SET(DiagData, ucDBBlackLevel, usBlackLevel);
    Hv_Mw_PQ_SetBlackLevel(CHANNEL_MAIN, usBlackLevel);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetBlackLevel(CHANNEL_SUB, usBlackLevel);
#endif

    return;
}

VOID Hv_App_PQ_SetSaturation(UCHAR8 ucSaturation)
{
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucSaturation, ucSaturation);
    HV_LOG_DEBUG(PQ, "Set Saturation %d", ucSaturation);
    HV_PQ_DATABASE_SET(DiagData, ucDBSaturation, ucSaturation);
    ucSaturation = Hv_App_PQ_GetRealValue(ucSaturation, PQ_SATURATION);
    Hv_Mw_PQ_SetSaturation(CHANNEL_MAIN, ucSaturation);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetSaturation(CHANNEL_SUB, ucSaturation);
#endif

    return;
}

UCHAR8 Hv_App_PQ_GetSaturation(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucSaturation);
}

VOID Hv_App_PQ_CMChangeLut(UINT32 uiLutAddr)
{
    Hv_Mw_PQ_CMChangeLut(uiLutAddr);
    return;
}

VOID Hv_App_PQ_SetBrightRange(PQBrightRange enRange)
{
    const ChannelManager *pstChannelManager = Hv_Mw_Channel_GetManager();
    ColorRangeType eMainClrRange = 0;
    ColorRangeType eSubClrRange = 0;

    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucLdr, enRange);
    enRange = Hv_App_PQ_GetRealValue(enRange, PQ_BRIGHTRANGE);
    HV_PQ_DATABASE_SET(DiagData, ucDBBrightRange, enRange);
    if(pstChannelManager->astChannelData[CHANNEL_MAIN].stVideoConfigParams.stColor.eClrFormat == ColorFormatType_RGB) 
    {
        if(PQ_BRIGHT_RANGE_AUTO == enRange)
        {
            eMainClrRange = pstChannelManager->astChannelData[CHANNEL_MAIN].stVideoConfigParams.stColor.eClrRange;
            if(eMainClrRange == ColorRangeType_Full_Range)///FULL
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_MAIN, PQ_Full_Range);  
            }
            else//limit
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_MAIN, PQ_LIMIT_Range); 
            }
        }
        else
        {
            if(enRange == PQ_BRIGHT_RANGE_FULL)///FULL
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_MAIN, PQ_Full_Range); 
            }
            else//limit
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_MAIN, PQ_LIMIT_Range); 
            }
        }
    }   
    else
    {
        //do nothing when yuv
    }
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    if(pstChannelManager->astChannelData[CHANNEL_SUB].stVideoConfigParams.stColor.eClrFormat == ColorFormatType_RGB) 
    {
        if(PQ_BRIGHT_RANGE_AUTO == enRange)
        {
            eSubClrRange = pstChannelManager->astChannelData[CHANNEL_SUB].stVideoConfigParams.stColor.eClrRange;
            if(eSubClrRange == ColorRangeType_Full_Range)///FULL
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_SUB, PQ_Full_Range);  
            }
            else//limit
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_SUB, PQ_LIMIT_Range); 
            }
        }
        else
        {
            if(enRange == PQ_BRIGHT_RANGE_FULL)///FULL
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_SUB, PQ_Full_Range); 
            }
            else//limit
            {
                Hv_Mw_PQ_SetBrightRange(CHANNEL_SUB, PQ_LIMIT_Range); 
            }
        }
    } 
    else
    {
        //do nothing when yuv
    }
#endif

    HV_LOG_DEBUG(PQ, "Set BrightRange %d %d %d", enRange, eMainClrRange, eSubClrRange);

    return;
}

UCHAR8 Hv_App_PQ_GetBrightRange(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucLdr);
}

VOID Hv_App_PQ_SetColorSpace(PQColorSpace enColorSpace)
{
    HV_LOG_DEBUG(PQ, "Set ColorSpace %d", enColorSpace);
    enColorSpace = Hv_App_PQ_GetRealValue(enColorSpace, PQ_COLORSPACE);
    HV_PQ_DATABASE_SET(DiagData, ucDBColorSpace, enColorSpace);
    Hv_Mw_PQ_SetColorSpace(CHANNEL_MAIN, enColorSpace);
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
    Hv_Mw_PQ_SetColorSpace(CHANNEL_SUB, enColorSpace);
#endif

    return;
}

VOID Hv_App_PQ_DitherInit(VOID)
{
    HV_LOG_DEBUG(PQ,"SRP dither %x\n", auiDitherSrpbin);
    Hv_Mw_PQ_DitherInit(auiDitherSrpbin, INIT_BIN_SIZE(auiDitherSrpbin));
    HV_LOG_DEBUG(PQ,"LDG dither %x\n", auiDitherLdgbin);
    Hv_Mw_PQ_DitherInit(auiDitherLdgbin, INIT_BIN_SIZE(auiDitherLdgbin));

    return;
}

VOID Hv_App_PQ_SetBrightness(UCHAR8 ucBrightness)
{
    const ChannelManager *pstChannelManager = Hv_Mw_Channel_GetManager();
    UCHAR8 ucSwitch = 0;
    ucSwitch = (pstChannelManager->astChannelData[0].stVideoConfigParams.stHdrParam.xType == 0)?0:1;
    USHORT16 usBrightness  = 0;
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucBrightness, ucBrightness);
    HV_LOG_DEBUG(PQ, "Brightness1 %u %u", ucBrightness, ucSwitch);
    if(ucSwitch == 0)
    {
        usBrightness = Hv_App_PQ_GetRealValue(ucBrightness, PQ_BRIGHTNESS);
    }
    else
    {
        usBrightness = Hv_App_PQ_GetRealValue(ucBrightness, PQ_BRIGHTNESS_HDR);
    }

    HV_PQ_DATABASE_SET(DiagData, usDBBrightness, usBrightness);
    Hv_Mw_PQ_SetBrightness(usBrightness);

    return;
}

UCHAR8 Hv_App_PQ_GetBrightness(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucBrightness);
}

VOID Hv_App_PQ_ScalerUpLutInit(VOID)
{
    HV_LOG_DEBUG(PQ, "set Scaler Down lut= %x",auiScalerDownLut);
    Hv_Mw_PQ_ScalerUpLutInit(auiScalerDownLut);

    return;
}

Status Hv_App_PQ_DispCtrlInit(VOID)
{
    DispCtrlCfg stCfg =
    {
        .puiFrameDetThd = uiFramerateDetThreshold,
        .puiGammaVrrLut = uiDispCtrlGammaVrrLut,
        .puiODLut0 = uiODLut0,
        .puiODLut1 = uiODLut1,
        .puiDemuraLut = 0,
        .uiDemuraLutLen = 0,
    };

    return Hv_Mw_PQ_DispCtrlInit(&stCfg);
}

VOID Hv_App_PQ_SetHdrSwitch(UINT32 uiValue)
{
    Hv_Mw_PQ_SetHdrSwitch(uiValue);

    return;
}

VOID Hv_App_PQ_SetODLevel(UCHAR8 ucODLevel)
{
    HV_COMMON_DATABASE_SET(UserData, ucResponseTime, ucODLevel);
#ifdef CONFIG_USER_DISPCTRL_OD_ON
    Hv_Mw_PQ_SetODLevel(ucODLevel);
#endif
    return;
}

UCHAR8 Hv_App_PQ_GetODLevel(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucResponseTime);
}

VOID Hv_App_PQ_SetDCR(UCHAR8 ucEn)
{
    HV_COMMON_DATABASE_SET(UserData, bVariableBackLight, ucEn);
    return Hv_Mw_PQ_DynamicBLEn(ucEn); 
}

UCHAR8 Hv_App_PQ_GetDCR(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, bVariableBackLight);
}

VOID Hv_App_PQ_DoubleChannelEnable(UCHAR8 ucEn)
{
    if(ucEn == HV_ENABLE)
    {
        /* disable GC sharpness when double channel enable */
        Hv_Mw_PQ_GCEnable(HV_DISABLE);
        Hv_Mw_PQ_SharpnessEnable(HV_DISABLE);
    }
    else
    {
        Hv_Mw_PQ_GCEnable(HV_ENABLE);
        Hv_Mw_PQ_SharpnessEnable(HV_ENABLE);
    }

    return;
}

VOID Hv_App_PQ_LdcSetMode(UCHAR8 ucMode)
{
    USHORT16 asMaxWeightLevel[4] = {0, 55, 32, 16};
    HV_COMMON_DATABASE_SET(UserData, bVariableBackLight, ucMode);
    Hv_Mw_PQ_LdcSetMode(ucMode, asMaxWeightLevel[ucMode]);
    return;
}

#if (HV_PROJECT_CONFIG_AMBILIGHT == HV_CONFIG_ON)
VOID Hv_App_PQ_CrosshairInit(VOID)
{
    Hv_Mw_PQ_CrosshairInit();
    return;
}

VOID Hv_App_PQ_CrosshairEnable(BOOL bEnable)
{
    Hv_Mw_PQ_CrosshairEnable(bEnable);
    return;
}

VOID Hv_App_PQ_CrosshairSetArea(CrosshairArea *pstArea)
{
    Hv_Mw_PQ_CrosshairSetArea(pstArea);
    return;
}

#endif


VOID Hv_App_PQ_SetColorTemp(PQColorTemp enType, UCHAR8 ucLowBlueLevel)
{
    ColorTemperature stColTemp = {0};
    /* 根据当前bgain，进行不同挡位的色温设置 */
    UCHAR8 ucBlueRatio = 100 - (ucLowBlueLevel * 5);
    UCHAR8 ucBlue = 0;
    /* 更新userdata数据 */
    HV_COMMON_DATABASE_SET(UserData, ucColorTemperature, enType);
    HV_COMMON_DATABASE_SET(UserData, ucLowBlueLight, ucLowBlueLevel);
    switch (enType)
    {
        case PQ_COLOR_TEMP_COOL:
        {
            stColTemp = HV_COMMON_DATABASE_GET(FactoryData, stColTempCool);
            ucBlue = (USHORT16)stColTemp.ucColorTempBGain * (USHORT16)ucBlueRatio / 100;
            Hv_App_PQ_SetRGBGainFac(stColTemp.ucColorTempRGain, stColTemp.ucColorTempGGain, ucBlue);
            break;
        }
        case PQ_COLOR_TEMP_STANDARD:
        {
            stColTemp = HV_COMMON_DATABASE_GET(FactoryData, stColTempStandard);
            ucBlue = (USHORT16)stColTemp.ucColorTempBGain * (USHORT16)ucBlueRatio / 100;
            Hv_App_PQ_SetRGBGainFac(stColTemp.ucColorTempRGain, stColTemp.ucColorTempGGain, ucBlue);
            break;
        }
        case PQ_COLOR_TEMP_WARM:
        {
            stColTemp = HV_COMMON_DATABASE_GET(FactoryData, stColTempWarm);
            ucBlue = (USHORT16)stColTemp.ucColorTempBGain * (USHORT16)ucBlueRatio / 100;
            Hv_App_PQ_SetRGBGainFac(stColTemp.ucColorTempRGain, stColTemp.ucColorTempGGain, ucBlue);
            break;
        }
        case PQ_COLOR_TEMP_CUSTOM:
        {
            ucBlue = (USHORT16)(HV_COMMON_DATABASE_GET(UserData, ucBlue)) * (USHORT16)ucBlueRatio / 100;
            Hv_App_PQ_SetRGBGain(HV_COMMON_DATABASE_GET(UserData, ucRed),
                                      HV_COMMON_DATABASE_GET(UserData, ucGreen),
                                      ucBlue);
            break;
        }
        default:
        {
            break;
        }
    }
    return;
}

UCHAR8 Hv_App_PQ_GetColorTemp(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucColorTemperature);
}

UCHAR8 Hv_App_PQ_GetLowBlueLight(VOID)
{
    return HV_COMMON_DATABASE_GET(UserData, ucLowBlueLight);
}

/*In case Ratio in OSD doesnot match Ratio in Driver*/
UCHAR8 Hv_App_PQ_RatioMapping()
{
    return HV_COMMON_DATABASE_GET(UserData, ucProportion);
}
/* 动态背光参数 */
#define PQ_DBLSMOOTHNUM     (5)    //存储连续5帧的全局平均亮度值
#define PQ_DBLPWMSTEP       (50)   //限制单帧PWM最大变化步长
/* 光感调试平滑buffer */
static USHORT16 s_usSmoothBuf[PQ_DBLSMOOTHNUM] = {0};
static UCHAR8   s_ucSmoothId = 0;



static VOID Hv_App_PQ_DCRProc(const VideoConfigParams* pstVideoConfigParams)
{
    UINT32   uiSum = 0;
    USHORT16 usSmoothPixelVal = 0;
    USHORT16 usBrightVal = 0;
    USHORT16 usBrightTargetVal = 0;
    static USHORT16 usPreBrightVal = 0;
    static USHORT16 usDelayVal = 0;
    USHORT16 usAvgPixelVal = Hv_Mw_PQ_LDCGetGlobalAvgBright();
    USHORT16 usMaxPixelVal = Hv_Mw_PQ_LDCGetGlobalMaxBright();

    s_usSmoothBuf[s_ucSmoothId] = usAvgPixelVal;
    /* 更新最新数据的序号 */
    s_ucSmoothId = (s_ucSmoothId + 1) % PQ_DBLSMOOTHNUM;

    for (UCHAR8 ucLoop = 0; ucLoop < PQ_DBLSMOOTHNUM; ucLoop++)
    {
        uiSum += s_usSmoothBuf[ucLoop];
    }
    usSmoothPixelVal = uiSum / PQ_DBLSMOOTHNUM;

    usBrightTargetVal = LINEAR_MAPPING_VALUE(usSmoothPixelVal, PQ_DCR_PIXEL_MIN, PQ_DCR_PIXEL_MAX,
            PQ_DCR_PWM_MIN, PQ_DCR_PWM_MAX);
    /*  亮度 设定按照步长逐帧调试 */
    if (ABS(usBrightTargetVal, usPreBrightVal) > PQ_DBLPWMSTEP)
    {
        if (usBrightTargetVal > usPreBrightVal)
        {
            usBrightVal = usPreBrightVal + PQ_DBLPWMSTEP;
        }
        else
        {
            usBrightVal = usPreBrightVal - PQ_DBLPWMSTEP;
        }
    }
    else
    {
        usBrightVal = usBrightTargetVal;
    }

    Hv_Mw_PQ_SetBrightness(usBrightVal);
    usPreBrightVal = usBrightVal;
    return;
}

#if (HV_CONFIG_ON == HV_PROJECT_CONFIG_AMBIENT_LIGHT)
VOID Hv_App_PQ_SetMonoLight(UCHAR8 ucColorType)
{
    Hv_Mw_PQ_UpdateSingleColor(ucColorType);
    return;
}

VOID Hv_App_PQ_SetAmbilight(AmbilightType enType, UCHAR8 ucColorType)
{
    Hv_Mw_PQ_BulbDeInit();

    switch (enType)
    {
        case AMBILIGHT_OFF:
        {
            Hv_Mw_AmbientLight_Stop();
            Hv_Mw_PQ_StopAmbilightTimer();
            Hv_Mw_PQ_StopAutoTimer();
            Hv_Mw_PQ_StopMarqueeTimer();
            break;
        }
        case AMBILIGHT_VIDEO:
        {
            Hv_Mw_AmbientLight_Stop();
            Hv_Mw_PQ_StopAutoTimer();
            Hv_Mw_PQ_StopMarqueeTimer();

            Hv_Mw_PQ_StartFollowingPQ();
            Hv_Mw_PQ_StartAmbilightTimer(40);
            break;
        }
        case AMBIENTLIGHT_AUDIO:
        {
            Hv_Mw_PQ_StopAmbilightTimer();
            Hv_Mw_PQ_StopAutoTimer();
            Hv_Mw_PQ_StopMarqueeTimer();

            Hv_Mw_AmbientLight_Start();
            break;
        }
        case AMBIENTLIGHT_MONO:
        {
            Hv_Mw_AmbientLight_Stop();
            Hv_Mw_PQ_StopAmbilightTimer();
            Hv_Mw_PQ_StopAutoTimer();
            Hv_Mw_PQ_StopMarqueeTimer();

            Hv_Mw_PQ_UpdateSingleColor(ucColorType);
            break;
        }
        case AMBIENTLIGHT_MARQUEE:
        {
            Hv_Mw_AmbientLight_Stop();
            Hv_Mw_PQ_StopAmbilightTimer();
            Hv_Mw_PQ_StopAutoTimer();

            Hv_Mw_PQ_StartMarqueeColor();
            Hv_Mw_PQ_StartMarqueeTimer(1000);
            break;
        }
        case AMBIENTLIGHT_AUTO:
        {
            Hv_Mw_AmbientLight_Stop();
            Hv_Mw_PQ_StopAmbilightTimer();
            Hv_Mw_PQ_StopMarqueeTimer();

            Hv_Mw_PQ_StartAutoColor();
            Hv_Mw_PQ_StartAutoTimer(1000);
            break;
        }
        default:
        {        
            Hv_Mw_AmbientLight_Stop();
            Hv_Mw_PQ_StopAmbilightTimer();
            Hv_Mw_PQ_StopAutoTimer();
            Hv_Mw_PQ_StopMarqueeTimer();
            break;
        }
    }

}
#endif

UCHAR8 Hv_App_PQ_CallBack(PQCALLBACKMODE enMode, const VOID *pvVideoConfigParams)
{

    const VideoConfigParams* pstVideoConfigParams = (VideoConfigParams*)pvVideoConfigParams;
    UCHAR8 ucRet = 0;

    switch(enMode)
    {
        case PQCALLBACK_VSYNC:
        {
            /* DCR开启时，动态调整亮度 */
            if(Hv_Mw_PQ_GetDynamicBLEn() != 0)
            {
                Hv_App_PQ_DCRProc(pstVideoConfigParams);
            }
            break;
        }
        case PQCALLBACK_TIMECHANGED:
#if ((HV_CONFIG_ON == HV_PROJECT_CONFIG_PXP) || (HV_CONFIG_ON == HV_PROJECT_CONFIG_MAGNIFY))
        {
            if ((HV_FALSE == pstVideoConfigParams->bMainFakeSwitch)
                && (PXP_MODE_CLOSE != pstVideoConfigParams->enPxpMode))
            {
                /* 只有开启PBP和PIP时使能PQ双通道配置，放大镜和单通道配置保持一致 */
                Hv_App_PQ_DoubleChannelEnable(HV_ENABLE);
            }
            else
            {
                Hv_App_PQ_DoubleChannelEnable(HV_DISABLE);
            }
         }
#endif
            break;
        case PQCALLBACK_RATIOMAPPING:
        {
            ucRet = Hv_App_PQ_RatioMapping();
            break;
        }
        default:
        {
            break;
        }

    }

    return ucRet; 
}

VOID Hv_App_PQ_LdcBacklightStart()
{
    return;
}
