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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  chimcxcommon.h
/// @brief Header for common multicamera files
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CHIMCXCOMMON_H
#define CHIMCXCOMMON_H

#include <array>
#include <map>
#include <vector>

#include "chi.h"
#include "chivendortag.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Forward Declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct LogicalCameraInfo;

// NOWHINE FILE CP006:  Used standard libraries for performance improvements
// NOWHINE FILE CP007:  Templates used for unifying the common class implementations
// NOWHINE FILE CP003: Added operator overloading for structures that can be used as hash key
// NOWHINE FILE GR017: Used bool for function overloading to be used with STLs

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Enumeration representing the stream operation modes
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum ChiMcxSessionOperationMode : UINT64
{
    ChiMcxSessionOperationModeNormal             = (      0),   ///< Normal Mode
    ChiMcxSessionOperationModeConstaintHighSpeed = (1 <<  0),   ///< High Frame Rate Mode
    ChiMcxSessionOperationModeHDR                = (1 <<  1),   ///< Video HDR On
    ChiMcxSessionOperationModeEISNonCausal       = (1 <<  2),   ///< EIS v2 recording usecase.
    ChiMcxSessionOperationModeEISCausal          = (1 <<  3),   ///< EIS v3 recording usecase
    ChiMcxSessionOperationModeFOVC               = (1 <<  4),   ///< Field of View compensation
    ChiMcxSessionOperationModeFastShutter        = (1 <<  5),   ///< FastShutter mode
    ChiMcxSessionOperationModeSSM                = (1 <<  6),   ///< Super Slow Motion with FRC interpolation usecase
    ChiMcxSessionOperationModeHDR10Plus          = (1 <<  7),   ///< Operation mode for HDR10 plus
    ChiMcxSessionOperationModeBokeh              = (1 <<  8),   ///< Operation mode for Bokeh
    ChiMcxSessionOperationModeSmoothZoom         = (1 <<  9),   ///< Operation mode for Smooth Zoom
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constant Definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const CHAR* pBokehString              = "BokehMode";   ///< Bokeh mode string
static const CHAR* pBokehMasterString        = "BokehMaster"; ///< Bokeh master string
static const CHAR* pHardSwitchString         = "HardSwitch";  ///< Hard switch string
static const UINT  BokehMinActiveCameraCount = 2;             ///< Minimum number of active cameras for Bokeh

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the vendor tag of the camera tag or operation mode
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct ChiMcxSessionConfigMode
{
    ///< @brief Type to indicate if the configuration is driven by a vendor tag, camera tag or operation mode
    enum Type
    {
        SessionVendorTag,   ///< Vendor tag for session parameter
        SessionCameraTag,   ///< Standard camera tag
        OperationMode,      ///< Operation mode
    } type;

    union Data
    {
        struct SessionVendorTagInfo
        {
            const CHAR* pComponentName; ///< Name of component associated with the vendor tag base
            const CHAR* pTagName;       ///< The session vendor tag name
            UINT32      tagId;          ///< Session Vendor tag identifier
        } sessionVendorTag;

        UINT32 sessionCameraTag;   ///< Camera Tag Indentifier

        ChiMcxSessionOperationMode operationMode;      ///< Operation Mode
    } u;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the vendor tag of the camera tag or operation mode
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum class ChiMcxSynchronizationType
{
    ChiMcxSynchronizationTypeCalibrated,     ///< Hard-realtime synchronization
    ChiMcxSynchronizationTypeApproximated,   ///< Soft/Approximated synchronization
};

/// @brief Stream information
struct ChiMcxStreamInfoEntry
{
    FLOAT                           maxFps;           ///< Maximum fps for this entry
    ChiDimension                    maxDimension;     ///< Maximum dimension supported with this fps
    UINT                            streamIntentMask; ///< Mask of stream intents
    std::vector<ChiStreamFormat>    supportedFormats; ///< List of supported formats
};

/// @brief Logical Camera Session configuration per intent
struct ChiMcxSessionIntent
{
    std::vector<ChiMcxStreamInfoEntry> supportedStreamInfo; ///< List of supported stream information
    ChiDimension                       minDimension;        ///< Minimum dimension supported by this feature
};

/// @brief Array of logical camera session intents
typedef std::array<ChiMcxSessionIntent, CHI_STREAM_INTENT_MAX> ChiMcxSessionIntentArray;

/// @brief Map of available configurations per operationmode
typedef std::map<ChiMcxSessionOperationMode, ChiMcxSessionIntentArray>
    ChiAvailableOperationModeConfig;

/// @brief Array of logical camera pipeline names
typedef std::array<const CHAR*, MaxDevicePerLogicalCamera> ChiMcxPipelineNameArray;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the logical camera features
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct ChiMcxSessionDescriptor
{
    ChiMcxSessionConfigMode            configMode;                    ///< Configuration mode identifying the feature type
    UINT                               minActiveCameras;              ///< Minimum number of cameras that are active when
                                                                      ///  the feature is enabled
    UINT                               maxActiveCameras;              ///< Maximum number of cameras that are active when
                                                                      ///  the feature is enabled
    std::pair<FLOAT, FLOAT>            fpsRange;                      ///< FPS range supported by this feature
    std::pair<FLOAT, FLOAT>            zoomRange;                     ///< Zoom range for this feature is valid
    UINT                               usecaseTransitionTableId;      ///< Identifier for the default usecase transition table
    std::map<UINT, const CHAR*>        realTimePipelineNames;         ///< Pipeline names for each realtime pipeline
    UINT                               supportedStreamIntentMask;     ///< Supported stream intents
    ChiMcxSessionIntentArray           sessionIntentArray;            ///< Array of stream intent info
    ChiMcxPipelineNameArray            logicalRealtimePipelineNames;  ///< Pipeline names for each logical realtime pipeline
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the logical sensor modes
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct ChiMcxSensorMode
{
    UINT    physicalCameraIndex;        ///< Physical Camera index as per logical camera table
    UINT    physicalSensorSubModeIndex; ///< Physical sensor mode sub index. 0 is the main mode

    // Assignment operator overloading when logical sensor mode is used as a key
    // NOWHINE DC002a: Skipped documentation for trivial overload functions
    bool operator==(
        const ChiMcxSensorMode& rOther) const
    {
        return physicalCameraIndex == rOther.physicalCameraIndex &&
            physicalSensorSubModeIndex == rOther.physicalSensorSubModeIndex;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief  Structure defining the Hash function
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    struct ChiHashFunction
    {
        // Hash function
        // NOWHINE CP008: Overloaded () for using this class as hash function
        std::size_t operator()(
            const ChiMcxSensorMode& sensorMode) const
        {
            return sensorMode.physicalCameraIndex | (sensorMode.physicalSensorSubModeIndex << 16);
        }
    };
 };

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the point
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
struct Point
{
    T  x;   ///< X cordinate
    T  y;   ///< Y cordinate
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the rectangle
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
struct Rect
{
    T  left;     ///< x offset
    T  top;      ///< y offset
    T  width;    ///< width of the rectangle
    T  height;   ///< height of the rectangle

    ///< @brief Right offset of the rectangle
    T Right()
    {
        return left + width - static_cast<T>(1);
    }

    ///< @brief Bottom offset of the rectangle
    T Bottom()
    {
        return top + height - static_cast<T>(1);
    }
};

/// @brief Array of CHI dimension for physical cameras
typedef std::array<ChiDimension, MaxDevicePerLogicalCamera> ChiDimensionArray;

/// @brief Array of double rectangle for physical cameras
typedef std::array<Rect<DOUBLE>, MaxDevicePerLogicalCamera> ChiRectDArray;

/// @brief Array of floats for physical cameras
typedef std::array<FLOAT, MaxDevicePerLogicalCamera> ChiFloatArray;

/// @brief Map of logical sensor mode
typedef std::unordered_map<ChiMcxSensorMode, UINT, ChiMcxSensorMode::ChiHashFunction> ChiMcxSensorModeArray;

typedef std::array<UINT, MaxSensorModes>      SensorModeIndexMap;    ///< Map from sensor submode index to main mode

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the logical camera layout
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct ChiMcxLayoutDescriptor
{
    ChiRectDArray      relativeFOVs;        ///< Map from logical camera mode index to relative FOV
                                            ///< Logical camera FOV is from (0,0) - > (1, 1)
    ChiDimensionArray  activeArrays;        ///< Active array sizes for each logical mode.
                                            ///  For insensor mode, active array size should be
                                            ///  the cropped width w.r.t physical active array
    ChiFloatArray      adjFOVRatios;        ///< Adjusted FOV ratios relative to the primary camera
    ChiDimension       logicalActiveArray;  ///< Active array size of the logical camera
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Enumerations refering to bokeh mode
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum BokehMode
{
    BOKEHMODE_OFF,          ///< Bokeh Mode off
    BOKEHMODE_STILLCAPTURE, ///< Still Capture Bokeh
    BOKEHMODE_CONTINUOUS,   ///< Continuous Bokeh Mode
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Structure representing the multicamera usecase specific configurations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct ChiMcxUsecaseConfiguration
{
    UINT    swMasterCameraIndex;    ///< Default index of the software master camera
    UINT    activeCameraMask;       ///< Mask of all active cameras
    UINT    hwMasterCameraIndex;    ///< Default index of the hardware master camera
    BOOL    isHWSyncEnabled;        ///< Flag to indicate whether hardware sync is enabled
    BOOL    isCRMSyncEnabled;       ///< Flag to indicate whether CRM sync is enabled
    BOOL    isFPSSyncEnabled;       ///< Flag to indicate whether kernel sync is enabled
    BOOL    isPipelineSyncEnabled;  ///< Flag to indicate whether pipeline sync is enabled
    INT     reserved[9];            ///< Reserved for custom information
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Parameter for configuring the ChiMcxUsecaseExtension
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct ChiUsecaseExtensionInputParams
{
    LogicalCameraInfo* pLogicalCameraInfo;   ///< Logical camera info
    BokehMode          bokehMode;            ///< State of Bokeh mode
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  Configuration parameters used in usecase
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct ChiUsecaseExtensionOutputParams
{
    FLOAT margin;       ///< View margin used by IFE node.
};
#endif // CHIMCXCOMMON_H
