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

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxsalinetinterface.h
/// @brief SALINet algorithms interfaces
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// NOWHINE FILE GR016: Typedefs must not be used for structs, classes, and enumerations

#ifndef CAMXSALINETINTERFACE_H
#define CAMXSALINETINTERFACE_H

#include "chi.h"
#include "chistatsinterfacedefs.h"
#include "chistatsdebug.h"

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

// Data structures that are exposed to OEM must be packed to have the expected layout.
#pragma pack(push, CDK_PACK_SIZE)

/** @addtogroup salinet_stats_nn
@{ */

#define SALINETMAXW 80              ///< Maximum width of the salient ROI.
#define SALINETMAXH 60              ///< Maximum height of the salient ROI.
#define SALINETROINUMMAX 5          ///< Maximum number of salient ROIs.

/// @brief Types of Create parameters for an instance of the Neural Network (NN) algorithm.
typedef struct
{
    ChiBufferFormat         imgBufFmt;          ///< Format of the image buffer.
    StatsDimension          imgBufDim;          ///< Dimensions of the image buffer.
    UINT32                  planeStride;        ///< Plane stride of the image buffer.
    UINT32                  sliceHeight;        ///< Height of a buffer plane slice.
    UINT32                  scaleDownRatio;     ///< Scale-down ratio of the image buffer for the color conversion library.
} SALINetBufFormatDimension;

/// @brief Parameters that describe the salient ROI dimensions.
typedef struct
{
    FLOAT x;                  ///< X coordinate of the region.
    FLOAT y;                  ///< Y coordinate of the region.
    FLOAT dx;                 ///< X + width of the region.
    FLOAT dy;                 ///< Y + height of the region.
} SALINetSaliencyROI;

/// @brief Parameters that contain the saliency output information for the NN algorithm.
typedef struct
{
    UINT8                   isValid;                                  ///< Flag to check the data validity.
    UINT8                   outWidth;                                 ///< Width of the saliency model output.
    UINT8                   outHeight;                                ///< Height of the saliency model output.
    UINT8                   saliNetOut[SALINETMAXW * SALINETMAXH];    ///< Array of saliency model output buffers.
    UINT8                   numSalROI;                                ///< Number of ROIs in the salientROI array.
    SALINetSaliencyROI      salientROI[SALINETROINUMMAX];             ///< Array of ROIs to be populated by the saliency net.
} SALINetSaliNetOut;

/// @brief Contains saliency output data for the NN algorithm.
typedef struct
{
    SALINetSaliNetOut       saliencyOut;        ///< Output data from the saliency model.
} SALINetResults;

/// @brief Cropping information for the NN algorithm.
typedef struct
{
    CHIRectangle appliedCropFD;                     ///< Crop is applied to a Face Detection buffer.
    CHIRectangle residualCropFD;                    ///< Residual crop to be applied to the Face Detection buffer during
                                                    ///  the preprocessing stage in the backend NN driver.
} SALINetCropInfo;

/// @brief Types of Process input parameters for the NN algorithm.
typedef enum
{
    SALINetInputTypeInvalid         = -1,           ///< Type is invalid or unknown.
    SALINetInputTypeCameraID,                       ///< Identifier for the camera.
    SALINetInputTypeRequestNumber,                  ///< Request number.
    SALINetInputTypeImgBuf,                         ///< Input image buffer.
    SALINetInputTypeCount,                          ///< Total number of parameters.
} SALINetAlgoInputType;

/// @brief Base structure of a Process input parameter for the NN algorithm instance. This structure is used with
///        #SALINetAlgoInputList.
typedef struct
{
    VOID*                   pSALINetInput;          ///< Pointer to the parameter payload.
    UINT32                  sizeOfSALINetInput;     ///< Size of the input payload data.
    SALINetAlgoInputType    inputType;              ///< Type of input payload.
                                                    ///  @newpagetable
} SALINetAlgoInput;

/// @brief List of Process input parameters that are passed to #SALINetAlgorithm::SALINetProcess().
typedef struct
{
    SALINetAlgoInput*       pSALINetInputs;         ///< Pointer to the array of parameters.
    UINT32                  inputCount;             ///< Number of elements in the array.
} SALINetAlgoInputList;

/// @brief Types of Process output parameters for the NN algorithm.
typedef enum
{
    SALINetOutputTypeInvalid            = -1,           ///< Type is invalid or unknown.
    SALINetOutputSaliencyResult,                        ///< Output data from the saliency model.
    SALINetOutputTypeCount,                             ///< Total number of parameters.
} SALINetAlgoOutputType;

/// @brief Base structure of a Process output parameter for an NN algorithm instance. This structure is used with
///        #SALINetAlgoOutputList.
typedef struct
{
    VOID*                   pSALINetOutput;              ///< Pointer to the payload that is the result of the query.
                                                         ///  The type of data depends on the value of outputType. The
                                                         ///  algorithm implementer must do a deep copy to the given memory.
    UINT32                  sizeOfSALINetOutput;         ///< Size of the payload data (in bytes).
    UINT32                  sizeOfWrittenSALINetOutput;  ///< Size of the payload data that is written back.
                                                         ///  If there is no output, set this value to 0.
    SALINetAlgoOutputType   outputType;                  ///< Type of parameter that is passed to the algorithm.
} SALINetAlgoOutput;

/// @brief List of Process output parameters that are passed to #SALINetAlgorithm::SALINetProcess().
typedef struct
{
    SALINetAlgoOutput*      pSALINetOutputs;    ///< Pointer to the array of parameters.
    UINT32                  outputCount;        ///< Number of elements in the array.
} SALINetAlgoOutputList;

/// @brief Types of Get input parameters for the NN algorithm.
typedef enum
{
    SALINetGetParamInputTypeInvalid = -1,              ///< Type is invalid or unknown.
    SALINetGetParamInputTypeCount,                     ///< Total number of parameters.
} SALINetAlgoGetParamInputType;

/// @brief Base structure of a Get input parameter for an NN algorithm instance. This structure is used with
///        #SALINetAlgoGetParamInputList.
typedef struct
{
    VOID*                           pGetParamInput;         ///< Pointer to the parameter payload.
    UINT32                          sizeOfGetParamInput;    ///< Size of the payload data (in bytes).
    SALINetAlgoGetParamInputType    getParamInputType;      ///< Type of input payload.
} SALINetAlgoGetParamInput;

/// @brief List of Get input parameters for an NN algorithm instance. This list is passed to #SALINetAlgoGetParam.
typedef struct
{
    SALINetAlgoGetParamInput*       pGetParamInputs;     ///< Pointer to the array of parameters.
    UINT32                          getParamInputCount;  ///< Number of elements in the array.
} SALINetAlgoGetParamInputList;

/// @brief Types of Get output parameters for the NN algorithm.
typedef enum
{
    SALINetGetParamOutputTypeInvalid = -1,              ///< Type is invalid or unknown.
    SALINetGetParamOutputTypeCount,                     ///< Total number of parameters.
} SALINetAlgoGetParamOutputType;

/// @brief Base structure of a Get output parameter for an NN algorithm instance. This structure is used with
///        #SALINetAlgoGetParamOutputList.
typedef struct
{
    VOID*                           pGetParamOutput;                ///< Pointer to the payload that is the result of the
                                                                    ///  query. The type of data depends on the value of
                                                                    ///  getParamOutputType.
    UINT32                          sizeOfGetParamOutput;           ///< Size of the payload data (in bytes).
    UINT32                          sizeOfWrittenGetParamOutput;    ///< Size of the payload (in bytes) that is written back.
                                                                    ///  If there is no output, set this value to 0.
    SALINetAlgoGetParamOutputType   getParamOutputType;             ///< Type of parameter that is passed to the algorithm.
} SALINetAlgoGetParamOutput;

/// @brief List of Get output parameters for an NN algorithm instance. This structure is used with #SALINetAlgoGetParam.
typedef struct
{
    SALINetAlgoGetParamOutput*      pGetParamOutputs;       ///< Pointer to the array of outputs.
    UINT32                          getParamOutputCount;    ///< Number of elements in pGetParamOutputs.
                                                            ///  @newpagetable
} SALINetAlgoGetParamOutputList;

/// @brief List of Get parameters that are passed to #SALINetAlgorithm::SALINetGetParam().
typedef struct
{
    SALINetAlgoGetParamInputList    inputInfoList;   ///< Input data that is necessary to support the query.
    SALINetAlgoGetParamOutputList   outputInfoList;  ///< Output metadata that is returned as a result of the query.
} SALINetAlgoGetParam;

/// @brief Types of Set parameters for the NN algorithm.
typedef enum
{
    SALINetSetParamTypeInvalid          = -1,           ///< Type is unknown or invalid.
    SALINetSetParamTypeTuningData,                      ///< Payload: #StatsTuningData
    SALINetSetParamsTypeCameraInfo,                     ///< Payload: #StatsCameraInfo
    SALINetSetParamTypeFDCropInformation,               ///< Payload: #SALINetCropInfo
    SALINetSetParamTypeCount,                           ///< Total number of parameters.
} SALINetAlgoSetParamType;

/// @brief Base structure of a Set parameter for an NN algorithm instance. This structure is used with
///        #SALINetAlgoSetParamList.
typedef struct
{
    const VOID*              pSALINetSetParam;      ///< Pointer to the parameter payload.
    UINT32                   sizeOfSetParam;        ///< Size of the payload data (in bytes).
    SALINetAlgoSetParamType  setParamType;          ///< Type of parameter that is passed to the algorithm.
} SALINetAlgoSetParam;

/// @brief List of Set parameters that are passed to #SALINetAlgorithm::SALINetSetParam().
typedef struct
{
    SALINetAlgoSetParam*        pSALINetSetParams;    ///< Pointer to the array of parameters.
    UINT32                      setParamsCount;       ///< Number of elements in the array.
} SALINetAlgoSetParamList;

/// @brief Parameters used when creating an NN algorithm instance.
typedef enum
{
    SALINetCreateParamsTypeInvalid      = -1,       ///< Type is unknown or invalid.
    SALINetCreateParamsTypeLogger,                  ///< Payload: Logger function structure
    SALINetCreateParamsTypeCameraInfo,              ///< Payload: #StatsCameraInfo
    SALINetCreateParamsTypeBufFmtDim,               ///< Payload: #StatsDimension
    SALINetCreateParamsTypeTuningParams,            ///< Payload: #StatsTuningData
    SALINetCreateParamTypeSettingsPtr,              ///< Pointer to the settings data.
    SALINetCreateParamsTypeCount,                   ///< Total number of parameters.
} SALINetAlgoCreateParamType;

/// @brief Base structure of a Create parameter for an NN algorithm instance. This structure is used with
///        #SALINetAlgoCreateParamList.
typedef struct
{
    VOID*                       pCreateParam;           ///< Pointer to the parameter payload.
    UINT32                      sizeOfCreateParam;      ///< Size of the payload data (in bytes).
    SALINetAlgoCreateParamType  createParamType;        ///< Type of parameter that is passed to the algorithm.
} SALINetAlgoCreateParam;

/// @brief List of Create parameters that are passed to CREATESALINet().
typedef struct
{
    SALINetAlgoCreateParam*     pCreateParams;          ///< Pointer to the array of parameters.
    UINT32                      createParamsCount;      ///< Number of elements in the array.
} SALINetAlgoCreateParamList;

/// @brief Types of Destroy parameters for the NN algorithm.
typedef enum
{
    SALINetDestroyParamTypeInvalid               = -1,  ///< Type is invalid or unknown.
    SALINetDestroyParamTypeCameraID,                    ///< Identifier for the camera.
    SALINetDestroyParamTypeCount,                       ///< Total number of parameters.
} SALINetAlgoDestroyParamType;

/// @brief Base structure of a Destroy parameter for an NN algorithm instance. This structure is used with
///        #SALINetAlgoDestroyParamList.
typedef struct
{
    SALINetAlgoDestroyParamType destroyParamType;       ///< Type of parameter that is passed to the algorithm.
    VOID*                       pParam;                 ///< Pointer to the parameter payload.
    UINT32                      sizeOfParam;            ///< Size of the payload data (in bytes).
} SALINetAlgoDestroyParam;

/// @brief List of Destroy parameters that are passed to #SALINetAlgorithm::SALINetDestroy().
typedef struct
{
    SALINetAlgoDestroyParam*    pParamList;         ///< Pointer to the array of parameters.
    UINT32                      paramCount;         ///< Number of elements in the array.
} SALINetAlgoDestroyParamList;

/// @brief Represents NN algorithm settings controlled from the camxsettings.xml file.
typedef struct
{
    BOOL                        profile;   ///< Indicates whether profiling is enabled.
                                           ///
                                           ///  @valuesbul
                                           ///  - 0 -- FALSE
                                           ///  - 1 -- TRUE @tablebulletend

    UINT8                       dump;      ///< Dumps the debug data.
} SALINetAlgoSettings;


/// @brief Function wrapper for the Statistics NN algorithm.
typedef struct /** @cond */ SALINetAlgorithm /** @endcond */
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond SALINetProcess @endcond
    ///
    /// @brief Runs the NN algorithm on the given inputs.
    ///
    /// @datatypes
    /// #SALINetAlgoInputList \n
    /// #SALINetAlgoOutputList
    ///
    /// @param[in] pSALINetAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pInputs               Pointer to the statistics inputs interface.
    /// @param[in] pOutputs              Pointer to statistics data that the algorithm outputs.
    ///
    /// @return #CDKResultSuccess. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*SALINetProcess)(
        SALINetAlgorithm*              pSALINetAlgorithm,
        const SALINetAlgoInputList*    pInputs,
        SALINetAlgoOutputList*         pOutputs);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond SALINetGetParam @endcond
    ///
    /// @brief Retrieves the most up-to-date NN algorithm information. Typically, the output is updated after calling
    ///        SALINetProcess().
    ///
    /// @datatypes
    /// #SALINetAlgoGetParam
    ///
    /// @param[in]  pSALINetAlgorithm     Pointer to the algorithm instance.
    /// @param[out] pGetParam             Pointer to the metadata and associated data that is necessary to support the query.
    ///
    /// @return #CDKResultSuccess.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*SALINetGetParam)(
        SALINetAlgorithm*       pSALINetAlgorithm,
        SALINetAlgoGetParam*    pGetParam);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond SALINetSetParam @endcond
    ///
    /// @brief Sets configuration parameters to the NN algorithm.
    ///
    /// @datatypes
    /// #SALINetAlgoSetParamList
    ///
    /// @param[in] pSALINetAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pSetParams            Pointer to the input parameter list.
    ///                                  Each element in the list is of type #SALINetAlgoSetParam.
    ///
    /// @return #CDKResultSuccess. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*SALINetSetParam)(
        SALINetAlgorithm*                pSALINetAlgorithm,
        const SALINetAlgoSetParamList*   pSetParams);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond SALINetGetFeatureCapability @endcond
    ///
    /// @brief Gets the features of the NN algorithm.
    ///
    /// @param[in] pSALINetAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pFeatures             Pointer to the features supported by the algorithm.
    ///
    /// @return #CDKResultSuccess.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*SALINetGetFeatureCapability)(
        SALINetAlgorithm*       pSALINetAlgorithm,
        UINT64*                 pFeatures);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond SALINetDestroy @endcond
    ///
    /// @brief Destroys a derived instance of the NN interface.
    ///
    /// @datatypes
    /// #SALINetAlgoDestroyParamList
    ///
    /// @param[in] pSALINetAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pDestroyParams        Pointer to the list of parameters.
    ///
    /// @return None. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*SALINetDestroy)(
        SALINetAlgorithm*                    pSALINetAlgorithm,
        const SALINetAlgoDestroyParamList*   pDestroyParams);

} SALINetAlgorithm;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @cond CreateSALINet @endcond
///
/// @brief Creates an instance of the NN algorithm.
///
/// @datatypes
/// #SALINetAlgoCreateParamList \n
/// #SALINetAlgorithm
///
/// @param[in] pCreateParams          Pointer to the parameters.
/// @param[in] ppSALINetAlgorithm     Double pointer  to the created algorithm instance.
///
/// @return #CDKResultSuccess.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef CDKResult (*CREATESALINet)(
    const SALINetAlgoCreateParamList*   pCreateParams,
    SALINetAlgorithm**                  ppSALINetAlgorithm);

#pragma pack(pop)

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // SALINETINTERFACE_H
