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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxqllalgorithminterface.h
/// @brief QLL library interface
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef  CAMXQLLALGORITHMINTERFACE_H
#define  CAMXQLLALGORITHMINTERFACE_H

#include "camxdebugprint.h"
#include "chistatsdebug.h"
#include "camxtypes.h"
#include "chistatspropertydefines.h"
#include "camxipeproperty.h"
#include "chiispstatsdefs.h"
#ifdef ENABLE_QLL
#include "qll_interface.h"
#endif

#ifdef __cplusplus

extern "C"
{
#endif // __cplusplus

CAMX_NAMESPACE_BEGIN

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

/************** QLL Algorithm data ****************/
typedef struct
{
    UINT64             exposureTime;                     ///< exposure time
    FLOAT              linearGain;                       ///< linear gain applied to sensor and isp
    FLOAT              sensitivity;                      ///< Original sensitivity
    UINT64             meteringTargetExp;                ///< Metering target exposure
} AECExposureInfo;

typedef struct
{
    UINT64           requestId;                             ///< Request ID
    FLOAT            luxIndex;                              ///< lux index
    FLOAT            compenADRCGain;                        ///< ADRC ratio
    AECExposureInfo  exposureData[AlgoOutputExposureCount]; ///< exposure information
} AECData;

typedef struct
{
    UINT32              tfiWidth;                        ///< tfi DC4 buffer heigh
    UINT32              tfiHeight;                       ///< tfi DC4 buffer width
    UINT32              tfiStride;                       ///< tfi DC4 buffer stride
}TFIBufferDimensions;

typedef struct
{
    FLOAT               maxSensorAnalogGain;             ///< Sensor's max analog gain
    UINT64              maxSensorExposureTimeLimitation; ///< Sensor driver exposure limitation in ns
    UINT32              cameraPosition;                  ///< camera position
} QLLInitData;

/// @ brief QLL input for global motion indication
struct GMIData
{
    FLOAT       normAvg;                        ///< Norm average [0, 1]
    FLOAT       motionIndicationVal;            ///< Global Motion indication [0, 1]
    UINT8       tripodEnabled;                  ///< Whether EVA tripod is enabled. 1 == TRUE, 0 == FALSE
    FLOAT       tripodVal;                      ///< EVA tripod value
};

/// @ brief QLL input for local motion indication
struct LMIData
{
    UINT8       calcType;                       ///< Calcuation type: 0 == DMM, 1 == TFI
    FLOAT       motionIndicationVal;            ///< Global Motion indication [0, 1]
};

/// @ brief QLL library inputs from IPE node
struct QLLMotionData
{
    UINT64      requestId;                     ///< request id for this qll input information
    CamxTime    timeStamp;                     ///< timestamp for this qll input information
    GMIData     gmiInfo;                       ///< Global Motion Indication Information
    LMIData     lmiInfo;                       ///< Local Motion Indication Information
};

typedef enum
{
    QLLAlgoInputInvalid = -1,
    QLLAlgoInputAECDecisions,                   ///< AEC decisions input for setting long frame
                                                ///  Payload type: QLLAECDecisions
    QLLAlgoInputCameraInfo,                     ///< Camera info
                                                ///  Payload type: StatsCameraInfo
    QLLAlgoInputChromatixData,                  ///< Chromatix tuning header for QLL algorithm
                                                ///  Payload type: StatsTuningData
    QLLAlgoInputMotionData,                     ///< GMI, LMI, EVA information
                                                ///< Payload type: QLLMotionData
    QLLAlgoInputCount,
    QLLAlgoInputMax = 0x7FFFFFFF
} QLLAlgoInputType;

typedef enum
{
    QLLAlgoSetParamInvalid = -1,
    QLLAlgoSetParamCameraInfo,                          ///< camera info
                                                        ///  Payload type: StatsCameraInfo
    QLLAlgoSetParamPipelineDelay,                       ///< Set the pipeline delay
                                                        ///  Paylod type: UINT8
    QLLAlgoSetParamIsSnapshotFrame,                     ///< set flag to indicate snapshot request
                                                        ///  Payload type: BOOL
    QLLAlgoSetParamIsForceTriggered,                    ///< set flag to force qll triggered
                                                        ///  Payload type: BOOL
    QLLAlgoSetParamCount,
    QLLAlgoSetParamMax = 0x7FFFFFFF
} QLLAlgoSetParamType;

typedef enum
{
    QLLAlgoGetParamTypeInvalid = -1,
    QLLAlgoGetParamTypeMax = 0x7FFFFFFF
} QLLAlgoGetParamType;

typedef enum
{
    QLLAlgoOutputInvalid = -1,
    QLLAlgoOutputQLLFrameControl,                   ///< QLL frame output information for long/medium/short frames
                                                    ///  Payload type: QLLFrameControl
    QLLAlgoOutputCount,
    QLLAlgoOutputMax = 0x7FFFFFFF
} QLLAlgoOutputType;

typedef enum
{
    QLLAlgoDestroyParamInvalid = -1,
    QLLAlgoDestroyParamTypeCameraInfo,                    ///< camera info
    QLLAlgoDestroyParamTypeCount,
    QLLAlgoDestroyParamTypeMax = 0x7FFFFFFF
} QLLAlgoDestroyParamType;

typedef enum
{
    QLLAlgoCreateParamTypeInvalid = -1,                    ///< Invalid type
    QLLAlgoCreateParamTypeLoggerFunctionPtr,               ///< Logging function pointers
                                                           ///  Payload type: StatsLoggerFunction
    QLLAlgoCreateParamTypeCameraInfo,                      ///< Camera info
                                                           ///  Payload type: StatsCameraInfo
    QLLAlgoCreateParamTypeInitData,                        ///< Initialization Data
                                                           ///  Payload type: QLLInitData
    QLLAlgoCreateParamTypeChromatixData,                   ///< Chromatix Data
                                                           ///  Payload type: QLLTuning
    QLLAlgoCreateParamTypeDumpLogMask,                     ///< Mask to enable QLL lib log dumps
                                                           ///  Payload type: UINT
    QLLAlgoCreateParamTypeHDRFeatureMode,                  ///< HDR feature mode
                                                           /// Payload type: HDRFeatureMode
    QLLAlgoCreateParamTypeCount,                           ///< Anchor to indicate the last item in the defines
    QLLAlgoCreateParamTypeMax = 0x7FFFFFFF
} QLLAlgoCreateParamsType;

typedef struct
{
    VOID*               pQLLInput;                      ///< pointer to qll input
    UINT32              sizeOfQLLInput;                 ///< size of input
    QLLAlgoInputType    inputType;                      ///< input type
} QLLAlgoInput;


typedef struct
{
    QLLAlgoInput*       pQLLInputList;                  ///< Pointer to input list
    UINT32              numberOfQLLInputs;              ///< number of inputs to QLL engine
} QLLAlgoInputList;

typedef struct
{
    VOID*               pQLLSetParam;                   ///< pointer to set param
    UINT32              sizeOfQLLSetParam;              ///< size of set param
    QLLAlgoSetParamType setParamType;
} QLLAlgoSetParam;

typedef struct
{
    QLLAlgoSetParam*    pQLLSetParamList;               ///< Pointer to set param list
    UINT32              numberOfQLLSetParams;           /// number of elements in set param
} QLLAlgoSetParamList;

typedef struct
{
    VOID*    pInputData;                               ///< pointer to input data
    UINT32   sizeOfInputData;                          ///< size of input data
} QLLAlgoGetParamInputs;

typedef struct
{
    VOID*   pOutputData;                               ///< pointer to output data
    UINT32  sizeOfOutputData;                          ///< size of output data
} QLLAlgoGetParamOutputs;

typedef struct
{
    QLLAlgoGetParamType     type;                      ///< type of get param
    QLLAlgoGetParamInputs   inputs;                    ///< get param inputs
    QLLAlgoGetParamOutputs  outputs;                   ///< get param output
}   QLLAlgoGetParam;

typedef struct
{
    QLLAlgoDestroyParamType  destroyParamType;         ///< destroy param type
    VOID*                    pParam;                   ///< poointer to destroy param
    UINT32                   sizeOfParam;              ///< size of the param
} QLLAlgoDestroyParam;

typedef struct
{
    QLLAlgoDestroyParam*    pParamList;               ///< destroy param list
    UINT32                  paramCount;               ///< param count
}   QLLAlgoDestroyParamList;

/// @brief Represents the one single type of QLL output from the algorithm
typedef struct
{
    VOID*                   pQLLOutput;                 ///< Pointer to the payload. See QLLAlgoOutputType for details
                                                        ///  Algorithm implementer needs to do a deep copy
    SIZE_T                  sizeOfQLLOutput;            ///< Size of input payload pointed to by pQLLOutput
    SIZE_T                  sizeOfWrittenQLLOutput;     ///< Size of payload written back
    QLLAlgoOutputType       outputType;                 ///< Type of the payload
} QLLAlgoOutput;

typedef struct
{
    QLLAlgoOutput* pQLLOutputList;                      ///< Pointer to QLLAlgoOutput array.
    SIZE_T         numberOfQLLOutputs;                  ///< Number of elements in pOutputData
} QLLAlgoOutputList;

typedef struct
{
    VOID*                        pCreateParam;          ///< Payload. See QLLAlgoCreateParamType for details
    UINT32                       sizeOfCreateParam;     ///< Size of payload pointed by data.
    QLLAlgoCreateParamsType      createParamType;       ///< Create parameter type.
} QLLAlgoCreateParam;

typedef struct
{
    QLLAlgoCreateParam*         pCreateParamList;        ///< Payload. See QLLAlgoCreateParamType for details
    SIZE_T                      numberOfCreateParam;     ///< Number of create parameters.
} QLLAlgoCreateParamList;

///< QLL Algorithm Class
class QLLAlgorithm
{
    public:
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLCreateAlgo
        ///
        /// @brief  Create QLL algorithm function pointer
        ///
        /// @param  pCreateParamList Pointer to createparamlist
        /// @param  ppQLLAlgorithm   qll algorithm pointer
        ///
        /// @return CamxResultSuccess if successful
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        typedef CamxResult (*QLLCreateAlgo)(
            const QLLAlgoCreateParamList* pCreateParamList,
            QLLAlgorithm**                ppQLLAlgorithm);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLProcess
        ///
        /// @brief  invoke qll library for processing
        ///
        /// @param  pInput    Pointer to input list
        /// @param  pOutput   Pointer to output list
        ///
        /// @return CamxResultSuccess if successful
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        typedef CamxResult (*QLLProcess)(
            const QLLAlgoInputList*     pInput,
            QLLAlgoOutputList*          pOutput);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLGetParam
        ///
        /// @brief  Get parameter from qll library
        ///
        /// @param  pGetParam   Pointer to get param list
        ///
        /// @return CamxResultSuccess if successful
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        typedef CamxResult (*QLLGetParam)(
            const QLLAlgoGetParam*         pGetParam);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLSetParam
        ///
        /// @brief  Set parameter to qll library
        ///
        /// @param  pSetParam   Pointer to set param list
        ///
        /// @return CamxResultSuccess if successful
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        typedef CamxResult (*QLLSetParam)(
            const QLLAlgoSetParamList*  pSetParam);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLDestroy
        ///
        /// @brief  Destroy qll library
        ///
        /// @return NONE
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        typedef VOID (*QLLDestroy)(
            const QLLAlgoDestroyParamList* pDestroyList);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLAlgorithm
        ///
        /// @brief  qll algorithm constructor
        ///
        /// @return NONE
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        QLLAlgorithm();

    protected:
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// ~QLLAlgorithm
        ///
        /// @brief  qll algorithm deconstructor
        ///
        /// @return NONE
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ~QLLAlgorithm();

    private:
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLProcessInputParam
        ///
        /// @brief  qll process input parameters
        ///
        /// @param  pInput input list
        ///
        /// @return NONE
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        VOID QLLProcessInputParams(
                const QLLAlgoInputList* pInput,
                UINT32 cameraID);

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// QLLProcessOutputParams
        ///
        /// @brief  qll process output parameters
        ///
        /// @param pOutput  output list
        ///
        /// @return NONE
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        VOID QLLProcessOutputParams(
                QLLAlgoOutputList* pOutput,
                UINT32 cameraID);

};

///< QLL Callback function pointers
typedef struct
{
    QLLAlgorithm::QLLCreateAlgo       createAlgo;
    QLLAlgorithm::QLLProcess          qllProcess;
    QLLAlgorithm::QLLGetParam         qllGetParam;
    QLLAlgorithm::QLLSetParam         qllSetParam;
    QLLAlgorithm::QLLDestroy          qllDestroy;
}  QLLAlgorithmCallbacks;

///< QLL algorithm entry function
typedef VOID (*QLLALGORITHMENTRY)(
    QLLAlgorithmCallbacks* pQLLAlgoCallbacks);

#pragma pack(pop)

#ifdef __cplusplus
}
#endif // __cplusplus

CAMX_NAMESPACE_END

#endif // CAMXQLLALGORITHMINTERFACE_H
