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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxjpegdmaconfig.h
/// @brief camxjpegdmaconfig class declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXJPEGDMACONFIG_H
#define CAMXJPEGDMACONFIG_H

#include "camxcmdbuffermanager.h"
#include "camxjpegutil.h"
#include "camxdefs.h"
#include "camxformats.h"
#include "camxhal3types.h"
#include "camxhwcontext.h"
#include "camxmem.h"
#include "camxpacketbuilder.h"
#include "camxtitan17xdefs.h"

CAMX_NAMESPACE_BEGIN

/// @brief JpegdmaBlockConfig
struct JpegdmaBlockConfig
{
    FLOAT  rangeEnd;      ///< Range end
    UINT32 blockWidth;    ///< Block width
    UINT32 blockWidthSel; ///< Block Width Selection
};

/// @brief JPEGEScaleConfig
struct JPEGDMAScaleConfig
{
    BOOL   bScaleEnabled; ///< Flag for scaling enable
    BOOL   bCropEnabled;  ///< Flag for crop enable
    UINT32 inputWidth;    ///< Input width total ( crop width + h offset)
    UINT32 inputHeight;   ///< Input height      (crop height + v offset)
    UINT32 outputWidth;   ///< Output width
    UINT32 outputHeight;  ///< Output height
    UINT32 hOffset;       ///< Horizontal offset
    UINT32 vOffset;       ///< Vertical offset
    UINT32 cropWidth;     ///< Cropped Width
    UINT32 cropHeight;    ///< Cropped Height
    UINT32 yStrideIn;     ///< Input stride luma
    UINT32 yScanlineIn;   ///< Input scanline luma
    UINT32 cStrideIn;     ///< Input stride chroma
    UINT32 cScanlineIn;   ///< Input scanline chroma
    UINT32 yStrideOut;    ///< Output stride luma
    UINT32 yScanlineOut;  ///< Output scanline chroma
};

/// @brief JpegdmaFEInputCfg
struct JpegdmaFEInputCfg
{
    UINT32 imageWidth;   ///< Image width
    UINT32 imageHeight;  ///< Image height

    UINT32 hPhase0Int;   ///< Horizontal phase step integer value
    UINT32 hPhase0Frac;  ///< Horizontal phase step fractional value
    UINT32 vPhase0Int;   ///< Vertical phase step integer value
    UINT32 vPhase0Frac;  ///< Vertical phase step fractional value

    UINT16 planeType;    ///< Plane type
    UINT32 stride;       ///< Buffer stride
    UINT32 scanline;     ///< Scanline
    UINT32 blockWidth;   ///< Block width
};

/// @brief JpegdmaWEOutputCfg
struct JpegdmaWEOutputCfg
{
    UINT32 outputWidth;   ///< Output width
    UINT32 outputHeight;  ///< Output height
    UINT16 blocksPerRow;  ///< Width of the final image in blocks
    UINT16 blocksPerCol;  ///< Height of the final image in blocks
    UINT32 stride;        ///< Buffer stride
    UINT32 scanline;      ///< Scanline
    UINT32 hStep;         ///< Horizontal step to increment or decrement write address per block
    UINT32 lastHStep;     ///< Horizontal step to increment or decrement write address for last block in a row
    UINT32 lastVStep;     ///< Vertical step to increment or decrement write address for last block in a column
};

/// @brief JpegdmaPPScaleCfg
struct JpegdmaPPScaleCfg
{
    UINT32    phaseHStep;  ///< Horizontal phase step
    UINT32    phaseVStep;  ///< Vertical phase step
    UINT8     scaleEnable; ///< Scale enable
};

/// @brief JPEGInputData
struct JPEGDMAInputData
{
    CmdBuffer*          pCmdBuffer0;            ///< Pointer to the Command Buffer Object
    CmdBuffer*          pCmdBuffer1;            ///< Pointer to the Command Buffer Object
    HwContext*          pHwContext;             ///< Pointer to the Hardware Context
    BYTE*               pInYBufAddr;            ///< Input plane 0 address
    BYTE*               pInCBCRBufAddr;         ///< Input plane 1 address
    BYTE*               pInPln2BufAddr;         ///< Input plane 2 address
    BYTE*               pOutYBufAddr;           ///< Output plane 0 address
    BYTE*               pOutCBCRBufAddr;        ///< Output plane 1 address
    BYTE*               pOutPln2BufAddr;        ///< Output plane 2 address
    UINT32              inYBufOffset;           ///< Input plane 0 offset
    UINT32              inCBCRBufOffset;        ///< Input plane 1 offset
    UINT32              inPLN2BufOffset;        ///< Input plane 2 offset
    UINT32              outYBufOffset;          ///< Output plane 0 offset
    UINT32              outCBCRBufOffset;       ///< Output plane 1 offset
    UINT32              outPLN2BufOffset;       ///< Output plane 2 offset
    ImageFormat         inFormat;               ///< Input image format
    ImageFormat         outFormat;              ///< Output image format
    JPEGDMAScaleConfig  scaleCropReq;           ///< Input scaling requested
    UINT32              numInputPlanes;         ///< Number of plames
    UINT32              cbcr_order;             ///< 0 cbcr, 1 crcb
    JPEGDMAScaleConfig  scaleConfig;            ///< Final scale config
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Class for JPEGDMAConfig
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class JPEGDMAConfig
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Create
    ///
    /// @brief  Create JPEG DMA config Object
    ///
    /// @param  ppJPEGDMAConfig  Pointer to the JPEGDMAConfig instance to be created
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CamxResult Create(
        JPEGDMAConfig** ppJPEGDMAConfig);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Execute
    ///
    /// @brief  Execute process capture request to configure module
    ///
    /// @param  pCmdBuffer0      Pointer to command buffer 0
    /// @param  pCmdBuffer1      Pointer to command buffer 1
    /// @param  pInputData       Pointer to the DMA input data
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult Execute(
        CmdBuffer*        pCmdBuffer0,
        CmdBuffer*        pCmdBuffer1,
        JPEGDMAInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateCropForOutAspectRatio
    ///
    /// @brief  Adjust crop info if cropped aspect ratio different from output aspect ratio
    ///
    /// @param  pScaleCropReq  pointer to src. dst and crop dimensions
    /// @param  bCropWidth     if we should adjust crop width or height
    ///
    /// @return CamxResultSuccess if successful and 0 dependencies, dependency information otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult UpdateCropForOutAspectRatio(
        JPEGDMAScaleConfig* pScaleCropReq,
        BOOL                bCropWidth);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Destroy
    ///
    /// @brief  Destroy the object
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_INLINE VOID Destroy()
    {
        CAMX_DELETE this;
    };

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~JPEGDMAConfig
    ///
    /// @brief  Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~JPEGDMAConfig();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// JPEGDMAConfig
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    explicit JPEGDMAConfig();

private:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateCmdConfigsFromInputData
    ///
    /// @brief  Update command config from input data
    ///
    /// @param  pInputData Pointer to the JPEG input data
    /// @param  pCmdBuffer Pointer to the cmd buffer to fill
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult UpdateCmdConfigsFromInputData(
        JPEGDMAInputData* pInputData,
        CmdBuffer*        pCmdBuffer);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// WriteRegRange
    ///
    /// @brief  Writes a command into the command buffer that, when executed, has the effect of writing a number of values at
    ///         the register address beginning with "reg".
    ///
    /// @param  pCmdBuffer  Address of the target command buffer
    /// @param  reg         Beginning of the register address range where values will be written
    /// @param  numVals     Number of values (registers) that will be written
    /// @param  pVals       An array of values that will be written
    ///
    /// @return CamxResult
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult WriteRegRange(
        CmdBuffer*  pCmdBuffer,
        UINT32      reg,
        UINT32      numVals,
        UINT32*     pVals);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMACoreCFG
    ///
    /// @brief  Fill core command config from input data
    ///
    /// @param  pInputData Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer Pointer to the cmd buffer to fill
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMACoreCFG(
        JPEGDMAInputData* pInputData,
        CmdBuffer*        pCmdBuffer);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMAFEConfig
    ///
    /// @brief  Fill fetch engine command config from input data
    ///
    /// @param  pInputData         Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer         Pointer to the cmd buffer to fill
    /// @param  pJPEGDMAFEInputCfg Pointer to the fetch engine input config
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMAFEConfig(
        JPEGDMAInputData*  pInputData,
        CmdBuffer*         pCmdBuffer,
        JpegdmaFEInputCfg* pJPEGDMAFEInputCfg);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMAFEBufConfig
    ///
    /// @brief  Fill fetch engine buffer command config from input data
    ///
    /// @param  pInputData         Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer         Pointer to the cmd buffer to fill
    /// @param  pJPEGDMAFEInputCfg Pointer to the fetch engine input config info
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMAFEBufConfig(
        JPEGDMAInputData*  pInputData,
        CmdBuffer*         pCmdBuffer,
        JpegdmaFEInputCfg* pJPEGDMAFEInputCfg);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMAWEConfig
    ///
    /// @brief  Fill write engine command config from input data
    ///
    /// @param  pInputData Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer Pointer to the cmd buffer to fill
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMAWEConfig(
        JPEGDMAInputData* pInputData,
        CmdBuffer*        pCmdBuffer);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMAWEBufConfig
    ///
    /// @brief  Fill write engine buffer command config from input data
    ///
    /// @param  pInputData   Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer   Pointer to the cmd buffer to fill
    /// @param  pWEOutputCfg Pointer to the write engine output config info
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMAWEBufConfig(
        JPEGDMAInputData*   pInputData,
        CmdBuffer*          pCmdBuffer,
        JpegdmaWEOutputCfg* pWEOutputCfg);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMAFEPingUpdate
    ///
    /// @brief  Fill fetch engine command config from input data
    ///
    /// @param  pInputData Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer Pointer to the cmd buffer to fill
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMAFEPingUpdate(
        JPEGDMAInputData* pInputData,
        CmdBuffer*        pCmdBuffer);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMAWEPingUpdate
    ///
    /// @brief  Fill write engine command config from input data
    ///
    /// @param  pInputData Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer Pointer to the cmd buffer to fill
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMAWEPingUpdate(
        JPEGDMAInputData* pInputData,
        CmdBuffer*        pCmdBuffer);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDMAScaleConfig
    ///
    /// @brief  Fill scale command config from input data
    ///
    /// @param  pInputData  Pointer to the JPEG DMA input data
    /// @param  pCmdBuffer  Pointer to the cmd buffer to fill
    /// @param  pPPScaleCfg Pointer to the scaling config info
    ///
    /// @return CamxResult Success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FillDMAScaleConfig(
        JPEGDMAInputData*  pInputData,
        CmdBuffer*         pCmdBuffer,
        JpegdmaPPScaleCfg* pPPScaleCfg);

    JPEGDMAConfig(const JPEGDMAConfig&)            = delete;        ///< Disallow the copy constructor
    JPEGDMAConfig& operator=(const JPEGDMAConfig&) = delete;        ///< Disallow assignment operator

    BOOL   m_moduleEnable;    ///< Flag to indicated if this module is enabled
    UINT32 m_curIdx;          ///< Command buffer index offset
    UINT16 m_curPlaneType;    ///< Plane type in process, y0, cb 1, cr 2, cbcr 3
};

CAMX_NAMESPACE_END

#endif // CAMXJPEGDMACONFIG_H
