// NOWHINE ENTIRE FILE
//-------------------------------------------------------------------------
// Copyright (c) 2021 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//------------------------------------------------------------------------

#ifndef __PROCESS_EVA_H__
#define __PROCESS_EVA_H__

#include "ICA_Chromatix.h"
#include "GeoLib.h"
#include "DSX_Chromatix.h"
#include "DS4to1_Chromatix.h"
#include "Depth_Chromatix_v10.h"
#include "DMM_Chromatix_v10.h"
#include "DME_Chromatix_v30.h"

// This file does not include EVA headers so CamX modules that cannot include EVA API still can include this file.
// Structs defined in EVA API are forward declared here.
typedef struct _evaGceSessionConfig evaGceSessionConfig;
typedef struct _evaGceSessionConfigData evaGceSessionConfigData;
typedef struct _evaGceIcaRegDataSession evaGceIcaRegDataSession;
typedef struct _evaGceIcaSession evaGceIcaSession;
typedef struct _evaGceCrcSession evaGceCrcSession;

typedef struct _evaGceFrameConfig evaGceFrameConfig;
typedef struct _evaGceFrameConfigData evaGceFrameConfigData;
typedef struct _evaGceIcaFrame evaGceIcaFrame;
typedef struct _evaGceIcaRegGridPerspDataFrame evaGceIcaRegGridPerspDataFrame;
typedef struct _evaGceDsxYFrame evaGceDsxYFrame;
typedef struct _evaGceDsxCFrame evaGceDsxCFrame;
typedef struct _evaGceDsxYRegDataFrame evaGceDsxYRegDataFrame;
typedef struct _evaGceDsxCRegDataFrame evaGceDsxCRegDataFrame;
typedef struct _evaGceDs4YFrame evaGceDs4YFrame;
typedef struct _evaGceDs4CFrame evaGceDs4CFrame;
typedef struct _evaGceCrcFrame  evaGceCrcFrame;

typedef struct _evaDmmSgmAlignControlInfo evaDmmSgmAlignControlInfo;
typedef struct _evaDmeFrameConfigBuffer evaDmeFrameConfigBuffer;


#define NCLIB_PROCESS_GCE_PROC_BUFFER_SIZE (ICA_V30_GRID_TRANSFORM_HI_RES_SIZE * 8)
#define NCLIB_PACK_EVA_MATRICES_BUFFER_SIZE (NcLibIcaMaxMatricesNum * NcLibIcaMaxMatrixSize * 8)

/////////////////////////////
// GCE
/////////////////////////////


/**< Ways to configure ECU gain */
enum NcLibEcuGainSrc
{
    NCLIB_ECU_GAIN_NONE,                    /**< ECU disabled */
    NCLIB_ECU_GAIN_EXTENAL,                 /**< Assume gain configuration is configured outside NcLib */
    NCLIB_ECU_GAIN_CHROMATIX,               /**< Override gain configuration with Chromatix tuning */
    NCLIB_ECU_GAIN_COMBINE,                 /**< Combine gain calculated outside NcLib with Chromatix tuning */
    NCLIB_ECU_GAIN_SRCS_NUM                 /**< Internal for SW purposes */
};

/**< Type of content that passes through GCE */
enum NcLibGceContentType
{
    NCLIB_GCE_NO_CONTENT,                    /**< Internal for SW purposes */
    NCLIB_GCE_IMAGE,                         /**< The content is an image */
    NCLIB_GCE_MV,                            /**< The content is a motion vectors grid */
    NCLIB_GCE_CONTENT_TYPES_NUM              /**< Internal for SW purposes */
};

/**< GCE configuration filled by NcLibEvaCalc functions */

struct NcLibGceCfgTop
{
    uint32_t               alignmentType;    /**< Flow type for reference */
    uint32_t               alignmentStage;   /**< Flow stage num for reference */
    uint64_t               requestID;        /**< Request ID for reference */
    NcLibGceContentType    contentType;      /**< Whether GCE works on an image or on motion vectors */
};

struct NcLibOpgMvCompParams
{
    uint8_t                mode;             /** Enable MV compensation mode */
    uint8_t                lumaAxis;         /** Set Y pixel value to X or Y component when MV compensation is applied in Y only mode */
    int8_t                 fracBitsIn;       /** Number of fractional bits in OPG input pixel value */
    int8_t                 fracBitsOut;      /** Number of fractional bits in OPG output pixel value */
};

struct NcLibGceIcaLmcParams
{
    NcLibIcaLmcPassParams  lmc;
    uint32_t               icaOutWidth;      /**< ICA output width. */
};

struct NcLibGceSessionCfgIca
{
    bool                   en;               /**< Whether ICA is enabled */
    bool                   warpEn;           /**< Whether ICA warp is enabled */
    NcLibGceIcaLmcParams   lmc;              /**< LMC configuration for GCE ICA */
    NcLibOpgMvCompParams   opgMvc;           /**< OPG MV correction for GCE ICA */
};

struct NcLibGceFrameCfgIca
{
    GeoLib2IcaMapping      mapping;          /**< ICA mapping */
    NcLibFloat2            opgMvcOffset;     /** < Offset applied to MV compensation calculation */
};

struct NcLibGceCfgDsx
{
    bool                   yEn;              /**< Whether DSX luma channel is enabled */
    bool                   cEn;              /**< Whether DSX chroma channel is enabled */
    NCLIB_CONTEXT_DSX      cropAndScale;     /**< DSX configuration */
};

struct NcLibGceCfgDs4
{
    bool                   yEn;              /**< Whether DS4 luma channel is enabled */
    bool                   cEn;              /**< Whether DS4 chroma channel is enabled */
    NcLibImageSize         crop;             /**< DS4 cropped size at input */
};

struct NcLibGceSessionCfgCrc
{
    uint8_t                inBpp;            /**< CRC input BPP */
    uint8_t                outBpp;           /**< CRC output BPP */
};

struct NcLibGceFrameCfgCrc
{
    NcLibImageSize         offset;           /**< Crop offset */
    NcLibImageSize         size;             /**< Crop size */
};

struct NcLibGceSessionCfg
{
    NcLibGceCfgTop         top;
    NcLibGceSessionCfgIca  ica;
    NcLibGceSessionCfgCrc  postDsx;
    NcLibGceSessionCfgCrc  postDs4;
    bool                   smallStripes;
    NcLibEcuGainSrc        ecuGainSrc;       /**< ECU gain configuration type */
};

struct NcLibGceFrameCfg
{
    NcLibGceCfgTop         top;
    NcLibGceFrameCfgIca    ica;
    NcLibGceCfgDsx         dsx;
    NcLibGceCfgDs4         ds4;
    NcLibGceFrameCfgCrc    postDsx;
    NcLibGceFrameCfgCrc    postDs4;
};

/**
*  @brief   Get size of evaGceFrameConfig struct for "blind" memory allocation
*
*  @return evaGceFrameConfig size
*/
size_t NcLibGetSize_evaGceFrameConfig();

/**
*  @brief   Get size of evaGceFrameConfigData struct for "blind" memory allocation
*
*  @return evaGceFrameConfigData size
*/
size_t NcLibGetSize_evaGceFrameConfigData();

/**
*  @brief   Get size of evaGceSessionConfig struct for "blind" memory allocation
*
*  @return evaGceFrameConfig size
*/
size_t NcLibGetSize_evaGceSessionConfig();

/**
*  @brief   Get size of evaGceSessionConfigData struct for "blind" memory allocation
*
*  @return evaGceFrameConfigData size
*/
size_t NcLibGetSize_evaGceSessionConfigData();

/**
*  @brief   Get size of evaDmeFrameConfigBuffer struct for "blind" memory allocation
*
*  @return evaDmeFrameConfigBuffer size
*/
size_t NcLibGetSize_evaDmeFrameConfigBuffer();

/**
*  @brief   Get size of evaDmmSgmAlignControlInfo struct for "blind" memory allocation
*
*  @return evaDmmSgmAlignControlInfo size
*/
size_t NcLibGetSize_evaDmmSgmAlignControlInfo();

/**
*  @brief   Calculate GCE session configuration. Calls NcLibProcessGce*Session functions in a row.
*
*  @param [in]      gridEnabled        Whether grid is applied in this GCE.
*  @param [in]      gridGeometry       If gridEnabled, indicates the grid size, which cannot change during session.
*  @param [in]      perspCols          Perspective transform matrices columns number.
*  @param [in]      perspRows          Perspective transform matrices rows number.
*  @param [in]      icaChx             GCE ICA Chromatix. If it's NULL OPG LUTs will not be populated in the output struct.
*  @param [in]      depthChx           Depth Chromatix. Relevant only for depth map processing. Must be NULL for other cases.
*  @param [in]      gceCfg             GCE configuration
*  @param [out]     out                Config output struct filled by the function.
*  @param [out]     outData            Data output struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceSession(
    const bool gridEnabled,
    const NcLibIcaGridGeometry gridGeometry,
    const uint32_t perspCols,
    const uint32_t perspRows,
    const ICA_Chromatix* icaChx,
    const Depth_Chromatix_v10* depthChx,
    const NcLibGceSessionCfg* gceCfg,
    evaGceSessionConfig* out,
    evaGceSessionConfigData* outData);

/**
*  @brief   Calculate GCE frame configuration. Calls NcLibProcessGce*Frame functions in a row.
*
*  @param [in]      grid               Transform grid. Must match the grid parameters passed to NcLibProcessGceSession.
*  @param [in]      persp              Perspective transform matrices. Must match the transform passed to NcLibProcessGceSession.
*  @param [in]      dsxChx             GCE DSX Chromatix.
*  @param [in]      ds4Chx             GCE DS4 Chromatix.
*  @param [in]      icaChx             GCE ICA Chromatix.
*  @param [in]      gceSession         GCE Session configuration
*  @param [in]      gceCfg             GCE Frame configuration
*  @param [in,out]  procBuffer         Pointer to intermediate buffer of at least NCLIB_PROCESS_GCE_PROC_BUFFER_SIZE
*                                      bytes. The function will use this buffer for intermediate calculations.
*  @param [out]     out                Config output struct filled by the function.
*  @param [out]     outData            Data output struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceFrame(
    const NcLibIcaGrid* grid,
    const NcLibIcaMatrices* persp,
    const DSX_Chromatix* dsxChx,
    const DS4to1_Chromatix* ds4Chx,
    const ICA_Chromatix* icaChx,
    const NcLibGceSessionCfg* gceSession,
    const NcLibGceFrameCfg* gceCfg,
    void* procBuffer,
    evaGceFrameConfig* out,
    evaGceFrameConfigData* outData);

/**
*  @brief   Calculate GCE ICA session configuration. Use if NcLibProcessGceSession does not fit your SW design.
*
*  @param [in]      gridEnabled        Whether grid is applied in this GCE.
*  @param [in]      gridGeometry       If gridEnabled, indicates the grid size, which cannot change during session.
*  @param [in]      perspCols          Perspective transform matrices columns number.
*  @param [in]      perspRows          Perspective transform matrices rows number.
*  @param [in]      icaChx             GCE ICA Chromatix. If it's NULL OPG LUTs will not be populated in the output struct.
*  @param [in]      depthChx           Depth Chromatix. Relevant only for depth map processing. Must be NULL for other cases.
*  @param [in]      gceTop             GCE configuration Top section
*  @param [in]      gceIca             GCE configuration ICA section
*  @param [out]     ica                Output struct filled by the function.
*  @param [out]     icaData            Output data struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceIcaSession(
    const bool gridEnabled,
    const NcLibIcaGridGeometry gridGeometry,
    const uint32_t perspCols,
    const uint32_t perspRows,
    const ICA_Chromatix* icaChx,
    const Depth_Chromatix_v10* depthChx,
    const NcLibGceCfgTop* gceTop,
    const NcLibGceSessionCfgIca* gceIca,
    evaGceIcaSession* ica,
    evaGceIcaRegDataSession* icaData);

/**
*  @brief   Calculate GCE ICA frame configuration. Use if NcLibProcessGceFrame does not fit your SW design.
*
*  @param [in]      grid               Transform grid. Must match the grid parameters passed to NcLibProcessGceSession.
*  @param [in]      persp              Perspective transform matrices. Must match the transform passed to NcLibProcessGceSession.
*  @param [in]      icaChx             GCE ICA Chromatix. If it's NULL OPG LUTs will not be populated in the output struct.
*  @param [in]      gceIcaSession      GCE session configuration ICA section
*  @param [in]      gceIca             GCE configuration ICA section
*  @param [in,out]  procBuffer         Pointer to intermediate buffer of at least NCLIB_PROCESS_GCE_PROC_BUFFER_SIZE
*                                      bytes. The function will use this buffer for intermediate calculations.
*  @param [out]     ica                Output struct filled by the function.
*  @param [out]     icaData            Output data struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceIcaFrame(
    const NcLibIcaGrid* grid,
    const NcLibIcaMatrices* persp,
    const ICA_Chromatix* icaChx,
    const NcLibGceSessionCfgIca* gceIcaSession,
    const NcLibGceFrameCfgIca* gceIca,
    void* procBuffer,
    evaGceIcaFrame* ica,
    evaGceIcaRegGridPerspDataFrame* icaData);

/**
*  @brief   Calculate GCE DSX configuration. Use if NcLibProcessGce does not fit your SW design.
*
*  @param [in]      dsxChx             GCE DSX Chromatix.
*  @param [in]      gceDsx             GCE configuration DSX section
*  @param [in,out]  procBuffer         Pointer to intermediate buffer of at least NCLIB_PROCESS_GCE_DSX_PROC_BUFFER_SIZE
*                                      bytes. The function will use this buffer for intermediate calculations.
*  @param [out]     dsxY               Config output luma struct filled by the function.
*  @param [out]     dsxC               Config output chroma struct filled by the function.
*  @param [out]     dsxYData           Data output luma struct filled by the function.
*  @param [out]     dsxCData           Data output chroma struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceDsx(
    const DSX_Chromatix* dsxChx,
    const NcLibGceCfgDsx* gceDsx,
    void* procBuffer,
    evaGceDsxYFrame* dsxY,
    evaGceDsxCFrame* dsxC,
    evaGceDsxYRegDataFrame* dsxYData,
    evaGceDsxCRegDataFrame* dsxCData);

/**
*  @brief   Calculate GCE DS4 configuration. Use if NcLibProcessGce does not fit your SW design.
*
*  @param [in]      gceDs4             GCE configuration DS4 section
*  @param [in]      ds4Chx             GCE DS4 Chromatix.
*  @param [out]     ds4Y               Output luma struct filled by the function.
*  @param [out]     ds4C               Output chroma struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceDs4(
    const NcLibGceCfgDs4* gceDs4,
    const DS4to1_Chromatix* ds4Chx,
    evaGceDs4YFrame* ds4Y,
    evaGceDs4CFrame* ds4C);

/**
*  @brief   Calculate GCE post-DSX or post-DS4 CRC session configuration. Use if NcLibProcessGceSession does not fit your SW design.
*
*  @param [in]      gceTop             GCE configuration Top section
*  @param [in]      gceCrc             GCE configuration post-DSX or post-DS4 section
*  @param [out]     outY               Output luma struct filled by the function.
*  @param [out]     outC               Output chroma struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceCrcSession(
    const NcLibGceCfgTop* gceTop,
    const NcLibGceSessionCfgCrc* gceCrc,
    evaGceCrcSession* outY,
    evaGceCrcSession* outC);

/**
*  @brief   Calculate GCE post-DSX or post-DS4 CRC frame configuration. Use if NcLibProcessGceFrame does not fit your SW design.
*
*  @param [in]      gceTop             GCE configuration Top section
*  @param [in]      gceCrcSession      GCE session configuration post-DSX or post-DS4 section
*  @param [in]      gceCrc             GCE configuration post-DSX or post-DS4 section
*  @param [out]     outY               Output luma struct filled by the function.
*  @param [out]     outC               Output chroma struct filled by the function.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceCrcFrame(
    const NcLibGceCfgTop* gceTop,
    const NcLibGceSessionCfgCrc* gceCrcSession,
    const NcLibGceFrameCfgCrc* gceCrc,
    evaGceCrcFrame* outY,
    evaGceCrcFrame* outC);

/**
*  @brief   Fill GCE session redundant Top fields, assuming them from module-specific fields in the same struct.
*           Use if NcLibProcessGceSession does not fit your SW design.
*
*  @param [in]      smallStripes       If true ICA will run on narrow stripes
*  @param [in,out]  config             Config output struct. Assumed to be fully populated except for sGceTopConfig field.
*                                      out->sGceTopConfig is the function output. All other fields are the function input.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibProcessGceTop(bool smallStripes, evaGceSessionConfig* config);


/////////////////////////////
// DMM and Alignment Control
/////////////////////////////

enum NcLibDmmAlignmentType
{
    NCLIB_DMM_SAT,
    NCLIB_DMM_MCTF,
    NCLIB_DMM_MFHDR,
    NCLIB_DMM_MMF,
    NCLIB_DMM_ALIGNMENT_TYPES_NUM
};

// NOTE: the first part must be identical to evaDmmGceStages
enum NCLIB_DMM_GCE_STAGE
{
    NCLIB_DMM_GCE_WarpErsLd0 = 0,
    NCLIB_DMM_GCE_WarpErsLd1,
    NCLIB_DMM_GCE_WarpErsLd0_DS,
    NCLIB_DMM_GCE_WarpGlobalAlign,
    NCLIB_DMM_GCE_WarpErsLd2,
    NCLIB_DMM_GCE_BYPASS,
    NCLIB_DMM_GCE_MvWarpDisplay,
    NCLIB_DMM_GCE_MvWarpDisplay_DS,

    NCLIB_DMM_GCE_MvWarpVideo,
    NCLIB_DMM_GCE_MvWarpVideo_DS,

    NCLIB_DMM_GCE_MvWarpDisplay_US,
    NCLIB_DMM_GCE_MvWarpDisplay_US_DS,
    NCLIB_DMM_GCE_MvWarpVideo_US,
    NCLIB_DMM_GCE_MvWarpVideo_US_DS,

    NCLIB_DMM_GCE_STAGES_NUM,
    NCLIB_DMM_GCE_DISPLAY_STAGES_NUM   = NCLIB_DMM_GCE_MvWarpVideo,
    NCLIB_DMM_GCE_VIDEO_FIRST_STAGE    = NCLIB_DMM_GCE_MvWarpVideo,
    NCLIB_DMM_GCE_VIDEO_STAGES_NUM     = 2,
    NCLIB_DMM_GCE_US_FIRST_STAGE       = NCLIB_DMM_GCE_MvWarpDisplay_US,
    NCLIB_DMM_GCE_VIDEO_US_FIRST_STAGE = NCLIB_DMM_GCE_MvWarpVideo_US,
    NCLIB_DMM_GCE_US_STAGES_NUM        = 2
};

// NOTE: the first part must be identical to evaDmmSgmStages
enum NCLIB_DMM_SGM_PASS
{
    NCLIB_DMM_SGM_CONFIDENCE = 0,
    NCLIB_DMM_SGM_FULL,
    NCLIB_DMM_SGM_CAND,
    NCLIB_DMM_SGM_PASSES_NUM
};

struct NCLIB_CONTEXT_ALIGN
{
    float absoluteMotion;                   /**< Optional motion indication in pixels, e.g. AMD result */
    uint32_t absoluteMotionConfidence;      /**< Confidence of motion indication, 0 if none is present */
    NcLibDmmAlignmentType alignmentType;    /**< Which alignment this DMM is calculating */
    NcLibFloat2 ipeTransformDefinedOn;      /**< Dimensions of the IPE transform in pixels */
    NcLibFloat2 sgmTransformDefinedOn;      /**< Dimensions of the SGM transform in pixels */
    NcLibFloat2 dmeTransformDefinedOn;      /**< Dimensions of the image alignment transform in pixels.
                                            *    Can take from NcLibEvaCalcDmmFrame output:
                                            *    gceOut[NCLIB_DMM_GCE_WarpErsLd1].ica.mapping.outputImageRoi.size */
};

/**
*  @brief   Calculate DMM SGM alignment control configurations
*
*  @param [in]      context            Pointer to the context struct
*  @param [in]      gyroAlign          Pointer to the gyro alignment matrix struct (single matrix only)
*  @param [in]      isGyroAlignTopLeft True if gyroAlign matrix is relative to top left corner, False if it's centered
*  @param [in]      chx                Pointer to the DMM Chromatix struct
*  @param [out]     out                Output struct filled by the function.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibProcessDmmAlignControl(
    const NCLIB_CONTEXT_ALIGN* context,
    const NcLibIcaMatrices* gyroAlign,
    bool isGyroAlignTopLeft,
    const DMM_Chromatix_v10* chx,
    evaDmmSgmAlignControlInfo* out);

/////////////////////////////
// DME
/////////////////////////////

struct NCLIB_CONTEXT_DME
{
    bool isFirstFrame;
    NcLibImageSize satRoiOffset;
    NcLibImageSize satRoiSize;
    uint64_t       frameId;
};

/**
*  @brief   Configure DME 3.0 frame
*
*  @param [in]      context         Pointer to the context struct
*  @param [in]      chx             Chromatix configuration
*  @param [out]     out             Output EVA DME frame settings
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibProcessEvaDme30(
    const NCLIB_CONTEXT_DME* context,
    const DME_Chromatix_v30* chx,
    evaDmeFrameConfigBuffer* out);


/////////////////////////////
// Stand-alone GCE
/////////////////////////////

/**
*  @brief   Pack ICA grid struct to EVA FW/HW buffer format.
*
*  @param [in]      icaGrid            Pointer to the grid struct
*  @param [out]     procBuffer         Pointer to intermediate buffer of at least NCLIB_PROCESS_GCE_PROC_BUFFER_SIZE
*                                      bytes. The function will use this buffer for intermediate calculations.
*  @param [out]     grid_data_packer   Buffer for output packed grid. Must be at least 27392 bytes long.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibEvaPackGrid(const NcLibIcaGrid* icaGrid, void* procBuffer, void* grid_data_packer);

/**
*  @brief   Pack ICA matrices struct to EVA FW/HW buffer format.
*
*  @param [in]      icaPersp                Pointer to the matrices struct
*  @param [out]     procBuffer              Pointer to intermediate buffer of at least NCLIB_PACK_EVA_MATRICES_BUFFER_SIZE
*                                           bytes. The function will use this buffer for intermediate calculations.
*  @param [out]     perspective_data_packer Buffer for output packed matrices. Must have at least 32 bytes for each matrix, up to
*                                           288 bytes for 9 matrices.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
void NcLibEvaPackMatrices(const NcLibIcaMatrices* icaPersp, void* procBuffer, void* perspective_data_packer);

#endif // __PROCESS_EVA_H__
