// NOWHINE ENTIRE FILE
//-------------------------------------------------------------------------
// Copyright (c) 2020-2022 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//------------------------------------------------------------------------
#ifndef NCLIBEVA_H
#define NCLIBEVA_H


#include <stdint.h>
#include "GeoLib.h"       // for IcaMapping
#include "Process_EVA.h"
#include "Process_SGM.h"
#include "NcLibVbseUtils.h" // For rotation enum


/////////////////////////////
// DMM
/////////////////////////////

struct NcLibEvaCalcDmmSizesIn
{
    NcLibFloat2            inRoiSize;                  /**< Max EVA input ROI size. Normally image size can be passed instead. */
    NcLibFloat2            dispInRoiSize;              /**< Max display ROI on EVA input. Required only if there is video path.
                                                       *    Otherwise set this to 0 and pass the ROI in inRoiSize. */
    NcLibImageSize         icaOutSize;                 /**< Full out size of the ICA that will apply this DMM transform, at DZ=1.
                                                       *    LMC calculated by this DMM will match this size. */
    NcLibFloat2            icaOutRoi;                  /**< Full out ROI of the ICA that will apply this DMM transform, at DZ=1.
                                                       *    LMC calculated by this DMM will match this ROI. */
    NcLibFloat2            videoIcaOutRoi;             /**< Full out ROI of the Video path ICA that will apply this DMM
                                                       *    transform, at DZ=1. LMC calculated by this DMM with MV Video Warp
                                                       *    pass will match this ROI. Set to (0,0) if there is no video pass. */
    NcLibDmmAlignmentType  alignmentType;              /**< Which alignment this DMM is calculating */
    float                  minDmeTunedScaling;         /**< Minimum expected value of NcLibEvaCalcDmmFrameIn::dmeTunedScaling. */
    uint32_t               minDmeTunedSize;            /**< Minimum expected value of NcLibEvaCalcDmmFrameIn::dmeTunedSize. */
    float                  maxSgmToIpeRatio;           /**< Maximal expected SGM size to IPE ICA input size ratio,
                                                       *    0 for DME-only. Normally 1/4 or 1/8. If unknown pass 0.25. */
    bool                   haveMvUsPass;               /**< Whether an MV upscaling GCE pass is added after MV warp */
    bool                   haveVideoMvUsPass;          /**< Whether an MV upscaling GCE pass is added after MV Video warp. Set
                                                       *    to false if there is no video pass.  */
};

struct NcLibEvaCalcDmmSessionIn
{
    NcLibImageSize         icaOutSize;                 /**< Full out size of the ICA that will apply this DMM transform, at DZ=1.
                                                       *    LMC calculated by this DMM will match this size. */
    NcLibDmmAlignmentType  alignmentType;              /**< Which alignment this DMM is calculating */
    bool                   haveMvUsPass;               /**< Whether an MV upscaling GCE pass is added after MV warp */
    bool                   haveVideoMvUsPass;          /**< Whether an MV upscaling GCE pass is added after MV Video warp. Set
                                                       *    to false if there is no video pass.  */
    float                  sgmDs;                      /**< SGM downscale ratio, as returned by NcLibEvaCalcDmmSizes */
};

struct NcLibEvaCalcDmmFrameIn
{
    NcLibROI               inRoi;                      /**< ROI mapped to ICA virtual domain relative to EVA input */
    NcLibROI               dispInRoi;                  /**< ROI mapped to Display ICA virtual domain relative to EVA input.
                                                       *    Required only if there is video path. Otherwise set this to 0 and
                                                       *    pass the ROI in inRoi. */
    NcLibROI               warpOutRoiFull;             /**< Full out FOV of the ICA that will apply this DMM transform,
                                                       *    excluding ICA DZ crop. LMC calculated by this DMM will match this
                                                       *    ROI */
    NcLibFloat2            videoWarpOutRoiFull;        /**< Full out FOV size of the Video path ICA that will apply this DMM
                                                       *    transform, excluding ICA DZ crop. LMC calculated by this DMM with MV
                                                       *    Video Warp will match this ROI. Set to (0,0) if there is no video
                                                       *    pass. */
    NcLibDmmAlignmentType  alignmentType;              /**< Which alignment this DMM is calculating */
    float                  satScaleFactor;             /**< For SAT alignment, ratio between sensor FOVs, wider to narrower (> 1).
                                                       *    For other alignments must be 1. */
    float                  dmeTunedScaling;            /**< MMF only. From DME Chromatix: down_scale_ratio */
    uint32_t               dmeTunedSize;               /**< MMF only. From DME Chromatix: multi_frame_input_resolution */
    float                  sgmToIpeRatio;              /**< Requested SGM size to IPE ICA input size ratio, 0 for DME-only.
                                                       *    Normally 1/4 or 1/8. Should consider available SGM capacity and
                                                       *    DMM Chromatix: top.dense_image_based_alignment_enable */
    bool                   haveMvUsPass;               /**< Whether an MV upscaling GCE pass is added after MV warp */
    bool                   haveVideoMvUsPass;          /**< Whether an MV upscaling GCE pass is added after MV Video warp. Set
                                                       *    to false if there is no video pass.  */
    uint64_t               requestID;                  /**< Request ID for reference */
};

struct NcLibEvaCalcVideoDmmSessionIn
{
    NcLibImageSize         warpOutSizeFull;            /**< ICA full out size.
                                                       *    LMC calculated by this DMM will match this size */
    NcLibDmmAlignmentType  alignmentType;              /**< Which alignment this DMM is calculating */
    bool                   haveMvUsPass;               /**< Whether an MV upscaling GCE pass is added after MV Video warp. */
    NcLibImageSize         mvVideoIn;                  /**< MV Video Warp in size in samples, same as SGM cand out size. Can be
                                                       *    (0, 0) if there is no MV upscaling pass */
    float                  sgmDs;                      /**< SGM downscale ratio, as returned by NcLibEvaCalcDmmSizes */
};

struct NcLibEvaCalcVideoDmmFrameIn
{
    NcLibROI               warpOutRoiFull;             /**< ICA full out ROI in pixels.
                                                       *    LMC calculated by this DMM will match this ROI */
    NcLibDmmAlignmentType  alignmentType;              /**< Which alignment this DMM is calculating */
    bool                   haveMvUsPass;               /**< Whether an MV upscaling GCE pass is added after this MV warp */
    uint64_t               requestID;                  /**< Request ID for reference */
};

struct NcLibEvaCalcDmmUsSessionIn
{
    NcLibImageSize         warpOutSizeFull;            /**< ICA full out size.
                                                       *    LMC calculated by this DMM will match this size */
    NcLibDmmAlignmentType  alignmentType;              /**< Which alignment this DMM is calculating */
    bool                   isVideoPath;                /**< Whether this is primary DMM path or after MV Video warp. */
    float                  sgmDs;                      /**< SGM downscale ratio, as returned by NcLibEvaCalcDmmSizes. */
};

struct NcLibEvaCalcDmmUsFrameIn
{
    NcLibImageSize         warpOutSizeFull;            /**< ICA full out size.
                                                       *    LMC calculated by this DMM will match this size */
    NcLibDmmAlignmentType  alignmentType;              /**< Which alignment this DMM is calculating */
    bool                   isVideoPath;                /**< Whether this is primary DMM path or after MV Video warp. */
    uint64_t               requestID;                  /**< Request ID for reference. Set to 0 for EvaCalcDmmUsSession. */
};

struct NcLibEvaCalcMvData
{
    NcLibImageSize mvSize;
    NcLibFloat2    mvPureSize;
    float          sgmDs;
    float          mvScaleFactorVideo;
    NcLibFloat2    sgmMultVideo;
    NcLibFloat2    sgmMult;
    bool           useSgm;
    bool           performanceBreach;                  /**< Will be set if sgmToIpeRatio is too big and resulting
                                                       *    configuration produces bigger SGM input */
};

struct NcLibEvaMvWarpMaxSizes
{
    NcLibImageSize out0;                               /**< MvWarpDisplay first output max size in samples (num of MVs) */
    NcLibImageSize out1;                               /**< MvWarpDisplay second output max size in samples (num of MVs) */
    NcLibImageSize usOut0;                             /**< MV Upscaling pass first output max size in samples (num of MVs)*/
    NcLibImageSize usOut1;                             /**< MV Upscaling pass second output max size in samples (num of MVs) */
    NcLibImageSize dsOut0;                             /**< MvWarpDisplayDs first output max size in samples (num of MVs) */
    NcLibImageSize dsOut1;                             /**< MvWarpDisplayDs second output max size in samples (num of MVs) */
};

struct NcLibEvaDmmMaxSizes
{
    NcLibImageSize dmeGceOut;                          /**< WarpErsLd1 and WarpErsLd2 GCEs output max size in pixels */
    NcLibImageSize dmmGceOut;                          /**< WarpErsLd0 and WarpGlobalAlign max output size in pixels */
    NcLibImageSize sgmCandOut;                         /**< SGM Candidate pass output max size in samples */
    float          sgmDs;                              /**< SGM downscale ratio */
    NcLibEvaMvWarpMaxSizes mvWarp;                     /**< Max sizes for MV Warp and scaling stages */
};

/**
*  @brief   Calculate EVA DMM output sizes
*
*  @param [in]      in             Input struct
*  @param [out]     maxSizes       Output struct, will be populated with max EVA output sizes.
*                                  Should be NULL if max sizes calculation is not required.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibEvaCalcDmmSizes(const NcLibEvaCalcDmmSizesIn* in, NcLibEvaDmmMaxSizes* maxSizes);

/**
*  @brief   Calculate session-level geometries for EVA running DMM flow
*
*  @param [in]      in             Input struct
*  @param [out]     gceOut         Array of output structs of at least NCLIB_DMM_GCE_DISPLAY_STAGES_NUM elements.
*                                  Configurations for each GCE pass will be returned in this array.
*                                  Stages order in the array is defined by NCLIB_DMM_GCE_STAGE, which is same as evaDmmGceStages.
*                                  NcLibProcessGceSession should be called for each filled element in this array.
*  @param [in,out]  gceOutLength   On input: size of gceOut array. On output: number of filled GCE configurations.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibEvaCalcDmmSession(const NcLibEvaCalcDmmSessionIn* in,
    NcLibGceSessionCfg* gceOut, uint32_t* gceOutLength);

/**
*  @brief   Calculate frame-level geometries for EVA running DMM flow
*
*  @param [in]      in             Input struct
*  @param [in]      maxSizes       EVA output sizes as returned by NcLibEvaCalcDmmSizes
*  @param [out]     gceOut         Array of output structs of at least NCLIB_DMM_GCE_DISPLAY_STAGES_NUM elements.
*                                  Configurations for each GCE pass will be returned in this array.
*                                  Stages order in the array is defined by NCLIB_DMM_GCE_STAGE, which is same as evaDmmGceStages.
*                                  NcLibProcessGceFrame should be called for each filled element in this array.
*  @param [in,out]  gceOutLength   On input: size of gceOut array. On output: number of filled GCE configurations.
*  @param [out]     sgmOut         Array of output structs of at least NCLIB_DMM_SGM_PASSES_NUM elements.
*                                  Configurations for each SGM pass will be returned in this array.
*                                  Stages order in the array is defined by per NCLIB_DMM_SGM_PASS.
*                                  NcLibProcessSGM should be called for each filled element in this array.
*  @param [in,out]  sgmOutLength   On input: size of sgmOut array. On output: number of filled SGM configurations.
*  @param [out]     ipeLmcCfg      Array of LMC configurations per DC pass, for ICA that will apply this DMM transform.
*                                  If using MV upscaling GCE, use ipeLmcCfg returned by NcLibEvaCalcDmmUsFrame instead.
*  @param [out]     dmmFov         EVA full output DMM FOV after this MV warp, in samples (num of MVs). Can be NULL.
*  @param [out]     mvData         MV configuration, required for calculating video MV warp configuration.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibEvaCalcDmmFrame(const NcLibEvaCalcDmmFrameIn* in,
    const NcLibEvaDmmMaxSizes* maxSizes,
    NcLibGceFrameCfg* gceOut, uint32_t* gceOutLength,
    NCLIB_CONTEXT_SGM* sgmOut, uint32_t* sgmOutLength,
    NcLibIcaLmcPassParams ipeLmcCfg[PASS_TYPE_NUM],
    NcLibROI* dmmFov, NcLibEvaCalcMvData* mvData);

/**
*  @brief   Calculate session-level geometries for EVA running DMM upscaling sub-flow (adjusting results to VSR)
*
*  @param [in]      in             Input struct
*  @param [out]     maxSizes       Output struct, will be populated with max EVA output sizes.
*                                  Should be NULL if max sizes calculation is not required.
*  @param [out]     gceOut         Array of output structs of at least NCLIB_DMM_GCE_US_STAGES_NUM elements.
*                                  Configurations for each GCE pass will be returned in this array.
*                                  NcLibProcessGceSession should be called for each filled element in this array.
*  @param [in,out]  gceOutLength   On input: size of gceOut array. On output: number of filled GCE configurations.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibEvaCalcDmmUsSession(const NcLibEvaCalcDmmUsSessionIn* in,
    NcLibEvaMvWarpMaxSizes* maxSizes, NcLibGceSessionCfg* gceOut, uint32_t* gceOutLength);

/**
*  @brief   Calculate frame-level geometries for EVA running DMM video sub-flow (adjusting display results to video pass)
*
*  @param [in]      in             Input struct
*  @param [in]      vsrGce         ICA configuration calculated by GeoLib2EvaCalcFrame, in samples (num of MVs).
*  @param [in]      mvData         MV configuration, as received from NcLibEvaCalcDmmFrame.
*  @param [out]     gceOut         Array of output structs of at least NCLIB_DMM_GCE_US_STAGES_NUM elements.
*                                  Configurations for each GCE pass will be returned in this array.
*                                  NcLibProcessGceFrame should be called for each filled element in this array.
*  @param [in,out]  gceOutLength   On input: size of gceOut array. On output: number of filled GCE configurations.
*  @param [out]     ipeLmcCfg      Array of LMC configurations per DC pass, for ICA that will apply this DMM transform.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibEvaCalcDmmUsFrame(const NcLibEvaCalcDmmUsFrameIn* in, const GeoLib2IcaMapping* vsrGce, const NcLibEvaCalcMvData* mvData,
    NcLibGceFrameCfg* gceOut, uint32_t* gceOutLength, NcLibIcaLmcPassParams ipeLmcCfg[PASS_TYPE_NUM]);

/**
*  @brief   Calculate session-level geometries for EVA running DMM video sub-flow (adjusting display results to video pass)
*
*  @param [in]      in             Input struct
*  @param [out]     maxSizes       Output struct, will be populated with max EVA output sizes.
*                                  Should be NULL if max sizes calculation is not required.
*  @param [out]     gceOut         Array of output structs of at least NCLIB_DMM_GCE_VIDEO_STAGES_NUM elements.
*                                  Configurations for each GCE pass will be returned in this array.
*                                  NcLibProcessGceSession should be called for each filled element in this array.
*  @param [in,out]  gceOutLength   On input: size of gceOut array. On output: number of filled GCE configurations.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibEvaCalcVideoDmmSession(const NcLibEvaCalcVideoDmmSessionIn* in,
    NcLibEvaMvWarpMaxSizes* maxSizes, NcLibGceSessionCfg* gceOut, uint32_t* gceOutLength);

/**
*  @brief   Calculate frame-level geometries for EVA running DMM video sub-flow (adjusting display results to video pass)
*
*  @param [in]      in             Input struct
*  @param [in]      mvData         MV configuration, as received from NcLibEvaCalcDmmFrame.
*  @param [out]     gceOut         Array of output structs of at least NCLIB_DMM_GCE_VIDEO_STAGES_NUM elements.
*                                  Configurations for each GCE pass will be returned in this array.
*                                  NcLibProcessGceFrame should be called for each filled element in this array.
*  @param [in,out]  gceOutLength   On input: size of gceOut array. On output: number of filled GCE configurations.
*  @param [out]     ipeLmcCfg      Array of LMC configurations per DC pass, for ICA that will apply this DMM transform.
*                                  If using MV upscaling GCE, use ipeLmcCfg returned by NcLibEvaCalcDmmUsFrame instead.
*  @param [out]     dmmFov         EVA full output DMM FOV after this MV warp, in samples (num of MVs). Can be NULL.
*
*  @return NC_LIB_SUCCESS on success, appropriate error code on failure.
*/
int32_t NcLibEvaCalcVideoDmmFrame(const NcLibEvaCalcVideoDmmFrameIn* in,
    const NcLibEvaCalcMvData* mvData,
    NcLibGceFrameCfg* gceOut, uint32_t* gceOutLength,
    NcLibIcaLmcPassParams ipeLmcCfg[PASS_TYPE_NUM],
    NcLibROI* dmmFov);


/////////////////////////////
// DFS
/////////////////////////////

// Top constants
enum
{
    NCLIB_DFS_ALIGNMENT_TYPE = NCLIB_DMM_ALIGNMENT_TYPES_NUM,
    NCLIB_DFS_MAIN = 0,
    NCLIB_DFS_AUX = 1
};

constexpr uint32_t NCLIB_DPP_MAX_PPS = 640 * 360 * 60;         // pixels per second, due to performance


struct NcLibEvaCalcDfsInitIn
{
    NcLibImageSize mainFullSize;             /**< Size of the Full main image. */
    NcLbVbseRotation mainRotation;           /**< Rotation flag of main image, defined in sensor stereo params */
    NcLbVbseRotation auxRotation;            /**< Rotation flag of auxiliary image, defined in sensor stereo params */
    NcLibImageSize tunedDfsSize[3];          /**< Requested DFS size LUT (DPP Chromatix: common_params.dfs_width/height)*/
    NcLibFloat2 preCropRatio;                /**< Sensor and IFE crop ratio at DZ=1. E.g. for full sensor aspect ratio 4:3
                                             *    and IFE output 16:9, preCropRatio is expected to be around (1, 0.75). */
    NcLibFloat2 maxExtraScaling;             /**< Max allowed upscaling (DPP Chromatix: common_params.dfs_max_extra_scale_x/y) */
    uint32_t fps;                            /**< EVA activation frequency, up to 60 */
};

struct NcLibEvaCalcDfsFrameIn
{
    NcLibROI auxMaxRoi;                      /**< Max ROI (also main full image) on auxiliary EVA input */
    NcLbVbseRotation auxRotation;            /**< Rotation flag of auxiliary image, defined in sensor stereo params */
    NcLibImageSize dfsSize;                  /**< Map size, as calculated by CalcDfsInit */
    uint64_t requestID;                      /**< Request ID for reference */
};

/**
*  @brief   Calculate DFS input image and output map size. Assumptions:
*           1. Max ROI is always stretched on the entire Full image
*           2. EVA receives 1/4 of the Full image
*
*  @param [in]      in             Input struct
*  @param [out]     dfsSize        Resulting map size. Should be passed to CalcDfsFrame
*  @param [out]     mainSession    Main image GCE session-level configuration
*  @param [out]     mainFrame      Main image GCE frame-level configuration
*  @param [out]     auxSession     Auxiliary image GCE session-level configuration
*  @param [out]     sgmCfg         SGM configuration
*
*  @return NC_LIB_SUCCESS on success, error code on failure.
*/
int32_t NcLibEvaCalcDfsInit(
    const NcLibEvaCalcDfsInitIn* in,
    NcLibImageSize* dfsSize,
    NcLibGceSessionCfg* mainSession,
    NcLibGceFrameCfg* mainFrame,
    NcLibGceSessionCfg* auxSession,
    NCLIB_CONTEXT_SGM* sgmCfg);

/**
*  @brief   Calculate geometries for EVA running DFS flow
*
*  @param [in]      in             Input struct
*  @param [out]     auxGceCfg      Auxiliary image frame-level GCE configuration
*
*  @return NC_LIB_SUCCESS on success, error code on failure.
*/
int32_t NcLibEvaCalcDfsFrame(
    const NcLibEvaCalcDfsFrameIn* in,
    NcLibGceFrameCfg* auxGceCfg);


/////////////////////////////
// Segmentation
/////////////////////////////

/**
*  @brief   Segmentation require specific input dimensions due to tiles and performance
*           restrictions. This function calculates the configuration of GCE pass that
*           is used to scale the input to meet these requirements.
*           The output of this function will be used by NcLibProcessGceFrame to produce GCE
*           configuration. This function is expected to be called in the initialization stage
*           of the flow (it is not updated per frame).
*           DS4 output is expected to be used in in this pass.
*
*  @param [in]      inRoi       The input ROI that describes the input image and buffer.
*                               In case of Video/Preview flows, the input is expected to
*                               comes from the IFE FD port with these sizes:
*                               Video/Preview with 4:3 ROI  - 1920x1440
*                               Video/Preview with 16:9 ROI - 1920x1080
*                               In case of Snapshot/MMF/Still MFHDR the input is expected
*                               to come from the 1:4 image.
*  @param [in]      isVideoFlow Set to true in case of Video/Preview flow. Else set to false.
*  @param [out]     outRoi      The output ROI that describes the image and buffer of DS4 output.
*                               The imageSize describes the minimal buffer size (in pixels)
*                               that should be allocated.
*  @param [out]     session     The session configuration that will be used in
*                               NcLibProcessGceFrame.
*  @param [out]     frame       The per frame configuration that will be used
*                               in NcLibProcessGceFrame.
*
*  @return NC_LIB_SUCCESS in case of success, otherwise failed.
*/
int32_t NcLibCalcSegmentGceScale(
    const NcLibROI* inRoi,
    const bool isVideoFlow,
    NcLibROI* outRoi,
    NcLibGceSessionCfg* session,
    NcLibGceFrameCfg* frame);


#endif // NCLIBEVA_H
