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

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxtrackerinterface.h
/// @brief Touch to track algorithm interfaces
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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

#ifndef CAMXTRACKERINTERFACE_H
#define CAMXTRACKERINTERFACE_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 chi_stats_tracker
@{ */

/// @brief Tracker state types.
typedef enum
{
    TrackerStateIdle,               ///< Tracker is idle.
    TrackerStateRegistering,        ///< Tracker received a registration command and is registering the ROI.
    TrackerStateRegistered,         ///< Tracker finished registration and received a valid track instance ID.
    TrackerStateTracking,           ///< Tracker node is tracking on the registered object.
    TrackerStateInvalid,            ///< Tracker state is unknown or invalid.
} TrackerAlgoState;

/// @brief String representations of #TrackerAlgoState:
///
/// @code
/// "TrackerStateRegistering",
/// "TrackerStateRegistered",
/// "TrackerStateTracking",
/// "TrackerStateInvalid"
/// @endcode
///
/// The strings must be in same sequence as in #TrackerAlgoState.
/// @hideinitializer
static const CHAR* TrackerAlgoStateStrings[] =
{
    "TrackerStateIdle",
    "TrackerStateRegistering",
    "TrackerStateRegistered",
    "TrackerStateTracking",
    "TrackerStateInvalid"
};

/// @brief Command triggers for the Tracker algorithm.
typedef enum
{
    TrackerCMDTrack,            ///< Trigger the object track operation to get the latest ROI for the recognized object.
    TrackerCMDReg,              ///< Trigger the object registration with the provided ROI.
    TrackerCMDCancel,           ///< Cancel synchronization and deregister the tracking object.
    TrackerCMDInvalid           ///< Tracker command is invalid.
} TrackerCMDType;

/// @brief String representations of #TrackerCMDType:
///
/// @code
/// "TrackerCMDTrack",
/// "TrackerCMDReg",
/// "TrackerCMDCancel",
/// "TrackerCMDInvalid"
/// @endcode
///
/// The strings must be in same sequence as in #TrackerAlgoState.
/// @hideinitializer
static const CHAR* TrackerCMDTypeStrings[] =
{
    "TrackerCMDTrack",
    "TrackerCMDReg",
    "TrackerCMDCancel",
    "TrackerCMDInvalid"
};

/// @brief Operation modes for the Tracker algorithm.
typedef enum
{
    TrackerModeDefault,
    TrackerModePerformance,     ///< Fastest implementation is selected for all.
    TrackerModeCpuOffload,      ///< Preference is given to offload to any available hardware.
    TrackerModeLowPower,        ///< Preference is given to an implementation that draws the least power.
    TrackerModeCpuPerformance,  ///< CPU Performance mode.
    TrackerModeCpuOffloadCVP    ///< CPU Offload mode, where preference is given to offload the partial implementation to
                                ///  the CVP.
} TrackerOperationMode;

/// @brief Precision modes for Tracker processing.
typedef enum
{
    TrackerPrecisionHigh = 0,   ///< High processing load, but results are more precise.
    TrackerPrecisionLow  = 1,   ///< Low processing load, but results are less precise.
    TrackerPrecisionLWT  = 2    ///< LiteWeightTracker, but results are precise and no latency impact.
} TrackerPrecisionMode;

/// @brief Contains parameters for creating an image buffer for the Tracker algorithm.
typedef struct
{
    ChiBufferFormat         imgBufFmt;          ///< Format of the image buffer.
    StatsDimension          imgBufDim;          ///< Dimensions (width and height) of the image buffer.
    UINT32                  planeStride;        ///< Plane stride of the image buffer.
} TrackerBufFormatDimension;

/// @brief Contains parameters that define the Tracker algorithm output.
typedef struct
{
    UINT32                  confidence;         ///< Confidence level that is output by the algorithm.
    StatsRectangle          statsRectROI;       ///< ROI rectangle statistics that is output by the algorithm.
    TrackerAlgoState        trackerAlgoState;   ///< Current state of the algorithm.
} TrackerResults;

/// @brief Contains static settings relevant to the Tracker algorithm.
typedef struct
{
    BOOL                    enableTouchToTrack;  ///< Indicates whether the Touch To Track feature is enabled Not sure how to put "from overridesetting" in the comment; please clarify/revise this comment.
                                                 ///
                                                 ///  @valuesbul
                                                 ///  - 0 -- FALSE
                                                 ///  - 1 -- TRUE @tablebulletend

    UINT32                  profile3A;           ///< Bit mask to control 3A profiling traces.
} TrackerSettingsInfo;

/// @brief Types of Process input parameters for the Tracker algorithm.
typedef enum
{
    TrackerInputTypeInvalid         = -1,           ///< Type is invalid or unknown.
    TrackerInputTypeCameraID,                       ///< Identifier for the camera.
    TrackerInputTypeRequestNumber,                  ///< Request number.
    TrackerInputTypeCMDType,                        ///< Type of command trigger. \n
                                                    ///  Payload: #TrackerCMDType
    TrackerInputTypeRegisterROI,                    ///< Input touch ROI. \n
                                                    ///  Payload: #CHIRectangle
    TrackerInputTypeImgBuf,                         ///< Input image buffer.
    TrackerInputTypeCount,                          ///< Total number of parameters.
} TrackerAlgoInputType;

/// @brief Base structure of a Process input parameter for a Tracker algorithm instance. This structure is used with
///        #TrackerAlgoInputList.
typedef struct
{
    VOID*                   pTrackerInput;          ///< Pointer to the parameter payload.
    UINT32                  sizeOfTrackerInput;     ///< Size of the payload data (in bytes).
    TrackerAlgoInputType    inputType;              ///< Type of input payload.
} TrackerAlgoInput;

/// @brief List of Process input parameters that are passed to #TrackerAlgorithm::TrackerProcess().
typedef struct
{
    TrackerAlgoInput*       pTrackerInputs;             ///< Pointer to the array of parameters.
    UINT32                  inputCount;                 ///< Number of elements in the array.
} TrackerAlgoInputList;

/// @brief Types of Process output parameters for the Tracker algorithm.
typedef enum
{
    TrackerOutputTypeInvalid            = -1,
    TrackerOutputTypeTrackROIResult,
    TrackerOutputTypeCount,
} TrackerAlgoOutputType;

/// @brief Base structure of a Process output parameter for a Tracker algorithm instance. This structure is used with
///        #TrackerAlgoOutputList.
typedef struct
{
    VOID*                   pTrackerOutput;              ///< 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                  sizeOfTrackerOutput;         ///< Size of the payload data (in bytes).
    UINT32                  sizeOfWrittenTrackerOutput;  ///< Size of the payload (in bytes) that is written back.
                                                         ///  If there is no output, set this parameter to 0.
    TrackerAlgoOutputType   outputType;                  ///< Type of output payload.
} TrackerAlgoOutput;

/// @brief List of Process output parameters that are passed to #TrackerAlgorithm::TrackerProcess().
typedef struct
{
    TrackerAlgoOutput*      pTrackerOutputs;    ///< Pointer to the array of parameters.
    UINT32                  outputCount;        ///< Number of elements in the array.
} TrackerAlgoOutputList;

/// @brief Types of Get input parameters for the Tracker algorithm.
typedef enum
{
    TrackerGetParamIntputTypeInvalid = -1,      ///< Type is unknown or invalid.
    TrackerGetParamInputTypeCount,              ///< Total number of parameters.
} TrackerAlgoGetParamInputType;

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

/// @brief List of Get input parameters for a query from a Tracker algorithm instance.
///        This list is passed to #TrackerAlgoGetParam.
typedef struct
{
    TrackerAlgoGetParamInput*       pGetParamInputs;     ///< Pointer to the array of input parameters.
    UINT32                          getParamInputCount;  ///< Number of inputs in the array.
                                                         ///  @newpagetable
} TrackerAlgoGetParamInputList;

/// @brief Types of Get output parameters for the Tracker algorithm.
typedef enum
{
    TrackerGetParamOutputTypeInvalid = -1,               ///< Type is unknown or invalid.
    TrackerGetParamOutputTypeCount,                      ///< Total number of parameters.
} TrackerAlgoGetParamOutputType;

/// @brief Base structure of a Get output parameter for a Tracker algorithm instance. This structure is used with
///        #TrackerAlgoGetParamInputList.
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 parameter to 0.
    TrackerAlgoGetParamOutputType   getParamOutputType;           ///< Type of output payload.
} TrackerAlgoGetParamOutput;

/// @brief List of Get output parameters for a query from a Tracker algorithm instance.
///        This list is passed to #TrackerAlgoGetParam.
typedef struct
{
    TrackerAlgoGetParamOutput*      pGetParamOutputs;      ///< Pointer to the array of output parameters.
    UINT32                          getParamOutputCount;   ///< Number of elements in pGetParamOutputs.
} TrackerAlgoGetParamOutputList;

/// @brief List of parameters passed to #TrackerAlgorithm::TrackerGetParam().
typedef struct
{
    TrackerAlgoGetParamInputList    inputInfoList;   ///< Input data that is necessary to support the query.
    TrackerAlgoGetParamOutputList   outputInfoList;  ///< Output metadata that is returned as a result of the query.
                                                     ///  @newpagetable
} TrackerAlgoGetParam;

/// @brief Types of Set parameters for the Tracker algorithm.
typedef enum
{
    TrackerSetParamTypeInvalid          = -1,           ///< Type is unknown or invalid.
    TrackerSetParamTypeCount,                           ///< Total number of parameters.
} TrackerAlgoSetParamType;

/// @brief Base structure of a Set parameter for a Tracker algorithm instance. This structure is used with
///        #TrackerAlgoSetParamList.
typedef struct
{
    const VOID*                 pTrackerSetParam;       ///< Pointer to the parameter payload.
    UINT32                      sizeOfInputParam;       ///< Size of the payload data (in bytes).
    TrackerAlgoSetParamType     setParamType;           ///< Type of parameter that is passed to the algorithm.
} TrackerAlgoSetParam;

/// @brief List of Set parameters that are passed to #TrackerAlgorithm::TrackerSetParam().
typedef struct
{
    TrackerAlgoSetParam*        pTrackerSetParams;      ///< Pointer to the array of parameters.
    UINT32                      inputParamsCount;       ///< Number of elements in the array.
} TrackerAlgoSetParamList;

/// @brief Parameters used when creating a Tracker algorithm instance.
typedef enum
{
    TrackerCreateParamsTypeInvalid      = -1,       ///< Type is unknown or invalid.
    TrackerCreateParamsTypeBufFmtDim,               ///< Format and dimensions of the image buffer. \n
                                                    ///  Payload: #TrackerBufFormatDimension
    TrackerCreateParamsTypeLogger,                  ///< Logger function.
    TrackerCreateParamsTypeCameraInfo,              ///< Payload: #StatsCameraInfo
    TrackerCreateParamsTypeTuningData,              ///< Statistics tuning data.
    TrackerCreateParamsTypeSettingsInfo,            ///< Payload: TrackerSettingsInfo
    TrackerCreateParamsTypeCount,                   ///< Total number of parameters.
} TrackerAlgoCreateParamType;

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

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

/// @brief Parameters used when destroying a Tracker algorithm instance.
typedef enum
{
    TrackerDestroyParamTypeInvalid               = -1,  ///< Type is unknown or invalid.
    TrackerDestroyParamTypeCameraID,                    ///< Identifier for the camera.
    TrackerDestroyParamTypeCount,                       ///< Total number of parameters.
} TrackerAlgoDestroyParamType;

/// @brief Base structure of a Destroy parameter for a Tracker algorithm instance. This structure is used with
///        #TrackerAlgoDestroyParamList.
typedef struct
{
    TrackerAlgoDestroyParamType 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).
} TrackerAlgoDestroyParam;

/// @brief List of Destroy parameters that are passed to #TrackerAlgorithm::TrackerDestroy().
typedef struct
{
    TrackerAlgoDestroyParam*    pParamList;         ///< Pointer to the array of parameters.
    UINT32                      paramCount;         ///< Number of elements in the array.
                                                    ///  @newpagetable
} TrackerAlgoDestroyParamList;


/// @brief Function wrapper for the Tracker algorithm.
typedef struct /** @cond */ TrackerAlgorithm /** @endcond */
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond TrackerProcess @endcond
    ///
    /// @brief Runs the Tracker algorithm on the given inputs.
    ///
    /// @datatypes
    /// #TrackerAlgoInputList \n
    /// #TrackerAlgoOutputList
    ///
    /// @param[in] pTrackerAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pInputs               Pointer to the statistics inputs interface.
    /// @param[in] pOutputs              Pointer to the statistics data that the algorithm outputs.
    ///
    /// @return #CDKResultSuccess. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*TrackerProcess)(
        TrackerAlgorithm*              pTrackerAlgorithm,
        const TrackerAlgoInputList*    pInputs,
        TrackerAlgoOutputList*         pOutputs);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond TrackerGetParam @endcond
    ///
    /// @brief Retrieves the most up-to-date Tracker algorithm information. Typically, the output is updated after calling
    ///        TrackerProcess().
    ///
    /// @datatypes
    /// #TrackerAlgoGetParam
    ///
    /// @param[in]  pTrackerAlgorithm     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(*TrackerGetParam)(
        TrackerAlgorithm*       pTrackerAlgorithm,
        TrackerAlgoGetParam*    pGetParam);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond TrackerSetParam @endcond
    ///
    /// @brief Sets configuration parameters to the Tracker algorithm.
    ///
    /// @datatypes
    /// #TrackerAlgoSetParamList
    ///
    /// @param[in] pTrackerAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pSetParams            Pointer to the input parameter list. Each element in the list is of type
    ///                                  #TrackerAlgoSetParam.
    ///
    /// @return #CDKResultSuccess. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*TrackerSetParam)(
        TrackerAlgorithm*                pTrackerAlgorithm,
        const TrackerAlgoSetParamList*   pSetParams);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond TrackerGetFeatureCapability @endcond
    ///
    /// @brief Gets the features of the Tracker algorithm.
    ///
    /// @param[in] pTrackerAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pFeatures             Pointer to the features supported by the algorithm.
    ///
    /// @return #CDKResultSuccess.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*TrackerGetFeatureCapability)(
        TrackerAlgorithm*       pTrackerAlgorithm,
        UINT64*                 pFeatures);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond TrackerDestroy @endcond
    ///
    /// @brief Destroys a derived instance of the Tracker algorithm interface.
    ///
    /// @datatypes
    /// #TrackerAlgoDestroyParamList
    ///
    /// @param[in] pTrackerAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pDestroyParams        Pointer to the list of parameters.
    ///
    /// @return None. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*TrackerDestroy)(
        TrackerAlgorithm*                    pTrackerAlgorithm,
        const TrackerAlgoDestroyParamList*   pDestroyParams);
} TrackerAlgorithm;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @cond CreateTracker @endcond
///
/// @brief Creates an instance of the Tracker algorithm.
///
/// @datatypes
/// #TrackerAlgoCreateParamList \n
/// #TrackerAlgorithm
///
/// @param[in] pCreateParams       Pointer to the parameters.
/// @param[in] ppTrackerAlgorithm  Double pointer to the created algorithm instance.
///
/// @return #CDKResultSuccess.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef CDKResult (*CREATETRACKER)(
    const TrackerAlgoCreateParamList*   pCreateParams,
    TrackerAlgorithm**                  ppTrackerAlgorithm);

/** @} */ /* end_addtogroup chi_stats_tracker */

#pragma pack(pop)

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // CAMXTRACKERINTERFACE_H
