/*
* Copyright (c) 2019-2022, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file     decode_hevc_picture_packet_xe_m_base.cpp
//! \brief    Defines the interface for hevc decode picture packet
//!
#include "codechal_utilities.h"
#include "decode_hevc_picture_packet_xe_m_base.h"
#include "decode_hevc_phase_real_tile.h"
#include "decode_hevc_phase_front_end.h"
#include "decode_hevc_phase_back_end.h"
#include "decode_common_feature_defs.h"
#include "decode_hevc_mem_compression.h"
#include "decode_resource_auto_lock.h"

namespace decode
{

HevcDecodePicPktXe_M_Base::~HevcDecodePicPktXe_M_Base()
{
    FreeResources();
}

MOS_STATUS HevcDecodePicPktXe_M_Base::FreeResources()
{
    DECODE_FUNC_CALL();

    if (m_allocator != nullptr)
    {
        m_allocator->Destroy(m_resMfdDeblockingFilterRowStoreScratchBuffer);
        m_allocator->Destroy(m_resMfdDeblockingFilterRowStoreScratchBuffer);
        m_allocator->Destroy(m_resDeblockingFilterTileRowStoreScratchBuffer);
        m_allocator->Destroy(m_resDeblockingFilterColumnRowStoreScratchBuffer);
        m_allocator->Destroy(m_resMetadataLineBuffer);
        m_allocator->Destroy(m_resMetadataTileLineBuffer);
        m_allocator->Destroy(m_resMetadataTileColumnBuffer);
        m_allocator->Destroy(m_resSaoLineBuffer);
        m_allocator->Destroy(m_resSaoTileLineBuffer);
        m_allocator->Destroy(m_resSaoTileColumnBuffer);
        m_allocator->Destroy(m_resSliceStateStreamOutBuffer);
        m_allocator->Destroy(m_resMvUpRightColStoreBuffer);
        m_allocator->Destroy(m_resIntraPredUpRightColStoreBuffer);
        m_allocator->Destroy(m_resIntraPredLeftReconColStoreBuffer);
        m_allocator->Destroy(m_resCABACSyntaxStreamOutBuffer);
        m_allocator->Destroy(m_resCABACStreamOutSizeBuffer);
#if MOS_EVENT_TRACE_DUMP_SUPPORTED
        m_allocator->Destroy(m_tempRefSurf);
#endif
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::Init()
{
    DECODE_FUNC_CALL();
    DECODE_CHK_NULL(m_featureManager);
    DECODE_CHK_NULL(m_hwInterface);
    DECODE_CHK_NULL(m_osInterface);
    DECODE_CHK_NULL(m_miInterface);
    DECODE_CHK_NULL(m_hevcPipeline);
    DECODE_CHK_NULL(m_hcpInterface);

    m_hevcBasicFeature = dynamic_cast<HevcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
    DECODE_CHK_NULL(m_hevcBasicFeature);

#ifdef _DECODE_PROCESSING_SUPPORTED
    m_downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
    DecodeSubPacket* subPacket = m_hevcPipeline->GetSubPacket(DecodePacketId(m_hevcPipeline, downSamplingSubPacketId));
    m_downSamplingPkt = dynamic_cast<DecodeDownSamplingPkt *>(subPacket);
#endif

    m_allocator = m_pipeline ->GetDecodeAllocator();
    DECODE_CHK_NULL(m_allocator);

    DECODE_CHK_STATUS(AllocateFixedResources());

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::Prepare()
{
    DECODE_FUNC_CALL();

    m_hevcPicParams      = m_hevcBasicFeature->m_hevcPicParams;
    m_hevcIqMatrixParams = m_hevcBasicFeature->m_hevcIqMatrixParams;
    m_hevcRextPicParams  = m_hevcBasicFeature->m_hevcRextPicParams;
    m_hevcSccPicParams   = m_hevcBasicFeature->m_hevcSccPicParams;

#ifdef _MMC_SUPPORTED
    m_mmcState = m_hevcPipeline->GetMmcState();
    DECODE_CHK_NULL(m_mmcState);
#endif

    DECODE_CHK_STATUS(SetRowstoreCachingOffsets());

    DECODE_CHK_STATUS(AllocateVariableResources());

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::SetPhase(DecodePhase *phase)
{
    DECODE_FUNC_CALL();
    m_phase = phase;
    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::ReportCabacStreamOutSize(MOS_COMMAND_BUFFER &cmdBuffer)
{
    DECODE_FUNC_CALL();
    DECODE_CHK_NULL(m_resCABACStreamOutSizeBuffer);

    auto mmioRegistersHcp = m_hwInterface->GetHcpInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1);

    MHW_MI_STORE_REGISTER_MEM_PARAMS params;
    MOS_ZeroMemory(&params, sizeof(MHW_MI_STORE_REGISTER_MEM_PARAMS));
    params.presStoreBuffer = &m_resCABACStreamOutSizeBuffer->OsResource;
    params.dwOffset        = 0;
    params.dwRegister      = mmioRegistersHcp->hcpDebugFEStreamOutSizeRegOffset;

    DECODE_CHK_STATUS(m_miInterface->AddMiStoreRegisterMemCmd(
        &cmdBuffer,
        &params));

    return MOS_STATUS_SUCCESS;
}

bool HevcDecodePicPktXe_M_Base::IsRealTilePhase()
{
    if (m_phase == nullptr)
    {
        return false;
    }
    HevcPhaseRealTile *realtilePhase = dynamic_cast<HevcPhaseRealTile *>(m_phase);
    return (realtilePhase != nullptr);
}

bool HevcDecodePicPktXe_M_Base::IsFrontEndPhase()
{
    if (m_phase == nullptr)
    {
        return false;
    }
    HevcPhaseFrontEnd *frontEndPhase = dynamic_cast<HevcPhaseFrontEnd *>(m_phase);
    return (frontEndPhase != nullptr);
}

bool HevcDecodePicPktXe_M_Base::IsBackEndPhase()
{
    if (m_phase == nullptr)
    {
        return false;
    }
    HevcPhaseBackEnd *backEndPhase = dynamic_cast<HevcPhaseBackEnd *>(m_phase);
    return (backEndPhase != nullptr);
}

MOS_STATUS HevcDecodePicPktXe_M_Base::SetRowstoreCachingOffsets()
{
    if (m_hcpInterface->IsRowStoreCachingSupported())
    {
        MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
        rowstoreParams.Mode             = CODECHAL_DECODE_MODE_HEVCVLD;
        rowstoreParams.dwPicWidth       = m_hevcBasicFeature->m_width;
        rowstoreParams.bMbaff           = false;
        rowstoreParams.ucBitDepthMinus8 = (uint8_t)MOS_MAX(m_hevcPicParams->bit_depth_luma_minus8,
                                                           m_hevcPicParams->bit_depth_chroma_minus8);
        rowstoreParams.ucChromaFormat   = m_hevcPicParams->chroma_format_idc;
        rowstoreParams.ucLCUSize        = (uint8_t)m_hevcBasicFeature->m_ctbSize;
        DECODE_CHK_STATUS(m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams));
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::AllocateFixedResources()
{
    DECODE_FUNC_CALL();

    if (m_resSliceStateStreamOutBuffer == nullptr)
    {
        uint32_t sizeOfBuffer = CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6 * sliceStateCachelinesPerSlice * CODECHAL_CACHELINE_SIZE;
        m_resSliceStateStreamOutBuffer = m_allocator->AllocateBuffer(
            sizeOfBuffer,
            "SliceStateStreamOut",
            resourceInternalReadWriteCache,
            notLockableVideoMem);
        DECODE_CHK_NULL(m_resSliceStateStreamOutBuffer);
    }

    if (m_resCABACStreamOutSizeBuffer == nullptr)
    {
        m_resCABACStreamOutSizeBuffer = m_allocator->AllocateBuffer(
            sizeof(uint64_t),
            "CABACStreamOutSizeBuffer",
            resourceInternalReadWriteCache,
            notLockableVideoMem);
        DECODE_CHK_NULL(m_resCABACStreamOutSizeBuffer);
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::AllocateVariableResources()
{
    DECODE_FUNC_CALL();

    MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam;
    MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam));
    hcpBufSizeParam.ucMaxBitDepth  = m_hevcBasicFeature->m_bitDepth;
    hcpBufSizeParam.ucChromaFormat = m_hevcBasicFeature->m_chromaFormat;
    hcpBufSizeParam.dwCtbLog2SizeY = m_hevcPicParams->log2_diff_max_min_luma_coding_block_size +
                                     m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3;
    hcpBufSizeParam.dwPicWidth     = m_hevcBasicFeature->m_width;
    hcpBufSizeParam.dwPicHeight    = m_hevcBasicFeature->m_height;
    hcpBufSizeParam.dwMaxFrameSize = m_hevcBasicFeature->m_dataSize;

    auto AllocateBuffer = [&] (PMOS_BUFFER &buffer, MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType, const char *bufferName)
    {
        DECODE_CHK_STATUS(m_hcpInterface->GetHevcBufferSize(bufferType, &hcpBufSizeParam));
        if (buffer == nullptr)
        {
            buffer = m_allocator->AllocateBuffer(
                hcpBufSizeParam.dwBufferSize, bufferName, resourceInternalReadWriteCache, notLockableVideoMem);
            DECODE_CHK_NULL(buffer);
        }
        else
        {
            DECODE_CHK_STATUS(m_allocator->Resize(
                buffer, hcpBufSizeParam.dwBufferSize, notLockableVideoMem));
        }
        return MOS_STATUS_SUCCESS;
    };

    if (!m_hcpInterface->IsHevcDfRowstoreCacheEnabled())
    {
        // Deblocking Filter Row Store Scratch buffer
        DECODE_CHK_STATUS(AllocateBuffer(
            m_resMfdDeblockingFilterRowStoreScratchBuffer,
            MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_LINE,
            "DeblockingScratchBuffer"));
    }

    // Deblocking Filter Tile Row Store Scratch data surface
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resDeblockingFilterTileRowStoreScratchBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_LINE,
        "DeblockingTileScratchBuffer"));

    // Deblocking Filter Column Row Store Scratch data surface
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resDeblockingFilterColumnRowStoreScratchBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_COL,
        "DeblockingColumnScratchBuffer"));

    if (!m_hcpInterface->IsHevcDatRowstoreCacheEnabled())
    {
        // Metadata Line buffer
        DECODE_CHK_STATUS(AllocateBuffer(
            m_resMetadataLineBuffer,
            MHW_VDBOX_HCP_INTERNAL_BUFFER_META_LINE,
            "MetadataLineBuffer"));
    }

    // Metadata Tile Line buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resMetadataTileLineBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_LINE,
        "MetadataTileLineBuffer"));

    // Metadata Tile Column buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resMetadataTileColumnBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_COL,
        "MetadataTileColumnBuffer"));

    if (!m_hcpInterface->IsHevcSaoRowstoreCacheEnabled())
    {
        // SAO Line buffer
        DECODE_CHK_STATUS(AllocateBuffer(
            m_resSaoLineBuffer,
            MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_LINE,
            "SaoLineBuffer"));
    }

    // SAO Tile Line buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resSaoTileLineBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_LINE,
        "SaoTileLineBuffer"));

    // SAO Tile Column buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resSaoTileColumnBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_COL,
        "SaoTileColumnBuffer"));

    // MV up right column store buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resMvUpRightColStoreBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_MV_UP_RT_COL,
        "MVUpperRightColumnStore"));

    // Intra prediction up right column store buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resIntraPredUpRightColStoreBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_UP_RIGHT_COL,
        "MVUpperRightColumnStore"));

    // Intra prediction left recon column store buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resIntraPredLeftReconColStoreBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_LFT_RECON_COL,
        "IntraPredLeftReconColumnStore"));

    // Cabac stream out buffer
    DECODE_CHK_STATUS(AllocateBuffer(
        m_resCABACSyntaxStreamOutBuffer,
        MHW_VDBOX_HCP_INTERNAL_BUFFER_CABAC_STREAMOUT,
        "CABACStreamOutBuffer"));

    return MOS_STATUS_SUCCESS;
}

void HevcDecodePicPktXe_M_Base::SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS& pipeModeSelectParams)
{
    DECODE_FUNC_CALL();

    pipeModeSelectParams.Mode = m_hevcBasicFeature->m_mode;
    pipeModeSelectParams.bStreamOutEnabled = false;
    pipeModeSelectParams.bShortFormatInUse = m_hevcPipeline->IsShortFormat();
}

MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpDstSurfaceParams(MHW_VDBOX_SURFACE_PARAMS& dstSurfaceParams)
{
    DECODE_FUNC_CALL();

    dstSurfaceParams.Mode                       = CODECHAL_DECODE_MODE_HEVCVLD;
    dstSurfaceParams.psSurface                  = &m_hevcBasicFeature->m_destSurface;
    dstSurfaceParams.ucSurfaceStateId           = CODECHAL_HCP_DECODED_SURFACE_ID;
    dstSurfaceParams.ChromaType                 = m_hevcPicParams->chroma_format_idc;
    dstSurfaceParams.ucBitDepthLumaMinus8       = m_hevcPicParams->bit_depth_luma_minus8;
    dstSurfaceParams.ucBitDepthChromaMinus8     = m_hevcPicParams->bit_depth_chroma_minus8;
    dstSurfaceParams.dwUVPlaneAlignment         = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);

#ifdef _MMC_SUPPORTED
    DECODE_CHK_STATUS(m_mmcState->SetSurfaceMmcState(dstSurfaceParams.psSurface));
    DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(dstSurfaceParams.psSurface, &dstSurfaceParams.mmcState));
    DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcFormat(dstSurfaceParams.psSurface, &dstSurfaceParams.dwCompressionFormat));
#endif

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpRefSurfaceParams(
    const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams, MHW_VDBOX_SURFACE_PARAMS& refSurfaceParams)
{
    DECODE_FUNC_CALL();

    refSurfaceParams.Mode                       = CODECHAL_DECODE_MODE_HEVCVLD;
    refSurfaceParams.psSurface                  = &m_hevcBasicFeature->m_destSurface; // For HEVC decode, reference should be same format as dest surface
    refSurfaceParams.ucSurfaceStateId           = CODECHAL_HCP_REF_SURFACE_ID;
    refSurfaceParams.ChromaType                 = m_hevcPicParams->chroma_format_idc;
    refSurfaceParams.ucBitDepthLumaMinus8       = m_hevcPicParams->bit_depth_luma_minus8;
    refSurfaceParams.ucBitDepthChromaMinus8     = m_hevcPicParams->bit_depth_chroma_minus8;
    refSurfaceParams.dwUVPlaneAlignment         = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);

#ifdef _MMC_SUPPORTED
    HevcDecodeMemComp *hevcDecodeMemComp = dynamic_cast<HevcDecodeMemComp *>(m_mmcState);
    DECODE_CHK_NULL(hevcDecodeMemComp);
    // Set refSurfaceParams mmcState as MOS_MEMCOMP_MC to satisfy MmcEnable in AddHcpSurfaceCmd
    // The actual mmcstate is recorded by refSurfaceParams.mmcSkipMask
    refSurfaceParams.mmcState = MOS_MEMCOMP_MC;
    DECODE_CHK_STATUS(hevcDecodeMemComp->SetRefSurfaceMask(*m_hevcBasicFeature, pipeBufAddrParams.presReferences, refSurfaceParams.mmcSkipMask));
    DECODE_CHK_STATUS(hevcDecodeMemComp->SetRefSurfaceCompressionFormat(*m_hevcBasicFeature, pipeBufAddrParams.presReferences, refSurfaceParams.dwCompressionFormat));
#endif

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpSurfaces(MOS_COMMAND_BUFFER &cmdBuffer, const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
{
    DECODE_FUNC_CALL();

    MHW_VDBOX_SURFACE_PARAMS dstSurfaceParams;
    MOS_ZeroMemory(&dstSurfaceParams, sizeof(dstSurfaceParams));
    DECODE_CHK_STATUS(SetHcpDstSurfaceParams(dstSurfaceParams));
    DECODE_CHK_STATUS(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &dstSurfaceParams));

    MHW_VDBOX_SURFACE_PARAMS refSurfaceParams;
    MOS_ZeroMemory(&refSurfaceParams, sizeof(refSurfaceParams));
    SetHcpRefSurfaceParams(pipeBufAddrParams, refSurfaceParams);
    DECODE_CHK_STATUS(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &refSurfaceParams));

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::FixHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
{
    if (m_hevcBasicFeature->m_refFrames.m_curIsIntra)
    {
        PMOS_RESOURCE dummyRef = &(m_hevcBasicFeature->m_dummyReference.OsResource);
        if (m_hevcBasicFeature->m_useDummyReference &&
            !m_allocator->ResourceIsNull(dummyRef))
        {
            // set all ref pic addresses to valid addresses for error concealment purpose
            for (uint32_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
            {
                if (pipeBufAddrParams.presReferences[i] == nullptr)
                {
                    pipeBufAddrParams.presReferences[i] = dummyRef;
                    m_hevcBasicFeature->m_dummyReferenceSlot[i] = true;
                }
            }
        }
    }
    else
    {
        PMOS_RESOURCE validRef = m_hevcBasicFeature->m_refFrames.GetValidReference();
        for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
        {
            // error concealment for the unset reference addresses and unset mv buffers
            if (pipeBufAddrParams.presReferences[i] == nullptr)
            {
                pipeBufAddrParams.presReferences[i] = validRef;
            }
        }

        PMOS_BUFFER validMvBuf = m_hevcBasicFeature->m_mvBuffers.GetValidBufferForReference(
                                    m_hevcBasicFeature->m_refFrameIndexList);
        for (uint32_t i = 0; i < CODEC_NUM_HEVC_MV_BUFFERS; i++)
        {
            if (pipeBufAddrParams.presColMvTempBuffer[i] == nullptr)
            {
                pipeBufAddrParams.presColMvTempBuffer[i] = &validMvBuf->OsResource;
            }
        }
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
{
    DECODE_FUNC_CALL();

    pipeBufAddrParams.Mode                  = m_hevcBasicFeature->m_mode;

    PMOS_SURFACE destSurface                = &(m_hevcBasicFeature->m_destSurface);
    pipeBufAddrParams.psPreDeblockSurface   = destSurface;

#ifdef _MMC_SUPPORTED
    DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(destSurface, &pipeBufAddrParams.PreDeblockSurfMmcState));
#endif

    pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
        &(m_resMfdDeblockingFilterRowStoreScratchBuffer->OsResource);
    pipeBufAddrParams.presDeblockingFilterTileRowStoreScratchBuffer =
        &(m_resDeblockingFilterTileRowStoreScratchBuffer->OsResource);
    pipeBufAddrParams.presDeblockingFilterColumnRowStoreScratchBuffer =
        &(m_resDeblockingFilterColumnRowStoreScratchBuffer->OsResource);

    pipeBufAddrParams.presMetadataLineBuffer       = &(m_resMetadataLineBuffer->OsResource);
    pipeBufAddrParams.presMetadataTileLineBuffer   = &(m_resMetadataTileLineBuffer->OsResource);
    pipeBufAddrParams.presMetadataTileColumnBuffer = &(m_resMetadataTileColumnBuffer->OsResource);
    pipeBufAddrParams.presSaoLineBuffer            = &(m_resSaoLineBuffer->OsResource);
    pipeBufAddrParams.presSaoTileLineBuffer        = &(m_resSaoTileLineBuffer->OsResource);
    pipeBufAddrParams.presSaoTileColumnBuffer      = &(m_resSaoTileColumnBuffer->OsResource);

    auto mvBuffers = &(m_hevcBasicFeature->m_mvBuffers);
    PMOS_BUFFER curMvBuffer = mvBuffers->GetCurBuffer();
    DECODE_CHK_NULL(curMvBuffer);
    pipeBufAddrParams.presCurMvTempBuffer = &(curMvBuffer->OsResource);

    HevcReferenceFrames &refFrames = m_hevcBasicFeature->m_refFrames;
    const std::vector<uint8_t> & activeRefList = refFrames.GetActiveReferenceList(*m_hevcPicParams);
    if (!refFrames.m_curIsIntra)
    {
        DECODE_ASSERT(activeRefList.size() <= 8);
        for (uint8_t i = 0; i < activeRefList.size(); i++)
        {
            uint8_t frameIdx = activeRefList[i];
            if (frameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC)
            {
                continue;
            }

            pipeBufAddrParams.presReferences[i] = refFrames.GetReferenceByFrameIndex(frameIdx);
            if (pipeBufAddrParams.presReferences[i] == nullptr)
            {
                PCODEC_REF_LIST curFrameInRefList = refFrames.m_refList[m_hevcPicParams->CurrPic.FrameIdx];
                DECODE_CHK_NULL(curFrameInRefList);
                MOS_ZeroMemory(&curFrameInRefList->resRefPic, sizeof(MOS_RESOURCE));
                DECODE_ASSERTMESSAGE("Reference frame for current Frame is not exist, current frame will be skipped. Thus, clear current frame resource in reference list.");
                return MOS_STATUS_INVALID_PARAMETER;
            }
            PMOS_BUFFER mvBuf = mvBuffers->GetBufferByFrameIndex(frameIdx);
            pipeBufAddrParams.presColMvTempBuffer[i] = mvBuf ? (&mvBuf->OsResource) : nullptr;

            // Return error if reference surface's pitch * height is less than dest surface.
            MOS_SURFACE refSurface;
            refSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
            DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&refSurface));
            DECODE_CHK_COND((refSurface.dwPitch * refSurface.dwHeight) < (destSurface->dwPitch * destSurface->dwHeight),
                            "Reference surface's pitch * height is less than Dest surface.");
        }
    }

    DECODE_CHK_STATUS(FixHcpPipeBufAddrParams(pipeBufAddrParams));

    if (m_hevcBasicFeature->m_isSCCIBCMode)
    {
        uint8_t IBCRefIdx = refFrames.m_IBCRefIdx;
        DECODE_CHK_COND(activeRefList.size() <= IBCRefIdx, "Invalid IBC reference index.");

        uint8_t refIdxMask = 0;
        for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
        {
            uint8_t IBCFrameIdx = activeRefList[IBCRefIdx];
            if (pipeBufAddrParams.presReferences[i] == refFrames.GetReferenceByFrameIndex(IBCFrameIdx))
            {
                refIdxMask |= (1 << i);
            }
        }
        pipeBufAddrParams.IBCRefIdxMask = refIdxMask;
    }

    CODECHAL_DEBUG_TOOL(
        CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
        DECODE_CHK_NULL(debugInterface);
        for (uint32_t n = 0; n < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; n++)
        {
            if (pipeBufAddrParams.presReferences[n] != nullptr)
            {
                MOS_SURFACE dstSurface;
                MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
                dstSurface.OsResource = *(pipeBufAddrParams.presReferences[n]);
                DECODE_CHK_STATUS(CodecHalGetResourceInfo(m_osInterface, &dstSurface));

                std::string refSurfDumpName = "RefSurf_" + std::to_string(n);
                DECODE_CHK_STATUS(debugInterface->DumpYUVSurface(
                    &dstSurface,
                    CodechalDbgAttr::attrReferenceSurfaces,
                    refSurfDumpName.c_str()));
            }

            if (pipeBufAddrParams.presColMvTempBuffer[n] != nullptr)
            {
                std::string mvBufDumpName = "_DEC_" + std::to_string(n);
                DECODE_CHK_STATUS(debugInterface->DumpBuffer(
                    pipeBufAddrParams.presColMvTempBuffer[n],
                    CodechalDbgAttr::attrMvData,
                    mvBufDumpName.c_str(),
                    curMvBuffer->size));
            }
        })

#if MOS_EVENT_TRACE_DUMP_SUPPORTED
    if (MOS_TraceKeyEnabled(TR_KEY_DECODE_MV))
    {
        TraceDataDumpMV(pipeBufAddrParams);
    }
    
    if (MOS_TraceKeyEnabled(TR_KEY_DECODE_REFYUV))
    {
        TraceDataDumpReferences(pipeBufAddrParams);
    }
#endif

    return MOS_STATUS_SUCCESS;
}

#if MOS_EVENT_TRACE_DUMP_SUPPORTED
MOS_STATUS HevcDecodePicPktXe_M_Base::TraceDataDumpMV(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
{
    auto        mvBuffers   = &(m_hevcBasicFeature->m_mvBuffers);
    PMOS_BUFFER curMvBuffer = mvBuffers->GetCurBuffer();
    DECODE_CHK_NULL(curMvBuffer);

    for (uint32_t n = 0; n < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; n++)
    {
        if (!m_allocator->ResourceIsNull(pipeBufAddrParams.presReferences[n]))
        {
            if (pipeBufAddrParams.presColMvTempBuffer[n] != nullptr)
            {
                ResourceAutoLock resLock(m_allocator, pipeBufAddrParams.presColMvTempBuffer[n]);
                auto             pData = (uint8_t *)resLock.LockResourceForRead();
                DECODE_CHK_NULL(pData);

                MOS_TraceDataDump(
                    "Decode_HevcColMvTempBuffer",
                    n,
                    pData,
                    curMvBuffer->size);
                
                m_allocator->UnLock(pipeBufAddrParams.presColMvTempBuffer[n]);
            }
        }
    }

    if (!m_allocator->ResourceIsNull(pipeBufAddrParams.presCurMvTempBuffer))
    {
        ResourceAutoLock resLock(m_allocator, pipeBufAddrParams.presCurMvTempBuffer);
        auto             pData = (uint8_t *)resLock.LockResourceForRead();
        DECODE_CHK_NULL(pData);

        MOS_TraceDataDump(
                    "Decode_HevcCurMvTempBuffer",
                    0,
                    pData,
                    curMvBuffer->size);
        
        m_allocator->UnLock(pipeBufAddrParams.presCurMvTempBuffer);
    }
    
    return MOS_STATUS_SUCCESS;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::TraceDataDumpReferences(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
{
    bool        bReport     = false;

    for (uint32_t n = 0; n < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; n++)
    {
        if (!m_allocator->ResourceIsNull(pipeBufAddrParams.presReferences[n]))
        {
            bool        bAllocate = false;
            MOS_SURFACE dstSurface;
            MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
            dstSurface.OsResource = *(pipeBufAddrParams.presReferences[n]);
            DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&dstSurface));

            if (!m_allocator->ResourceIsNull(&dstSurface.OsResource))
            {
                if (m_tempRefSurf == nullptr || m_allocator->ResourceIsNull(&m_tempRefSurf->OsResource))
                {
                    bAllocate = true;
                }
                else if (m_tempRefSurf->dwWidth < dstSurface.dwWidth ||
                         m_tempRefSurf->dwHeight < dstSurface.dwHeight)
                {
                    bAllocate = true;
                }
                else
                {
                    bAllocate = false;
                }

                if (bAllocate)
                {
                    if (!m_allocator->ResourceIsNull(&m_tempRefSurf->OsResource))
                    {
                        m_allocator->Destroy(m_tempRefSurf);
                    }

                    m_tempRefSurf = m_allocator->AllocateLinearSurface(
                        dstSurface.dwWidth,
                        dstSurface.dwHeight,
                        "Decode Ref Surf",
                        dstSurface.Format,
                        dstSurface.bIsCompressed,
                        resourceInputReference,
                        lockableSystemMem,
                        MOS_TILE_LINEAR_GMM);
                }

                DECODE_CHK_STATUS(m_osInterface->pfnDoubleBufferCopyResource(
                    m_osInterface,
                    &dstSurface.OsResource,
                    &m_tempRefSurf->OsResource,
                    false));

                if (!bReport)
                {
                    DECODE_EVENTDATA_YUV_SURFACE_INFO eventData =
                    {
                        PICTURE_FRAME,
                        0,
                        m_tempRefSurf->dwOffset,
                        m_tempRefSurf->YPlaneOffset.iYOffset,
                        m_tempRefSurf->dwPitch,
                        m_tempRefSurf->dwWidth,
                        m_tempRefSurf->dwHeight,
                        (uint32_t)m_tempRefSurf->Format,
                        m_tempRefSurf->UPlaneOffset.iLockSurfaceOffset,
                        m_tempRefSurf->VPlaneOffset.iLockSurfaceOffset,
                        m_tempRefSurf->UPlaneOffset.iSurfaceOffset,
                        m_tempRefSurf->VPlaneOffset.iSurfaceOffset,
                    };
                    MOS_TraceEvent(EVENT_DECODE_REF_DUMPINFO, EVENT_TYPE_INFO, &eventData, sizeof(eventData), NULL, 0);

                    bReport = true;
                }

                ResourceAutoLock resLock(m_allocator, &m_tempRefSurf->OsResource);
                auto             pData = (uint8_t *)resLock.LockResourceForRead();
                DECODE_CHK_NULL(pData);

                MOS_TraceDataDump(
                    "Decode_HEVCRefSurf",
                    n,
                    pData,
                    (uint32_t)m_tempRefSurf->OsResource.pGmmResInfo->GetSizeMainSurface());
                
                m_allocator->UnLock(&m_tempRefSurf->OsResource);
            }
        }
    }
    
    return MOS_STATUS_SUCCESS;
}
#endif

void HevcDecodePicPktXe_M_Base::SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams)
{
    DECODE_FUNC_CALL();

    indObjBaseAddrParams.Mode            = m_hevcBasicFeature->m_mode;
    indObjBaseAddrParams.dwDataSize      = m_hevcBasicFeature->m_dataSize;
    indObjBaseAddrParams.dwDataOffset    = m_hevcBasicFeature->m_dataOffset;
    indObjBaseAddrParams.presDataBuffer  = &(m_hevcBasicFeature->m_resDataBuffer.OsResource);
}

MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpIndObjBaseAddrCmd(MOS_COMMAND_BUFFER  &cmdBuffer)
{
    DECODE_FUNC_CALL();

    MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
    MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
    SetHcpIndObjBaseAddrParams(indObjBaseAddrParams);

    DECODE_CHK_STATUS(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
    return MOS_STATUS_SUCCESS;
}

void HevcDecodePicPktXe_M_Base::SetHcpQmStateParams(MHW_VDBOX_QM_PARAMS& qmParams)
{
    DECODE_FUNC_CALL();

    qmParams.Standard = CODECHAL_HEVC;
    qmParams.pHevcIqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams;
}

MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpQmStateCmd(MOS_COMMAND_BUFFER  &cmdBuffer)
{
    DECODE_FUNC_CALL();

    MHW_VDBOX_QM_PARAMS qmParams;
    MOS_ZeroMemory(&qmParams, sizeof(qmParams));
    SetHcpQmStateParams(qmParams);

    DECODE_CHK_STATUS(m_hcpInterface->AddHcpQmStateCmd(&cmdBuffer, &qmParams));
    return MOS_STATUS_SUCCESS;
}

void HevcDecodePicPktXe_M_Base::SetHcpPicStateParams(MHW_VDBOX_HEVC_PIC_STATE& picStateParams)
{
    DECODE_FUNC_CALL();
    picStateParams.pHevcPicParams = m_hevcPicParams;
}

void HevcDecodePicPktXe_M_Base::SetHcpTileStateParams(MHW_VDBOX_HEVC_TILE_STATE& tileStateParams)
{
    DECODE_FUNC_CALL();
    tileStateParams.pHevcPicParams = m_hevcPicParams;
    tileStateParams.pTileColWidth  = (uint16_t *)m_hevcBasicFeature->m_tileCoding.GetTileColWidth();
    tileStateParams.pTileRowHeight = (uint16_t *)m_hevcBasicFeature->m_tileCoding.GetTileRowHeight();
}

MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpTileStateCmd(MOS_COMMAND_BUFFER  &cmdBuffer)
{
    DECODE_FUNC_CALL();

    MHW_VDBOX_HEVC_TILE_STATE tileStateParams;
    MOS_ZeroMemory(&tileStateParams, sizeof(tileStateParams));
    SetHcpTileStateParams(tileStateParams);

    DECODE_CHK_STATUS(m_hcpInterface->AddHcpTileStateCmd(&cmdBuffer, &tileStateParams));
    return MOS_STATUS_SUCCESS;
}

}
