/*
* Copyright (c) 2009-2021, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file     vphal_common.h
//! \brief    clarify common utilities for vphal
//! \details  clarify common utilities for vphal including:
//!           some marcro, enum, union, structure, function
//!
#ifndef __VPHAL_COMMON_H__
#define __VPHAL_COMMON_H__

#if EMUL || VPHAL_LIB

#include "support.h"

#endif  // EMUL || VPHAL_LIB

#include "mos_os.h"
#include "vp_common_hdr.h"
#include "media_common_defs.h"
#include "vp_common.h"

#ifdef __cplusplus
extern "C" {
#endif

//!
//! \def DBG_TEXT(txt)
//! Allow certain \a txt fields to be present only on DEBUG builds.
//!
#if _DEBUG
#define DBG_TEXT(txt) txt
#else
#define DBG_TEXT(txt) ""
#endif

#ifndef ABS
//!
//! \def ABS( x )
//! Calcualte absolute value of \a x.
//!
#define ABS(a)      (((a) < 0) ? (-(a)) : (a))
#endif

//!
//! \def OUT_OF_BOUNDS(a, min, max)
//! Calcualte if \a a out the range of  [\a min, \a max].
//!
#define OUT_OF_BOUNDS(a, min, max) ( ((a) < (min)) || ((a) > (max)) )

//!
//! \def WITHIN_BOUNDS(a, min, max)
//! Calcualte if \a a within the range of  [\a min, \a max].
//!
#define WITHIN_BOUNDS(a, min, max) ( ((a) >= (min)) && ((a) <= (max)) )

//!
//! \def VPHAL_ABS(x)
//! Calcualte the Abslute value of \a x.
//!
#define VPHAL_ABS(x)               (((x) > 0) ? (x) : -(x))

#define VPHAL_PI                   3.14159265358979324f //!< Definition the const pi

//!
//! \def SAME_SIZE_RECT(rect1, rect2)
//! Compare if the size of two rectangles is the same
//!
#define SAME_SIZE_RECT(rect1, rect2)                                            \
    (((rect1).right  - (rect1).left == (rect2).right  - (rect2).left) &&        \
     ((rect1).bottom - (rect1).top  == (rect2).bottom - (rect2).top))

//!
//! \def RECT1_EQUALS_RECT2(rect1, rect2)
//! Compare if two rectangles has the same coordinate
//!
#define RECT1_EQUALS_RECT2(rect1, rect2)                                        \
    (((rect1).left  == (rect2).left)  && ((rect1).top    == (rect2).top) &&     \
     ((rect1).right == (rect2).right) && ((rect1).bottom == (rect2).bottom))

//!
//! \def RECT1_CONTAINS_RECT2(rect1, rect2)
//! Compare if rectangle \a rect1 contains rectangle \a rect2 in coordinate
//!
#define RECT1_CONTAINS_RECT2(rect1, rect2)                                      \
    (((rect1).left  <= (rect2).left)  && ((rect1).top    <= (rect2).top) &&     \
     ((rect1).right >= (rect2).right) && ((rect1).bottom >= (rect2).bottom))

//!
//! \def RECT1_CONTAINS_RECT2_ONEPIXELBIAS(rect1, rect2)
//! Compare if rectangle \a rect1 contains rectangle \a rect2 in coordinate, One pixel bias is allowed
//!
#define RECT1_CONTAINS_RECT2_ONEPIXELBIAS(rect1, rect2)                                    \
    (((rect1).left  <= ((rect2).left + 1))  && ((rect1).top    <= ((rect2).top + 1)) &&  \
     (((rect1).right + 1) >= (rect2).right) && (((rect1).bottom + 1) >= (rect2).bottom))

//!
//! \def RECT1_OUTSIDE_RECT2(rect1, rect2)
//! Compare if the rectangle \a rect1 is outside the rectangle \a rect2 at least partly in coordinate
//!
#define RECT1_OUTSIDE_RECT2(rect1, rect2)                                       \
    (((rect1).left  >= (rect2).right) || ((rect1).top    >= (rect2).bottom) ||  \
     ((rect1).right <= (rect2).left)  || ((rect1).bottom <= (rect2).top))

//!
// \def DEGREE_TO_RADIAN(degree)
// Convert a degree value \a degree to radian.
//!
#define DEGREE_TO_RADIAN(degree)   (degree) * (VPHAL_PI) / 180
#define AVS_TBL_COEF_PREC         6           //!< Table coef precision (after decimal point
#define SAME_SAMPLE_THRESHOLD     1000        //!< When checking whether 2 timestamps are the same, leave room for some error

//!
//! \def MEDIA_IS_HDCONTENT(dwWidth, dwHeight)
//! Determine if the size of content is HD
//!
#define MEDIA_SDCONTENT_MAX_WIDTH        720
#define MEDIA_SDCONTENT_MAX_PAL_HEIGHT   576
#define MEDIA_SDCONTENT_MAX_SW_WIDTH     768
#define MEDIA_IS_HDCONTENT(dwWidth, dwHeight)    ((dwWidth > MEDIA_SDCONTENT_MAX_SW_WIDTH) || (dwHeight > MEDIA_SDCONTENT_MAX_PAL_HEIGHT))

//! \brief  Surface cache attributes
//!
#define VPHAL_SET_SURF_MEMOBJCTL(VpField, GmmUsageEnum)                                                         \
    {                                                                                                           \
        Usage = GmmUsageEnum;                                                                                   \
        MemObjCtrl = pOsInterface->pfnCachePolicyGetMemoryObject(Usage, pOsInterface->pfnGetGmmClientContext(pOsInterface));                                        \
        VpField = MemObjCtrl.DwordValue;                                                                        \
    }


// ProcAmp Default Values
#define PROCAMP_BRIGHTNESS_MIN     -100.0F
#define PROCAMP_BRIGHTNESS_MAX      100.0F
#define PROCAMP_BRIGHTNESS_DEFAULT    0.0F
#define PROCAMP_BRIGHTNESS_STEP       0.1F
#define PROCAMP_CONTRAST_MIN          0.0F
#define PROCAMP_CONTRAST_MAX         10.0F
#define PROCAMP_CONTRAST_DEFAULT      1.0F
#define PROCAMP_CONTRAST_STEP         0.01F
#define PROCAMP_HUE_MIN            -180.0F
#define PROCAMP_HUE_MAX             180.0F
#define PROCAMP_HUE_DEFAULT           0.0F
#define PROCAMP_HUE_STEP              0.1F
#define PROCAMP_SATURATION_MIN        0.0F
#define PROCAMP_SATURATION_MAX       10.0F
#define PROCAMP_SATURATION_DEFAULT    1.0F
#define PROCAMP_SATURATION_STEP       0.01F

// Denoise Default Values
#define NOISEREDUCTION_MIN            0.0F
#define NOISEREDUCTION_MAX           64.0F
#define NOISEREDUCTION_DEFAULT        0.0F
#define NOISEREDUCTION_STEP           1.0F

// Sharpness Values
#define EDGEENHANCEMENT_MIN           0.0F
#define EDGEENHANCEMENT_MAX          64.0F
#define EDGEENHANCEMENT_DEFAULT      44.0F
#define EDGEENHANCEMENT_STEP          1.0F
#define IEF_STRONG_EDGE_WEIGHT          7
#define IEF_REGULAR_WEIGHT              2
#define IEF_STRONG_EDGE_THRESHOLD       8

// Skin Tone Detection/Enhancement  values
#define STE_MIN                       0.0F
#define STE_MAX                       9.0F
#define STE_DEFAULT                   3.0F
#define STE_STEP                      1.0F

// Total Color Correction values
#define TCC_MIN                       0.0F
#define TCC_MAX                     255.0F
#define TCC_DEFAULT                 160.0F
#define TCC_STEP                      1.0F

// Adaptive Contrast Enhancement values
#define ACE_LEVEL_DEFAULT               5
#define ACE_STRENGTH_DEFAULT            1

// Compositing Block size
#define VPHAL_COMP_BLOCK_WIDTH  16
#define VPHAL_COMP_BLOCK_HEIGHT 16

// NLAS Default Values
#define NLAS_VERTICALCROP_MIN         0.0F
#define NLAS_VERTICALCROP_MAX         1.0F
#define NLAS_VERTICALCROP_DEFAULT     0.0F
#define NLAS_VERTICALCROP_STEP        0.001F
#define NLAS_HLINEARREGION_MIN        0.0F
#define NLAS_HLINEARREGION_MAX        1.0F
#define NLAS_HLINEARREGION_DEFAULT    1.0F
#define NLAS_HLINEARREGION_STEP       0.001F
#define NLAS_NONLINEARCROP_MIN        0.0F
#define NLAS_NONLINEARCROP_MAX        1.0F
#define NLAS_NONLINEARCROP_DEFAULT    0.0F
#define NLAS_NONLINEARCROP_STEP       0.001F

#define VPHAL_MAX_SOURCES               65       //!< worst case: 64 sub-streams + 1 pri video
#define VPHAL_MAX_CHANNELS              2
#define VPHAL_MAX_TARGETS               8        //!< multi output support
#define VPHAL_MAX_FUTURE_FRAMES         18       //!< maximum future frames supported in VPHAL

#define VPHAL_TOP_FIELD           0
#define VPHAL_BOTTOM_FIELD        1
#define VPHAL_TOP_FIELD_FIRST     0
#define VPHAL_BOTTOM_FIELD_FIRST  1

typedef struct _VPHAL_COMPOSITE_CACHE_CNTL
{
    bool                           bL3CachingEnabled;
    VPHAL_MEMORY_OBJECT_CONTROL    PrimaryInputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    InputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    TargetSurfMemObjCtl;
} VPHAL_COMPOSITE_CACHE_CNTL, *PVPHAL_COMPOSITE_CACHE_CNTL;

typedef struct _VPHAL_DNDI_CACHE_CNTL
{
    bool                            bL3CachingEnabled;
    VPHAL_MEMORY_OBJECT_CONTROL     CurrentInputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     PreviousInputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     STMMInputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     STMMOutputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     DnOutSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     CurrentOutputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     StatisticsOutputSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     LaceOrAceOrRgbHistogramSurfCtrl;
    VPHAL_MEMORY_OBJECT_CONTROL     AlphaOrVignetteSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     SkinScoreSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     LaceLookUpTablesSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL     Vebox3DLookUpTablesSurfMemObjCtl;
} VPHAL_DNDI_CACHE_CNTL, *PVPHAL_DNDI_CACHE_CNTL;

typedef struct _VPHAL_LACE_CACHE_CNTL
{
    // LACE would reuse the bL3CachingEnabled of VEBOX's cache control
    VPHAL_MEMORY_OBJECT_CONTROL    FrameHistogramSurfaceMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    AggregatedHistogramSurfaceMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    StdStatisticsSurfaceMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    PwlfInSurfaceMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    PwlfOutSurfaceMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    WeitCoefSurfaceMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    GlobalToneMappingCurveLUTSurfaceMemObjCtl;
} VPHAL_LACE_CACHE_CNTL, *PVPHAL_LACE_CACHE_CNTL;

typedef struct _VPHAL_16_ALIGN_CACHE_CNTL
{
    bool                           bL3CachingEnabled;
    VPHAL_MEMORY_OBJECT_CONTROL    SourceSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    TargetSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    SamplerParamsSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    SamplerParamsStatsSurfMemObjCtl;
}VPHAL_16_ALIGN_CACHE_CNTL, *PVPHAL_16_ALIGN_CACHE_CNTL;

typedef struct _VPHAL_FAST1TON_CACHE_CNTL
{
    bool                           bL3CachingEnabled;
    VPHAL_MEMORY_OBJECT_CONTROL    SourceSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    TargetSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    SamplerParamsSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    SamplerParamsStatsSurfMemObjCtl;
}VPHAL_FAST1TON_CACHE_CNTL, *PVPHAL_FAST1TON_CACHE_CNTL;

typedef struct _VPHAL_HDR_CACHE_CNTL
{
    bool                           bL3CachingEnabled;
    VPHAL_MEMORY_OBJECT_CONTROL    SourceSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    TargetSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    Lut2DSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    Lut3DSurfMemObjCtl;
    VPHAL_MEMORY_OBJECT_CONTROL    CoeffSurfMemObjCtl;
} VPHAL_HDR_CACHE_CNTL, *PVPHAL_HDR_CACHE_CNTL;

//!
//! \brief  Feature specific cache control settings
//!
typedef struct _VPHAL_RENDER_CACHE_CNTL
{
    // Input
    bool                        bDnDi;
    bool                        bCompositing;
    bool                        bLace;

    // Output
    VPHAL_DNDI_CACHE_CNTL        DnDi;
    VPHAL_COMPOSITE_CACHE_CNTL   Composite;
    VPHAL_LACE_CACHE_CNTL        Lace;
} VPHAL_RENDER_CACHE_CNTL, *PVPHAL_RENDER_CACHE_CNTL;


//!
//! \brief Vphal Output chroma configuration enum
//!
typedef enum _VPHAL_CHROMA_SUBSAMPLING
{
    CHROMA_SUBSAMPLING_TOP_CENTER       = 0,
    CHROMA_SUBSAMPLING_CENTER_CENTER,
    CHROMA_SUBSAMPLING_BOTTOM_CENTER,
    CHROMA_SUBSAMPLING_TOP_LEFT,
    CHROMA_SUBSAMPLING_CENTER_LEFT,
    CHROMA_SUBSAMPLING_BOTTOM_LEFT
} VPHAL_CHROMA_SUBSAMPLING;

//!
//! \brief Vphal Gamma Values configuration enum
//!
typedef enum _VPHAL_GAMMA_VALUE
{
    GAMMA_1P0 = 0,
    GAMMA_2P2,
    GAMMA_2P6
} VPHAL_GAMMA_VALUE;

typedef enum _VPHAL_DP_ROTATION_MODE
{
    VPHAL_DP_ROTATION_NV12_AVG            = 0,   //!< nv12 -> yuy2 by chroma average
    VPHAL_DP_ROTATION_NV12_NV12              ,   //!< nv12 -> nv12
    VPHAL_DP_ROTATION_NV12_REP               ,   //!< nv12 -> yuy2 by chroma repeat
    VPHAL_DP_ROTATION_NV12_YUY2_NOT_SET          //!< nv12 -> yuy2 by chroma average or repeat, decided by scaling mode
} VPHAL_DP_ROTATION_MODE;

//!
//! \def IS_RGB_LIMITED_RANGE(_a)
//! Check if RGB limited range
//!
#define IS_RGB_LIMITED_RANGE(_a)               (_a == CSpace_stRGB       || \
                                                _a == CSpace_BT2020_stRGB)

//!
//! \def IS_RGB_FULL_RANGE(_a)
//! Check if RGB full range
//!
#define IS_RGB_FULL_RANGE(_a)                  (_a == CSpace_sRGB       || \
                                                _a == CSpace_BT2020_sRGB)

//!
//! \def IS_YUV_LIMITED_RANGE(_a)
//! Check if YUV limited range
//!
#define IS_YUV_LIMITED_RANGE(_a)               (_a == CSpace_BT601       || \
                                                _a == CSpace_BT709       || \
                                                _a == CSpace_BT601Gray   || \
                                                _a == CSpace_BT2020)

//!
//! \def IS_YUV_FULL_RANGE(_a)
//! Check if YUV full range
//!
#define IS_YUV_FULL_RANGE(_a)                  (_a == CSpace_BT601_FullRange       || \
                                                _a == CSpace_BT709_FullRange       || \
                                                _a == CSpace_BT601Gray_FullRange   || \
                                                _a == CSpace_BT2020_FullRange)


//!
//! \brief Frame Format enum
//!
typedef enum _VPHAL_FRAME_FORMAT
{
    FRAME_FORMAT_PROGRESSIVE,
    FRAME_FORMAT_INTERLEAVED,
    FRAME_FORMAT_FIELD
} VPHAL_FRAME_FORMAT;




//!
//! \brief Gamut Mode enum
//!
typedef enum _VPHAL_GAMUT_MODE
{
    GAMUT_MODE_NONE,
    GAMUT_MODE_BASIC,
    GAMUT_MODE_ADVANCED
} VPHAL_GAMUT_MODE;
C_ASSERT(GAMUT_MODE_ADVANCED == 2); //!< When adding, update assert & vphal_solo_scenario.cpp

//!
//! \def SET_VPHAL_OUTPUT_PIPE(_a, _Pipe)
//! Set the output pipe
//!
#define SET_VPHAL_OUTPUT_PIPE(_a, _Pipe)                           \
    {                                                              \
        (_a->OutputPipe = _Pipe);                                  \
        VPHAL_RENDER_NORMALMESSAGE("VPHAL_OUTPUT_PIPE %d", _Pipe); \
    }

//!
//! \def IS_VPHAL_OUTPUT_PIPE_INVALID(_a)
//! Sheck if the output pipe is invalid
//!
#define IS_VPHAL_OUTPUT_PIPE_INVALID(_a)              (_a->OutputPipe == VPHAL_OUTPUT_PIPE_MODE_INVALID)

//!
//! \def IS_VPHAL_OUTPUT_PIPE_COMP(_a)
//! Check if the output pipe is Composition
//!
#define IS_VPHAL_OUTPUT_PIPE_COMP(_a)                 (_a->OutputPipe == VPHAL_OUTPUT_PIPE_MODE_COMP)

//!
//! \def IS_VPHAL_OUTPUT_PIPE_SFC(_a)
//! Check if the output pipe is SFC
//!
#define IS_VPHAL_OUTPUT_PIPE_SFC(_a)                  (_a->OutputPipe == VPHAL_OUTPUT_PIPE_MODE_SFC)

//!
//! \def IS_VPHAL_OUTPUT_PIPE_VEBOX(_a)
//! Check if the output pipe is Vebox
//!
#define IS_VPHAL_OUTPUT_PIPE_VEBOX(_a)                (_a->OutputPipe == VPHAL_OUTPUT_PIPE_MODE_VEBOX)

//!
//! \def SET_VPHAL_COMPONENT(_a, _Component)
//! Set the Component
//!
#define SET_VPHAL_COMPONENT(_a, _Component)           (_a->Component  =  _Component)                     // Set the Component

//!
//! \def SET_VPHAL_MMC_STATE(_a, _bEnableMMC)
//! Set the Component
//!
#define SET_VPHAL_MMC_STATE(_a, _bEnableMMC)          (_a->bEnableMMC =  _bEnableMMC)                    // Set the Component


//!
//! Union   VPHAL_HALF_PRECISION_FLOAT
//! \brief  Vphal half precision float type
//!
typedef union _VPHAL_HALF_PRECISION_FLOAT
{
    struct
    {
        uint16_t      Mantissa : 10;
        uint16_t      Exponent : 5;
        uint16_t      Sign     : 1;
    };

    uint16_t value;
} VPHAL_HALF_PRECISION_FLOAT, PVPHAL_HALF_PRECISION_FLOAT;


//!
//! \brief Vphal 3DLUT Channel Mapping enum
//!
typedef enum _VPHAL_3DLUT_CHANNEL_MAPPING
{
    CHANNEL_MAPPING_RGB_RGB          = 0,
    CHANNEL_MAPPING_YUV_RGB          = 1 << 0,
    CHANNEL_MAPPING_VUY_RGB          = 1 << 1,
} VPHAL_3DLUT_CHANNEL_MAPPING;


//!
//! Structure VPHAL_GAMUT_PARAMS
//! \brief IECP Gamut Mapping Parameters
//!
typedef struct _VPHAL_GAMUT_PARAMS
{
    VPHAL_GAMUT_MODE    GCompMode;
    VPHAL_GAMUT_MODE    GExpMode;
    VPHAL_GAMMA_VALUE   GammaValue;
    uint32_t            dwAttenuation;       //!< U2.10 [0, 1024] 0 = No down scaling, 1024 = Full down scaling
    float               displayRGBW_x[4];
    float               displayRGBW_y[4];
} VPHAL_GAMUT_PARAMS, *PVPHAL_GAMUT_PARAMS;

//!
//! Structure VPHAL_NLAS_PARAMS
//! \brief NLAS parameters - Non-Anamorphic Scaling
//!
typedef struct _VPHAL_NLAS_PARAMS
{
    float               fVerticalCrop;
    float               fHLinearRegion;
    float               fNonLinearCrop;
} VPHAL_NLAS_PARAMS, *PVPHAL_NLAS_PARAMS;

//!
//! Structure VPHAL_COLORFILL_PARAMS
//! \brief ColorFill parameters
//!
typedef struct _VPHAL_COLORFILL_PARAMS
{
    bool                bYCbCr;
    uint32_t            Color;
    VPHAL_CSPACE        CSpace;
    bool                bDisableColorfillinSFC;
    bool                bOnePixelBiasinSFC;
} VPHAL_COLORFILL_PARAMS, *PVPHAL_COLORFILL_PARAMS;

//!
//! Structure VPHAL_ALPHA_FILL_MODE
//! \brief Alpha mode
//!
typedef enum _VPHAL_ALPHA_FILL_MODE
{
    VPHAL_ALPHA_FILL_MODE_NONE = 0,
    VPHAL_ALPHA_FILL_MODE_OPAQUE,
    VPHAL_ALPHA_FILL_MODE_BACKGROUND,
    VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM,
} VPHAL_ALPHA_FILL_MODE;

//!
//! Structure VPHAL_ALPHA_PARAMS
//! \brief Alpha parameters
//!
typedef struct _VPHAL_ALPHA_PARAMS
{
    float                     fAlpha;
    VPHAL_ALPHA_FILL_MODE     AlphaMode;
} VPHAL_ALPHA_PARAMS, *PVPHAL_ALPHA_PARAMS;

//!
//! Structure VPHAL_CONSTRICTION_PARAMS
//! \brief Constriction parameters
//!
typedef struct _VPHAL_CONSTRICTION_PARAMS
{
    RECT                rcConstriction;
} VPHAL_CONSTRICTION_PARAMS, *PVPHAL_CONSTRICTION_PARAMS;

//!
//! Structure VPHAL_SPLIT_SCREEN_DEMO_POSITION
//! \brief Split-Screen Demo Mode Position
//!
typedef enum _VPHAL_SPLIT_SCREEN_DEMO_POSITION
{
    SPLIT_SCREEN_DEMO_DISABLED = 0,
    SPLIT_SCREEN_DEMO_LEFT,
    SPLIT_SCREEN_DEMO_RIGHT,
    SPLIT_SCREEN_DEMO_TOP,
    SPLIT_SCREEN_DEMO_BOTTOM,
    SPLIT_SCREEN_DEMO_END_POS_LIST
} VPHAL_SPLIT_SCREEN_DEMO_POSITION;

//!
//! Structure VPHAL_SPLIT_SCREEN_DEMO_MODE_PARAMS
//! \brief Split-Screen Demo Mode Parameters
//!
typedef struct _VPHAL_SPLIT_SCREEN_DEMO_MODE_PARAMS
{
    VPHAL_SPLIT_SCREEN_DEMO_POSITION        Position;            //!< Position of split mode area (disable features)
    bool                                    bDisableACE : 1; //!< Disable ACE
    bool                                    bDisableAVS : 1; //!< Disable AVS
    bool                                    bDisableDN : 1; //!< Disable DN
    bool                                    bDisableFMD : 1; //!< Disable FMD
    bool                                    bDisableIEF : 1; //!< Disable IEF
    bool                                    bDisableProcamp : 1; //!< Disable Procamp
    bool                                    bDisableSTE : 1; //!< Disable STE
    bool                                    bDisableTCC : 1; //!< Disable TCC
    bool                                    bDisableIS : 1; //!< Disable IS
    bool                                    bDisableDrDb : 1; //!< Disable DRDB
    bool                                    bDisableDNUV : 1; //!< Disable DNUV
    bool                                    bDisableFRC : 1; //!< Disable FRC
    bool                                    bDisableLACE : 1; //!< Disable LACE
} VPHAL_SPLIT_SCREEN_DEMO_MODE_PARAMS, *PVPHAL_SPLIT_SCREEN_DEMO_MODE_PARAMS;

//!
//! Structure VPHAL_RENDER_PARAMS
//! \brief VPHAL Rendering Parameters
//!
struct VPHAL_RENDER_PARAMS
{
    // Input/output surfaces
    uint32_t                                uSrcCount;                  //!< Num sources
    VPHAL_SURFACE                           *pSrc[VPHAL_MAX_SOURCES];   //!< Source Samples
    uint32_t                                uDstCount;                  //!< Num Targets
    VPHAL_SURFACE                           *pTarget[VPHAL_MAX_TARGETS];//!< Render Target

                                                                        // Additional parameters not included in PVPHAL_SURFACE
    PRECT                                   pConstriction;              //!< Constriction rectangle
    PVPHAL_COLORFILL_PARAMS                 pColorFillParams;           //!< ColorFill - BG only
    bool                                    bTurboMode;                 //!< Enable Media Turbo Mode
    bool                                    bStereoMode;                //!< Stereo BLT mode
    PVPHAL_ALPHA_PARAMS                     pCompAlpha;                 //!< Alpha for composited surfaces
    bool                                    bDisableDemoMode;           //!< Enable/Disable demo mode function calls
    PVPHAL_SPLIT_SCREEN_DEMO_MODE_PARAMS    pSplitScreenDemoModeParams; //!< Split-screen demo mode for VP features
    bool                                    bIsDefaultStream;           //!< Identifier to differentiate default stream

                                                                        // Debugging parameters
    MOS_COMPONENT                           Component;                  //!< DDI component (for DEBUGGING only)

                                                                        // Status Report
    bool                                    bReportStatus;              //!< Report current media BB status (Pre-Processing)
    uint32_t                                StatusFeedBackID;           //!< Unique Staus ID;
#if (_DEBUG || _RELEASE_INTERNAL)
    bool                                    bTriggerGPUHang;            //!< Trigger GPU HANG
#endif

    bool                                    bCalculatingAlpha;          //!< Alpha calculation parameters

                                                                        // extension parameters
    void                                    *pExtensionData;            //!< Extension data

    bool                                    bPathKernel;                // HDR path config if use kernel
    bool                                    bAPGWorkloadEnable = false;         //!< Identify Whether APG workload Enabled or not

    bool                                    bDisableVeboxFor8K = false;
    bool                                    bUseVEHdrSfc       = false;  // use SFC for to perform CSC/Scaling/RGBSwap of HDR streaming; if false, use composite render.
    bool                                    bNonFirstFrame     = false;  // first frame or not: first frame false, otherwise true considering zeromemory parameters.
    bool                                    bOptimizeCpuTiming = false;  //!< Optimize Cpu Timing

    VPHAL_RENDER_PARAMS() :
        uSrcCount(0),
        pSrc(),
        uDstCount(0),
        pTarget(),
        pConstriction(nullptr),
        pColorFillParams(nullptr),
        bTurboMode(false),
        bStereoMode(false),
        pCompAlpha(nullptr),
        bDisableDemoMode(false),
        pSplitScreenDemoModeParams(nullptr),
        bIsDefaultStream(false),
        Component(),
        bReportStatus(false),
        StatusFeedBackID(0),
#if (_DEBUG || _RELEASE_INTERNAL)
        bTriggerGPUHang(false),
#endif
        bCalculatingAlpha(false),
        pExtensionData(nullptr),
        bPathKernel(false),
        bUseVEHdrSfc(false),
        bNonFirstFrame(false)
    {
    }

};

typedef VPHAL_RENDER_PARAMS *PVPHAL_RENDER_PARAMS;
typedef const VPHAL_RENDER_PARAMS  *PCVPHAL_RENDER_PARAMS;

//!
//! \brief    Performs Color Space Convert for Sample 8 bit
//! \details  Performs Color Space Convert from Src Color Spase to Dst Color Spase
//! \param    [out] pOutput
//!           Pointer to VPHAL_COLOR_SAMPLE_8
//! \param    [in] pInput
//!           Pointer to VPHAL_COLOR_SAMPLE_8
//! \param    [in] srcCspace
//!           Source Color Space 
//! \param    [in] dstCspace
//!           Dest Color Space 
//! \return   bool
//!           Return true if successful, otherwise false
//!
bool VpHal_CSC_8(
    VPHAL_COLOR_SAMPLE_8    *pOutput,
    VPHAL_COLOR_SAMPLE_8    *pInput,
    VPHAL_CSPACE            srcCspace,
    VPHAL_CSPACE            dstCspace);

//!
//! \brief
//! \details  Get CSC matrix in a form usable by Vebox, SFC and IECP kernels
//! \param    [in] SrcCspace
//!           Source Cspace
//! \param    [in] DstCspace
//!           Destination Cspace
//! \param    [out] pfCscCoeff
//!           [3x3] Coefficients matrix
//! \param    [out] pfCscInOffset
//!           [3x1] Input Offset matrix
//! \param    [out] pfCscOutOffset
//!           [3x1] Output Offset matrix
//! \return   void
//!
void VpHal_GetCscMatrix(
    VPHAL_CSPACE                        SrcCspace,
    VPHAL_CSPACE                        DstCspace,
    float*                              pfCscCoeff,
    float*                              pfCscInOffset,
    float*                              pfCscOutOffset);

//!
//! \brief    sinc
//! \details  Calculate sinc(x)
//! \param    [in] x
//!           float
//! \return   float
//!           sinc(x)
//!
float VpHal_Sinc(float x);

//!
//! \brief    Lanczos
//! \details  Calculate lanczos(x)
//!           Basic formula is:  lanczos(x)= VpHal_Sinc(x) * VpHal_Sinc(x / fLanczosT)
//! \param    [in] x
//!           float
//! \param    [in] dwNumEntries
//!           dword
//! \param    [in] fLanczosT
//! 
//! \return   float
//!           lanczos(x)
//!
float VpHal_Lanczos(
    float        x,
    uint32_t    dwNumEntries,
    float        fLanczosT);


//!
//! \brief    Get Surface Info from OsResource
//! \details  Update surface info in PVPHAL_SURFACE based on allocated OsResource
//! \param    [in] pOsInterface
//!           Pointer to MOS_INTERFACE
//! \param    [in] pInfo
//!           Pointer to VPHAL_GET_SURFACE_INFO
//! \param    [in,out] pSurface
//!           Pointer to VPHAL_SURFACE
//! \return   MOS_STATUS
//!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
//!
MOS_STATUS VpHal_GetSurfaceInfo(
    PMOS_INTERFACE           pOsInterface,
    PVPHAL_GET_SURFACE_INFO  pInfo,
    PVPHAL_SURFACE           pSurface);

//!
//! \brief    Allocates the Surface
//! \details  Allocates the Surface
//!           - if the surface is not already allocated OR
//!           - resource dimenisions OR format changed
//! \param    [in] pOsInterface
//!           Pointer to MOS_INTERFACE
//! \param    [in,out] pSurface
//!           Pointer to VPHAL_SURFACE
//! \param    [in] pSurfaceName
//!           Pointer to surface name
//! \param    [in] Format
//!           Expected MOS_FORMAT
//! \param    [in] DefaultResType
//!           Expected Resource Type
//! \param    [in] DefaultTileType
//!           Expected Surface Tile Type
//! \param    [in] dwWidth
//!           Expected Surface Width
//! \param    [in] dwHeight
//!           Expected Surface Height
//! \param    [in] bCompressible
//!           Surface being compressible or not
//! \param    [in] CompressionMode
//!           Compression Mode
//! \param    [out] pbAllocated
//!           true if allocated, false for not
//! \param    [in] resUsageType
//!           resource usage type for caching
//! \param    [in] tileModeByForce
//!           Forced tile mode
//! \param    [in] memType
//!           vidoe memory location
//! \return   MOS_STATUS
//!           MOS_STATUS_SUCCESS if success. Error code otherwise
//!
MOS_STATUS VpHal_ReAllocateSurface(
    PMOS_INTERFACE          pOsInterface,                                       // [in]    Pointer to OS Interface
    PVPHAL_SURFACE          pSurface,                                           // [in/out]Pointer to surface
    PCCHAR                  pSurfaceName,                                       // [in]    Pointer to surface name
    MOS_FORMAT              Format,                                             // [in]    Surface Format
    MOS_GFXRES_TYPE         DefaultResType,                                     // [in]    Default Resource Type to use if resource has not be allocated yet
    MOS_TILE_TYPE           DefaultTileType,                                    // [in]    Default Resource Tile Type to use if resource has not be allocated yet
    uint32_t                dwWidth,                                            // [in]    Resource Width
    uint32_t                dwHeight,                                           // [in]    Resource Height
    bool                    bCompressible,                                      // [in]    Flag indaicated reource is compressible or not
    MOS_RESOURCE_MMC_MODE   CompressionMode,                                    // [in]    Compression mode
    bool*                   pbAllocated,                                        // [out]   Flag indicating new allocation
    MOS_HW_RESOURCE_DEF     resUsageType = MOS_HW_RESOURCE_DEF_MAX,             // [in]    resource usage type
    MOS_TILE_MODE_GMM       tileModeByForce = MOS_TILE_UNSET_GMM,               // [in]    Flag to indicate if GMM flag tile64 need set
    Mos_MemPool             memType = MOS_MEMPOOL_VIDEOMEMORY,                  // [in]    Flag to indicate the memType
    bool                    isNotLockable = false);                             // [in]    Flag to indicate whether resource being not lockable

//!
//! \brief    Reads the Surface contents and copy to the Dst Buffer
//! \details  Reads the Surface contents and copy to the Dst Buffer
//!           - 1 lock surface
//!           - 2 copy surface data to pDst
//!           - 3 unlock surface
//! \param    [in] pOsInterface
//!           Pointer to MOS_INTERFACE
//! \param    [in] pSurface
//!           Pointer to VPHAL_SURFACE
//! \param    [in] uBpp
//!           bit per pixel of surface contents
//! \param    [out] pDst
//!           output buffer to store Surface contents
//! \return   MOS_STATUS
//!           MOS_STATUS_SUCCESS if success. Error code otherwise
//!
MOS_STATUS VpHal_ReadSurface (
    PMOS_INTERFACE              pOsInterface,
    PVPHAL_SURFACE              pSurface,
    uint32_t                    uBpp,
    uint8_t*                    pDst);

//!
//! \brief    Copy Data from input Buffer to the Surface contents
//! \details  Copy Data from input Buffer to the Surface contents
//!           - 1 lock surface
//!           - 2 copy data from pSrc to Surface
//!           - 3 unlock surface
//! \param    [in] pOsInterface
//!           Pointer to MOS_INTERFACE
//! \param    [out] pSurface
//!           Pointer to VPHAL_SURFACE
//! \param    [in] uBpp
//!           bit per pixel of input buffer
//! \param    [in] pSrc
//!           Input buffer to store Surface contents
//! \return   MOS_STATUS
//!           MOS_STATUS_SUCCESS if success. Error code otherwise
//!
MOS_STATUS VpHal_WriteSurface (
    PMOS_INTERFACE              pOsInterface,
    PVPHAL_SURFACE              pSurface,
    uint32_t                    uBpp,
    const uint8_t*              pSrc);

//!
//! \brief    Get the color pack type of a surface
//! \details  Map mos surface format to color pack format and return.
//!           For unknown format return VPHAL_COLORPACK_UNKNOWN
//! \param    [in] Format
//!           MOS_FORMAT of a surface
//! \return   VPHAL_COLORPACK
//!           Color pack type of the surface
//!
VPHAL_COLORPACK VpHal_GetSurfaceColorPack (
    MOS_FORMAT                  Format);

//!
//! \brief    Decide whether Chroma up sampling is needed
//! \param    [in] pSource
//!           Pointer to Source Surface
//! \param    [in] pTarget
//!           Pointer to Target Surface
//! \return   bool
//!           Return true if Chroma up sampling is needed, otherwise false
//!
bool VpHal_IsChromaUpSamplingNeeded(
    PVPHAL_SURFACE          pSource,
    PVPHAL_SURFACE          pTarget);

//!
//! \brief    Decide whether Chroma down sampling is needed
//! \param    [in] pSource
//!           Pointer to Source Surface
//! \param    [in] pTarget
//!           Pointer to Target Surface
//! \return   bool
//!           Return true if Chroma down sampling is needed, otherwise false
//!
bool VpHal_IsChromaDownSamplingNeeded(
    PVPHAL_SURFACE          pSource,
    PVPHAL_SURFACE          pTarget);

//! \brief    Get the bit depth of a surface
//! \details  Get bit depth of input mos surface format and return.
//!           For unknown format return 0
//! \param    [in] Format
//!           MOS_FORMAT of a surface
//! \return   uint32_t
//!           Bit depth of the surface
//!
uint32_t VpHal_GetSurfaceBitDepth(
    MOS_FORMAT      Format);

//!
//! \brief      Get the scale ratio
//! \details    Get the scale ratio from input surface to output surface
//! \param      [in] pSource
//!             Pointer to input Surface
//! \param      [in] pTarget
//!             Pointer to output Surface
//! \param      [out] pfScaleX
//!             Pointer to scaling ratio x
//! \param      [out] pfScaleY
//!             Pointer to scaling ratio y
//! \return     void
//!
void VpHal_GetScalingRatio(
    PVPHAL_SURFACE              pSource,
    PVPHAL_SURFACE              pTarget,
    float*                      pfScaleX,
    float*                      pfScaleY);

//! \brief    Transfer float type to half precision float type
//! \details  Transfer float type to half precision float (16bit) type
//! \param    [in] fInput
//!           input FP32 number
//! \return   uint16_t
//!           half precision float value in bit
//!
uint16_t VpHal_FloatToHalfFloat(
    float     fInput);

//!
//! \brief    Initial the Type/TileType fields in Alloc Params structure
//! \details  Initial the Type/TileType fields in Alloc Params structure
//!           - Use the last type from GMM resource
//! \param    [in, out] pAllocParams
//!           Pointer to MOS_ALLOC_GFXRES_PARAMS
//! \param    [in] pSurface
//!           Pointer to VPHAL_SURFACE
//! \param    [in] DefaultResType
//!           Expected Resource Type
//! \param    [in] DefaultTileType
//!           Expected Surface Tile Type
//!
void VpHal_AllocParamsInitType(
    PMOS_ALLOC_GFXRES_PARAMS    pAllocParams,
    PVPHAL_SURFACE              pSurface,
    MOS_GFXRES_TYPE             DefaultResType,
    MOS_TILE_TYPE               DefaultTileType);

MOS_SURFACE VpHal_ConvertVphalSurfaceToMosSurface(
    PVPHAL_SURFACE pSurface);

bool IsSyncFreeNeededForMMCSurface(PVPHAL_SURFACE pSurface, PMOS_INTERFACE pOsInterface);

//!
//! \brief  VEBOX IECP parameters
//!
class VPHAL_VEBOX_IECP_PARAMS
{
public:
    PVPHAL_COLORPIPE_PARAMS         pColorPipeParams;
    PVPHAL_PROCAMP_PARAMS           pProcAmpParams;
    MOS_FORMAT                      dstFormat;
    MOS_FORMAT                      srcFormat;

    // CSC params
    bool                            bCSCEnable;                                 // Enable CSC transform
    float*                          pfCscCoeff;                                 // [3x3] CSC Coeff matrix
    float*                          pfCscInOffset;                              // [3x1] CSC Input Offset matrix
    float*                          pfCscOutOffset;                             // [3x1] CSC Output Offset matrix
    bool                            bAlphaEnable;                               // Alpha Enable Param
    uint16_t                        wAlphaValue;                                // Color Pipe Alpha Value

    // Front End CSC params
    bool                            bFeCSCEnable;                               // Enable Front End CSC transform
    float*                          pfFeCscCoeff;                               // [3x3] Front End CSC Coeff matrix
    float*                          pfFeCscInOffset;                            // [3x1] Front End CSC Input Offset matrix
    float*                          pfFeCscOutOffset;                           // [3x1] Front End CSC Output Offset matrix

    VPHAL_VEBOX_IECP_PARAMS()
    {
        pColorPipeParams    = nullptr;
        pProcAmpParams      = nullptr;
        dstFormat           = Format_Any;
        srcFormat           = Format_Any;
        bCSCEnable          = false;
        pfCscCoeff          = nullptr;
        pfCscInOffset       = nullptr;
        pfCscOutOffset      = nullptr;
        bAlphaEnable        = false;
        wAlphaValue         = 0;

        bFeCSCEnable        = false;
        pfFeCscCoeff        = nullptr;
        pfFeCscInOffset     = nullptr;
        pfFeCscOutOffset    = nullptr;
    }
    virtual ~VPHAL_VEBOX_IECP_PARAMS()
    {
        pColorPipeParams    = nullptr;
        pProcAmpParams      = nullptr;
    }
    virtual void Init()
    {
        pColorPipeParams    = nullptr;
        pProcAmpParams      = nullptr;

        dstFormat           = Format_Any;
        srcFormat           = Format_Any;

        bCSCEnable          = false;
        pfCscCoeff          = nullptr;
        pfCscInOffset       = nullptr;
        pfCscOutOffset      = nullptr;
        bAlphaEnable        = false;
        wAlphaValue         = 0;
    }
    virtual void   *GetExtParams() { return nullptr; }
};
#ifdef __cplusplus
}
#endif

#endif  // __VPHAL_COMMON_H__
