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

#include <stdint.h>
#include <stdbool.h>
#include "QLL_Chromatix.h"

/*****************************************************************************/
/*         Definitions and Macros                                            */
/*****************************************************************************/

#define QLL_API_VERSION_MAJOR       1  /**< Major API version number */
#define QLL_API_VERSION_MINOR       0  /**< Minor API version number */
#define QLL_API_VERSION_STEP        0  /**< Step API version number */

#if defined(ANDROID)
#define QLL_VISIBILITY_PUBLIC       __attribute__ ((visibility ("default")))
#define QLL_VISIBILITY_LOCAL        __attribute__ ((visibility ("hidden")))
#else
#define QLL_VISIBILITY_PUBLIC
#define QLL_VISIBILITY_LOCAL
#endif // defined(ANDROID)

#ifdef __cplusplus
extern "C" {
#endif

#define QLL_MAX_BUFFER_SIZE     64      /**< QLL max number of frames for each MFNR instance */
#define QLL_RNR_LUT_SIZE        17      /**< QLL Chromatix ML radial strength LUT size */
#define QLL_RESERVED_LUT_SIZE   32      /**< QLL Chromatix reserved LUTs sizes */

/*****************************************************************************/
/*         QLL Algorithm data structures                                     */
/*****************************************************************************/

/**
    @brief   QLL operation modes.
**/
typedef enum qll_mode_e
{
    QLL_MODE_MFNR               = 0,    /**< Long frames MFNR with ADRC + Second IPE pass + ML node */
    QLL_MODE_MFHDR              = 1,    /**< MFNR + MFHDR + Second IPE pass + ML node */
    QLL_MODE_OFF                = 2,    /**< QLL decision is to use standard flow (non ultra low light scenario) */
    QLL_MODE_ON                 = 3,    /**< QLL should be enabled, either in MFNR or MFHDR flow (decided later)  */
    QLL_MODE_MAX_SIZE                   /**< For SW */
} qll_mode;

/**
    @brief   Display operation modes.
**/
typedef enum qll_preview_mode_e
{
    QLL_PREVIEW_MODE_DEF        = 0,    /**< Preview is standard (no MFHDR, no ADRC) */
    QLL_PREVIEW_MODE_ADRC       = 1,    /**< Preview is ADRC */
    QLL_PREVIEW_MODE_MFHDR      = 2,    /**< Preview is MFHDR */
    QLL_PREVIEW_MODE_MAX_SIZE           /**< For SW */
} qll_preview_mode;

/**
    @brief   Display frame type.
**/
typedef enum qll_preview_frame_type_e
{
    QLL_PREVIEW_FRAME_SHORT     = 0,    /**< The frame is short frame */
    QLL_PREVIEW_FRAME_SAFE      = 1,    /**< The frame is safe frame */
    QLL_PREVIEW_FRAME_LONG      = 2,    /**< The frame is long frame */
    QLL_PREVIEW_FRAME_MAX_SIZE          /**< For SW */
} qll_preview_frame_type;

/**
    @brief   Current camera module.
**/
typedef enum qll_camera_position_e
{
    qll_rear0, qll_rear1, qll_rear2, qll_rear3, qll_rear4,
    qll_back0, qll_back1, qll_back2, qll_back3, qll_back4,
    qll_camera_position_max_size
} qll_camera_position_t;

/**
    @brief   General buffer.
**/
typedef struct qll_buffer_s
{
    void*                   buffer;     /**< A pointer to the buffer */
    uint32_t                width;      /**< Buffer width, in samples */
    uint32_t                height;     /**< Buffer height, in samples */
    uint32_t                stride;     /**< Buffer stride, in bytes */
    uint32_t                vslice;     /**< Plane size for multi-plane, in bytes */
} qll_buffer_t;

/**
    @brief   Gyro sample.
**/
typedef struct qll_gyro_in_s
{
    float                   data[4];    /**< 0==x, 1==y, 2==z, 3==w */
    uint64_t                ts;         /**< Time stamp in nanoseconds */
} qll_gyro_in_t;

/**
    @brief   Gyro samples buffer.
**/
typedef struct qll_gyro_stream_in_s
{
    qll_gyro_in_t*          gyro;
    uint32_t                num_of_samples;
} qll_gyro_stream_in_t;

/**
    @brief   Display frame metadata.
**/
typedef struct qll_metadata_in_s
{
    void*                   tfi_data;                       /**< DC4 TFI buffer */
    qll_preview_frame_type  frame_type;                     /**< Short / safe / long frame */
    uint64_t                exposure_time;                  /**< Actual exposure time for current frame in nanoseconds */
    float                   gain;                           /**< Actual gain for current frame */
    uint8_t                 eva_auto_identity_detect_mode;  /**< The value of auto_identity_detect_mode populated by EVA (CVP) */
    uint16_t                eva_transform_conf;             /**< The transform confidence populated by EVA (CVP) */
    void*                   bhist;                          /**< Bhist buffer for current preview frame */
    uint64_t                ts_sof;                         /**< Start of frame in nanoseconds */
    uint64_t                request_id;                     /**< Metadata frame RequestID */
} qll_metadata_in_t;

/**
    @brief   AEC decision of last frame.
**/
typedef struct qll_aec_in_s
{
    float                   lux_idx;                    /**< AEC LUX index measurement */
    float                   gain_short;                 /**< AEC short gain decision */
    float                   gain_safe;                  /**< AEC safe gain decision */
    float                   gain_long;                  /**< AEC long gain decision */
    uint64_t                exposure_time_short;        /**< AEC short exposure time decision in nanoseconds */
    uint64_t                exposure_time_safe;         /**< AEC safe exposure time decision in nanoseconds */
    uint64_t                exposure_time_long;         /**< AEC long exposure time decision in nanoseconds */
    uint64_t                sensitivity_long_uncapped;  /**< AEC uncapped long sensitivity value */
    uint64_t                ts_sof;                     /**< Start of frame in nanoseconds */
    uint64_t                request_id;                 /**< AEC frame RequestID */
} qll_aec_in_t;

/**
    @brief   QLL decision on non ZSL frames capture.
**/
typedef struct qll_psl_out_s
{
    qll_mode                is_qll_mode;                                /**< QLL's decision for the mode of operation (ADRC or MFHDR) */
    uint16_t                long_frame_count;                           /**< QLL's decision for the number of long frames (PSL) to capture and process */
    bool                    long_adrc_manual_decision;                  /**< if true QLL provides DRC gain, TMC otherwise */
    float                   long_adrc_ratio;                            /**< The amount of DRC gain to apply, if manual chosen */
    uint64_t                max_long_exposure_time_ns;                  /**< Requested long frame (PSL) exposure time in nanoseconds */
    float                   long_gain;                                  /**< Requested long frame gain */
    float                   long_additinal_underexposure_gain_tmc;      /**< The additional gain that should be applied by TMC (with long_additinal_underexposure_gain_chgain) to reach original long sensitivity */
    float                   long_additinal_underexposure_gain_chgain;   /**< The additional gain that should be applied by channel gains (with long_additinal_underexposure_gain_tmc) to reach original long sensitivity */
    bool                    has_output;                                 /**< if true, a frame was processed. Otherwise, frame was not processed */
    uint64_t                request_id;                                 /**< QLL processed frame RequestID */
} qll_psl_out_t;

/**
    @brief   QLL decision on ZSL frames to be used and their order.
**/
typedef struct qll_zsl_out_s
{
    uint16_t                med_frame_count;                                        /**< QLL's decision for the number of medium frames to utilize. 0 Means ADRC only */
    uint64_t                med_buffer_request_id_for_mfnr[QLL_MAX_BUFFER_SIZE];    /**< The ReqestIDs for medium frames MFNR sorted by order */
    uint16_t                short_frame_count;                                      /**< QLL's decision for the number of short frames to utilize. Must be 0 if med_frame_count is 0 */
    uint64_t                short_buffer_request_id_for_mfnr[QLL_MAX_BUFFER_SIZE];  /**< The ReqestIDs for medium frames MFNR sorted by order */
} qll_zsl_out_t;

/**
    @brief   QLL initialization data.
**/
typedef struct qll_init_data_s
{
    uint32_t                tfi_width;              /**< DC4 TFI buffer width in pixels */
    uint32_t                tfi_height;             /**< DC4 TFI buffer height in pixels */
    uint32_t                tfi_stride;             /**< DC4 TFI buffer stride in bytes */
    uint32_t                sensor_mount_angle;     /**< Sensor mount angle (0, 90, 180, 270) */
    qll_camera_position_t   camera_position;        /**< Camera position (front, back, etc.) */
    uint16_t                frames_buffer_size;     /**< SW total buffer size in frames */
    float                   max_sensor_analog_gain; /**< Sensor's maximum analog gain */
    uint64_t                max_frame_exp_ns;       /**< Sensor driver exposure limitation in ns */
    qll_preview_mode        preview_mode;           /**< Preview mode of operation (standard, ADRC, MFHDR) */

} qll_init_data_t;

/**
    @brief   QLL input data for current frame.
**/
typedef struct qll_in_s
{
    QLL_Chromatix           qll_chromatix_data; /**< Chromatix struct for current frame */
    qll_gyro_stream_in_t    gyro_stream;        /**< Gyro samples buffer until current frame */
    qll_metadata_in_t       metadata;           /**< Metadata for current frame */
    qll_aec_in_t            aec_current;        /**< AEC decision for current frame */
    bool                    is_shutter_pressed; /**< True when shutter was pressed or PSL frames did not finish acquiring */
} qll_in_t;

/*****************************************************************************/
/*         QLL Algorithm data structures (ML part)                           */
/*****************************************************************************/

/**
    @brief   Standalone ML ISP instance input. It replaces the previous structs and drops the need for QLL context, according to sw request
**/
typedef struct qll_ml_in_standalone_s
{
    qll_buffer_t            input_frame;                                /**< ML input buffer */
    qll_buffer_t            tfi_aggregated;                             /**< TFI aggregated DC4 buffer */
    float                   gain;                                       /**< Actual gain for long frames */
    float                   white_balance[3];                           /**< The white balance applied to long frames {R, G, B} */
    float                   cct;                                        /**< Correlated Color Temperature */
    uint16_t                long_frame_count;                           /**< QLL's decision for the number of long frames (PSL) to capture and process */
    uint64_t                long_exposure_time_ns;                      /**< Long frame (PSL) exposure time in nanoseconds */
    float                   long_gain;                                  /**< Long frame gain */
    float                   long_additinal_underexposure_gain_chgain;   /**< The additional digital gain that was applied in channel gains */
    QLL_Chromatix           lib_chromatix;                              /**< QLL Chromatix tuning */
    uint64_t                request_id;                                 /**< QLL processed frame RequestID */
    uint32_t                log_flags;                                  /**< QLL dump flags */
} qll_ml_in_standalone_t;

/**
*   @brief  QLL handle type
**/
typedef void* qll_handle_t;

/**
*  @brief   Allocate memory for QLL and initialize the algorithm.
*
*  @param [in,out]    qll_handle      QLL handle.
*  @param [in]        init_data       Input data required to initialize the QLL algorithm.
*  @param [in]        log_flags       Flags for log dumps.
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_initialize(
    qll_handle_t*           qll_handle,
    const qll_init_data_t*  init_data,
    uint32_t                log_flags);

typedef int32_t (*qll_initialize_func_t)(
    qll_handle_t*           qll_handle,
    const qll_init_data_t*  init_data,
    uint32_t                log_flags);

/**
*  @brief   Reset memory for QLL.
*
*  @param [in,out]    qll_handle      QLL handle.
*  @param [in]        init_data       Input data required to initialize the QLL algorithm.
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_reset(
    qll_handle_t*           qll_handle,
    const qll_init_data_t*  init_data);

typedef int32_t (*qll_reset_func_t)(
    qll_handle_t*           qll_handle,
    const qll_init_data_t*  init_data);

/**
*  @brief    Update QLL data according to new ZSL input.
*
*  @param [in,out]  qll_handle      QLL handle.
*  @param [in]      qll_input       Input to QLL algorithm.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_update_stats(
    qll_handle_t    qll_handle,
    const qll_in_t* qll_input);

typedef int32_t (*qll_update_stats_func_t)(
    qll_handle_t    qll_handle,
    const qll_in_t* qll_input);

/**
*  @brief    Output the QLL decisions for capture.
*
*  @param [in,out]  qll_handle      QLL handle.
*  @param [out]     qll_output      Output of QLL algorithm.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_calc_capture_settings(
    qll_handle_t    qll_handle,
    qll_psl_out_t*  qll_output);

typedef int32_t (*qll_calc_capture_settings_func_t)(
    qll_handle_t    qll_handle,
    qll_psl_out_t*  qll_output);

/**
*  @brief    Output the QLL decisions for ZSL processing.
*
*  @param [in,out]  qll_handle      QLL handle.
*  @param [out]     qll_output      Output of QLL algorithm.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_get_zsl_frame_selection(
    qll_handle_t    qll_handle,
    qll_zsl_out_t*  qll_output);

typedef int32_t (*qll_get_zsl_frame_selection_func_t)(
    qll_handle_t    qll_handle,
    qll_zsl_out_t*  qll_output);

/**
*  @brief    Initialize ML QLL processing engine.
*
*  Prepare QLL ML engine for processing, must be called before first call to qll_ml_process().
*
*  @param [in]  ml_model_sel           Selects ML model weights by this identifier.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_ml_initialize(
    uint32_t ml_model_sel);

typedef int32_t (*qll_ml_initialize_func_t)(
    uint32_t ml_model_sel);

/**
*  @brief    Update QLL ML ISP stats according to current frame. Should be called after each MFNR blend frame.
*
*  @param [in]  tfi_frame_cur_in       TFI buffer of current MFNR blend-stage frame.
*  @param [in]  cur_frame_num_in       Current blend-stage frame number, out of the total MFNR frames, zero-based.
*  @param [in]  cur_dump_flags_in      QLL dump flags, 0x0 for no dumps.
*  @param [out] tfi_aggregated_out     Aggregated TFI output buffer.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_ml_update_stats(
    const qll_buffer_t* tfi_frame_cur_in,
    uint32_t            cur_frame_num_in,
    uint32_t            cur_dump_flags_in,
    qll_buffer_t*       tfi_aggregated_out);

typedef int32_t (*qll_ml_update_stats_func_t)(
    const qll_buffer_t* tfi_frame_cur_in,
    uint32_t            cur_frame_num_in,
    uint32_t            cur_dump_flags_in,
    qll_buffer_t*       tfi_aggregated_out);

/**
*  @brief    ML ISP noise processing of the post MFNR image.
*
*  @param [in]      qll_ml_input    Input of ML ISP.
*  @param [out]     qll_ml_output   Output of ML ISP.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_ml_process(
    const qll_ml_in_standalone_t*   qll_ml_input,
    qll_buffer_t*                   qll_ml_output);

typedef int32_t (*qll_ml_process_func_t)(
    const qll_ml_in_standalone_t*   qll_ml_input,
    qll_buffer_t*                   qll_ml_output);

/**
*  @brief    Abort ML QLL processing
*
*  Abort currently running ML QLL processing, if any. This call unblocks qll_ml_process() and
*  causes it to return QLL_RET_ML_ABORTED. Has no effect if no processing is currently in progress.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_ml_abort_processing();

typedef int32_t (*qll_ml_abort_processing_func_t)();

/**
*  @brief    De-initialize ML QLL processing engine.
*
*  Clean up and shut down QLL ML processing engine.
*
*  @return 0 in case of success, otherwise failed.
**/
QLL_VISIBILITY_PUBLIC int32_t qll_ml_deinitialize();

typedef int32_t (*qll_ml_deinitialize_func_t)();

/**
*  @brief    De-initializes the QLL algorithm context.
*
*  @param [in,out]  qll_handle     QLL handle.
*
**/
QLL_VISIBILITY_PUBLIC
int32_t qll_deinitialize(
    qll_handle_t*   qll_handle);

typedef int32_t (*qll_deinitialize_func_t)(
    qll_handle_t*   qll_handle);

#ifdef __cplusplus
}
#endif

#endif /* _QLL_INTERFACE_H_ */
