/*
* Copyright (c) 2011-2017, 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     codechal_decode_mpeg2.cpp
//! \brief    Implements the decode interface extension for MPEG2.
//! \details  Implements all functions and constants required by CodecHal for MPEG2 decoding.
//!

#include "codechal_decoder.h"
#include "codechal_decode_mpeg2.h"
#include "codechal_secure_decode.h"
#include "codechal_mmc_decode_mpeg2.h"
#if USE_CODECHAL_DEBUG_TOOL
#include <sstream>
#include <fstream>
#include "codechal_debug.h"
#endif

#define CODECHAL_DECODE_MPEG2_IDCTBLOCK_SIZE   64

// One MB size (16x16) intra MB, color = RGB[4, 4, 4]
const uint32_t CODECHAL_DECODE_MPEG2_WaDummyBitstream[] =
{0x01010000, 0x54e29752, 0x002022a5, //Dummy Slice 0, q_scale_type = 0, intra_vlc_format = 0
 0x01010000, 0x4de29752, 0x8661341a, //Dummy Slice 1, q_scale_type = 0, intra_vlc_format = 1
 0x01010000, 0x54e2a772, 0x002022a5, //Dummy Slice 2, q_scale_type = 1, intra_vlc_format = 0
 0x01010000, 0x4de2a772, 0x8661341a  //Dummy Slice 3, q_scale_type = 1, intra_vlc_format = 1
};

const uint32_t CODECHAL_DECODE_MPEG2_WaDummySliceLengths[] = {0x8, 0x8, 0x8, 0x8};
const uint32_t CODECHAL_DECODE_MPEG2_WaDummySliceOffsets[] = {0x4, 0x10, 0x1c, 0x28};

bool CodechalDecodeMpeg2::DetectSliceError(
    uint16_t                        slcNum,
    uint32_t                        prevSliceMbEnd,
    bool                            firstValidSlice)
{
    bool                        result         = false;
    CODECHAL_VLD_SLICE_RECORD   currSliceRecord = m_vldSliceRecord[slcNum];

    if (currSliceRecord.dwLength == 0 || currSliceRecord.dwLength > (1 << (sizeof(uint32_t) * 8 - 1)))
    {
        result = true;
    }
    else if ((m_sliceParams[slcNum].m_sliceDataOffset + currSliceRecord.dwLength) >
             m_dataSize)
    {
        // error handling for garbage data
        result = true;
    }
    else if (m_slicesInvalid)
    {
        // If cp copy failed for this interation due to lack of buffer space, cannot use any
        // slices in this iteration since there is no bitstream data for them
        result = true;
    }
    else if (prevSliceMbEnd > currSliceRecord.dwSliceStartMbOffset ||
             m_sliceParams[slcNum].m_sliceVerticalPosition >= m_picHeightInMb ||
             m_sliceParams[slcNum].m_sliceHorizontalPosition >= m_picWidthInMb)
    {
        result = true;
        m_slicesInvalid = true;
    }
    else if (!m_sliceParams[slcNum].m_numMbsForSlice)
    {
        // For SNB HW will not process BSD objects where the MbCount is 0, and if an invalid
        // slice start position has been detected or the number of MBs in the current slice
        // is invalid, the rest of the data may be garbage since SNB does not have
        // robust error concealment for MPEG2 VLD, skipping these slices prevents HW hangs

        result = true;
        m_slicesInvalid = true;
    }
    else if (m_sliceParams[slcNum].m_numMbsForSliceOverflow)
    {
        // Special case for last slice of an incomplete frame
        if ((slcNum == m_numSlices - 1) &&
            !firstValidSlice &&
            ((currSliceRecord.dwSliceStartMbOffset + m_sliceParams[slcNum].m_numMbsForSlice) <
                (uint32_t)(m_picHeightInMb * m_picWidthInMb)))
        {
            m_sliceParams[slcNum].m_numMbsForSlice = m_picWidthInMb;
        }
        else
        {
            result = true;
            m_slicesInvalid = true;
        }
    }

    return result;
}

MOS_STATUS CodechalDecodeMpeg2::InsertDummySlices(
    PMHW_BATCH_BUFFER               batchBuffer,
    uint16_t                        startMB,
    uint16_t                        endMB)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
    bool      cpEnable = false;

    CODECHAL_DECODE_FUNCTION_ENTER;

    CODECHAL_DECODE_CHK_NULL_RETURN(batchBuffer);
    CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
    CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface->osCpInterface);

    //  A copied data buffer must be present
    if (m_nextCopiedDataOffset && !m_dummySliceDataPresent)
    {
        // slice header uses 4 bytes
        CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface(
            sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream),
            m_resMpeg2DummyBistream,
            &m_resCopiedDataBuffer[m_currCopiedData],
            &m_dummySliceDataOffset));

        m_dummySliceDataPresent = true;
    }

    // force disable cp for dummy slices
    cpEnable = m_osInterface->osCpInterface->IsCpEnabled();
    if (cpEnable)
    {
        m_osInterface->osCpInterface->SetCpEnabled(false);
    }

    uint16_t intraVLDFormat                = m_picParams->W0.m_intraVlcFormat;
    uint16_t quantizerScaleType            = m_picParams->W0.m_quantizerScaleType;
    uint16_t dummySliceIndex               = quantizerScaleType * 2 + intraVLDFormat;

    MHW_VDBOX_MPEG2_SLICE_STATE         mpeg2SliceState;
    mpeg2SliceState.presDataBuffer      = nullptr;
    mpeg2SliceState.wPicWidthInMb       = m_picWidthInMb;
    mpeg2SliceState.wPicHeightInMb      = m_picHeightInMb;
    mpeg2SliceState.dwLength            =
        CODECHAL_DECODE_MPEG2_WaDummySliceLengths[dummySliceIndex];
    mpeg2SliceState.dwOffset =
        m_dummySliceDataOffset + CODECHAL_DECODE_MPEG2_WaDummySliceOffsets[dummySliceIndex];

    bool isLastSlice                   = false;
    uint16_t expectedEndMB                 = m_picWidthInMb * m_picHeightInMb;

    CodecDecodeMpeg2SliceParams slc;
    MOS_ZeroMemory(&slc, sizeof(CodecDecodeMpeg2SliceParams));

    while (startMB < endMB)
    {
        slc.m_macroblockOffset           = 6;
        slc.m_sliceHorizontalPosition     = startMB % m_picWidthInMb;
        slc.m_sliceVerticalPosition       = startMB / m_picWidthInMb;
        slc.m_quantiserScaleCode        = 10;
        slc.m_numMbsForSlice              = 1;

        isLastSlice = ((startMB + 1) == expectedEndMB);

        mpeg2SliceState.pMpeg2SliceParams       = &slc;
        mpeg2SliceState.dwSliceStartMbOffset    = startMB;
        mpeg2SliceState.bLastSlice              = isLastSlice;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2BsdObject(
            nullptr,
            batchBuffer,
            &mpeg2SliceState));

        startMB++;
    }

    // restore Cp state
    if (cpEnable)
    {
        m_osInterface->osCpInterface->SetCpEnabled(true);
    }

    if (isLastSlice)
    {
        m_incompletePicture = false;
    }

    return eStatus;
}

MOS_STATUS CodechalDecodeMpeg2::CopyDataSurface(
    uint32_t                        dataSize,
    MOS_RESOURCE                    sourceSurface,
    PMOS_RESOURCE                   copiedSurface,
    uint32_t                        *currOffset)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    if (Mos_ResourceIsNull(copiedSurface))
    {
        // Allocate resCopiedDataBuffer if not already allocated.
        CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
                                                      copiedSurface,
                                                      m_copiedDataBufferSize,
                                                      "CopiedDataBuffer"),
            "Failed to allocate copied residual data buffer.");
    }

    // initialize lock flags
    MOS_LOCK_PARAMS lockFlagsWriteOnly;
    MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
    lockFlagsWriteOnly.WriteOnly = 1;

    uint32_t size = MOS_ALIGN_CEIL(dataSize, 16); // 16 byte aligned

    // HuC is not supported on BDW
    if (m_hwInterface->m_noHuC)
    {
        CodechalDataCopyParams dataCopyParams;
        MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
        dataCopyParams.srcResource = &sourceSurface;
        dataCopyParams.srcSize = size;
        dataCopyParams.srcOffset = 0;
        dataCopyParams.dstResource = copiedSurface;
        dataCopyParams.dstSize = size;
        dataCopyParams.dstOffset   = m_nextCopiedDataOffset;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(
            &dataCopyParams));

        *currOffset = m_nextCopiedDataOffset;
        m_nextCopiedDataOffset += MOS_ALIGN_CEIL(size, MHW_CACHELINE_SIZE);  // 64-byte aligned
        return MOS_STATUS_SUCCESS;
    }

    if ((m_nextCopiedDataOffset + dataSize) > m_copiedDataBufferSize)
    {
        CODECHAL_DECODE_ASSERTMESSAGE("Copied data buffer is not large enough.");

        m_slicesInvalid = true;
        return MOS_STATUS_UNKNOWN;
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
        m_osInterface,
        m_videoContextForWa));
    m_osInterface->pfnResetOsStates(m_osInterface);

    m_osInterface->pfnSetPerfTag(
        m_osInterface,
        (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
    m_osInterface->pfnResetPerfBufferID(m_osInterface);

    MOS_COMMAND_BUFFER cmdBuffer;
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
        m_osInterface,
        &cmdBuffer,
        0));

    CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
        &cmdBuffer,
        false));

    // Use huc stream out to do the copy
    CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
        &cmdBuffer,                // pCmdBuffer
        &sourceSurface,            // presSrc
        copiedSurface,             // presDst
        size,                      // u32CopyLength
        0,                         // u32CopyInputOffset
        m_nextCopiedDataOffset));  // u32CopyOutputOffset

    MHW_MI_FLUSH_DW_PARAMS flushDwParams;
    MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
        &cmdBuffer,
        &flushDwParams));

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
        &cmdBuffer,
        nullptr));

    m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);

    if (!m_incompletePicture)
    {
        MOS_SYNC_PARAMS syncParams      = g_cInitSyncParams;
        syncParams.GpuContext           = m_videoContext;
        syncParams.presSyncResource     = &m_resSyncObjectVideoContextInUse;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));

        syncParams                      = g_cInitSyncParams;
        syncParams.GpuContext           = m_videoContextForWa;
        syncParams.presSyncResource     = &m_resSyncObjectVideoContextInUse;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
        m_osInterface,
        &cmdBuffer,
        m_videoContextForWaUsesNullHw));

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
        m_osInterface,
        m_videoContext));

    *currOffset = m_nextCopiedDataOffset;
    m_nextCopiedDataOffset += MOS_ALIGN_CEIL(size, 64);  // offsets are 64-byte aligned

    return eStatus;
}

/*--------------------------------------------------------------------------
| Name      : CodecHalMpeg2Decode_InitializeBeginFrame
| Purpose   : Initialize MPEG2 incomplete frame values in the DecodeBeginFrame
| Arguments : IN -> pMpeg2State    : the pointer to mpeg2 state
IN -> pDecoder       : the pointer to codechal decoder structure
| Returns   : MOS_STATUS_SUCCESS : Function successfully completed its task
|             MOS_STATUS_UNKNOWN: Error condition encountered (frame will not be rendered)
\---------------------------------------------------------------------------*/
MOS_STATUS CodechalDecodeMpeg2::InitializeBeginFrame()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    m_incompletePicture  = false;
    m_copiedDataBufferInUse = false;
    m_copiedDataOffset      = 0;
    m_nextCopiedDataOffset  = 0;
    m_lastMbAddress         = 0;
    m_slicesInvalid         = false;

    m_currCopiedData =
        (m_currCopiedData + 1) % CODECHAL_DECODE_MPEG2_COPIED_SURFACES;
    m_dummySliceDataPresent = false;
    m_dummySliceDataOffset  = 0;
    m_bbInUsePerFrame       = 0;

    return eStatus;
}

MOS_STATUS CodechalDecodeMpeg2::AllocateResources ()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
        m_osInterface,
        &m_resSyncObjectWaContextInUse));
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
        m_osInterface,
        &m_resSyncObjectVideoContextInUse));

    CodecHalAllocateDataList(
        m_mpeg2RefList,
        CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2);

    for (uint32_t i = 0; i < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2; i++)
    {
        m_mpeg2RefList[i]->RefPic.PicFlags = PICTURE_INVALID;
    }

    uint32_t numMacroblocks = m_picWidthInMb * m_picHeightInMb;

    if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
    {
        m_vldSliceRecord =
            (PCODECHAL_VLD_SLICE_RECORD)MOS_AllocAndZeroMemory(numMacroblocks * sizeof(CODECHAL_VLD_SLICE_RECORD));
        CODECHAL_DECODE_CHK_NULL_RETURN(m_vldSliceRecord);
    }

    for (uint16_t i = 0; i < m_bbAllocated; i++)
    {
        MOS_ZeroMemory(&m_mediaObjectBatchBuffer[i], sizeof(MHW_BATCH_BUFFER));
        uint32_t size = (m_standardDecodeSizeNeeded * numMacroblocks) + m_hwInterface->m_sizeOfCmdBatchBufferEnd;
        CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
            m_osInterface,
            &m_mediaObjectBatchBuffer[i],
            nullptr,
            size));
    }

    // Deblocking Filter Row Store Scratch buffer
    //(Num MacroBlock Width) * (Num Cachlines) * (Cachline size)
    CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
                                                  &m_resMfdDeblockingFilterRowStoreScratchBuffer,
                                                  m_picWidthInMb * 7 * CODECHAL_CACHELINE_SIZE,
                                                  "DeblockingFilterScratch"),
        "Failed to allocate BSD/MPC Row Store Scratch Buffer.");

    // MPR Row Store Scratch buffer
    // (FrameWidth in MB) * (CacheLine size per MB) * 2
    // IVB+ platforms need to have double MPR size for MBAFF
    CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
                                                  &m_resBsdMpcRowStoreScratchBuffer,
                                                  ((uint32_t)(m_picWidthInMb * CODECHAL_CACHELINE_SIZE)) * 2,
                                                  "MprScratchBuffer"),
        "Failed to allocate AVC BSD MPR Row Store Scratch Buffer.");

    m_consecutiveMbErrorConcealmentInUse = true;

    // Dummy slice buffer
    if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
    {
        uint32_t size = MOS_ALIGN_CEIL(sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream), 64);
        CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
                                                      &m_resMpeg2DummyBistream,
                                                      size,
                                                      "Mpeg2DummyBitstream"),
            "Failed to allocate MPEG2 bitstream buffer for format switching WA.");

        CodechalResLock DummyBitstreamLock(m_osInterface, &m_resMpeg2DummyBistream);
        auto data = DummyBitstreamLock.Lock(CodechalResLock::writeOnly);
        
        CODECHAL_DECODE_CHK_NULL_RETURN(data);

        MOS_ZeroMemory(data, size);
        CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
            data,
            size,
            (void *)CODECHAL_DECODE_MPEG2_WaDummyBitstream,
            sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream)),
            "Failed to copy memory.");

    }

    if (m_mode == CODECHAL_DECODE_MODE_MPEG2IDCT)
    {
        // The common indirect IT-COEFF data structure is defined as a uint32_t.
        m_copiedDataBufferSize = (numMacroblocks + 2) *
                                 (CODEC_NUM_BLOCK_PER_MB * CODECHAL_DECODE_MPEG2_IDCTBLOCK_SIZE * sizeof(uint32_t));
    }
    else
    {
        // Bitstream buffer size = height * width + dummy slice + 512 (for padding)
        m_copiedDataBufferSize =
            (m_picWidthInMb * m_picHeightInMb * CODECHAL_DECODE_MPEG2_BYTES_PER_MB) +
            sizeof(CODECHAL_DECODE_MPEG2_WaDummyBitstream) +
            512;
    }

    return eStatus;
}

CodechalDecodeMpeg2::~CodechalDecodeMpeg2 ()
{
    CODECHAL_DECODE_FUNCTION_ENTER;

    CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);

    m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectWaContextInUse);
    m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectVideoContextInUse);

    CodecHalFreeDataList(m_mpeg2RefList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2);

    MOS_FreeMemory(m_vldSliceRecord);

    for (uint32_t i = 0; i < m_bbAllocated; i++)
    {
        Mhw_FreeBb(m_osInterface, &m_mediaObjectBatchBuffer[i], nullptr);
    }

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &m_resMfdDeblockingFilterRowStoreScratchBuffer);

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &m_resBsdMpcRowStoreScratchBuffer);

    // Dummy slice buffer
    if (!Mos_ResourceIsNull(&m_resMpeg2DummyBistream))
    {
        m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_resMpeg2DummyBistream);
    }

    for (uint32_t i = 0; i < CODECHAL_DECODE_MPEG2_COPIED_SURFACES; i++)
    {
        m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_resCopiedDataBuffer[i]);
    }
}

MOS_STATUS CodechalDecodeMpeg2::SetFrameStates ()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    uint32_t totalMBInFrame = 0;

    CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
    CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
    CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_picParams);

    m_dataSize                            = m_decodeParams.m_dataSize;
    m_dataOffset                          = m_decodeParams.m_dataOffset;
    m_numSlices                           = m_decodeParams.m_numSlices;
    m_picParams                           = (CodecDecodeMpeg2PicParams *)m_decodeParams.m_picParams;
    m_sliceParams                         = (CodecDecodeMpeg2SliceParams *)m_decodeParams.m_sliceParams;
    m_iqMatrixBuffer                      = (CodecMpeg2IqMatrix *)m_decodeParams.m_iqMatrixBuffer;
    m_destSurface                         = *m_decodeParams.m_destSurface;
    m_resDataBuffer                       = *m_decodeParams.m_dataBuffer;
    m_numMacroblocks                      = m_decodeParams.m_numMacroblocks;
    m_mbParams                            = (CodecDecodeMpeg2MbParmas *)m_decodeParams.m_macroblockParams;
    m_mpeg2ISliceConcealmentMode          = m_decodeParams.m_mpeg2ISliceConcealmentMode;
    m_mpeg2PbSliceConcealmentMode         = m_decodeParams.m_mpeg2PBSliceConcealmentMode;
    m_mpeg2PbSlicePredBiDirMvTypeOverride = m_decodeParams.m_mpeg2PBSlicePredBiDirMVTypeOverride;
    m_mpeg2PbSlicePredMvOverride          = m_decodeParams.m_mpeg2PBSlicePredMVOverride;

    m_picWidthInMb  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_picParams->m_horizontalSize);
    m_picHeightInMb = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_picParams->m_verticalSize);

    // For some corrupted mpeg2 streams, need to use dwHeight or dwWidth because they are updated at decode create time.
    // Horizontal_size or vertical_size may be different and wrong in first pic parameter.
    totalMBInFrame = (m_picParams->m_currPic.PicFlags == PICTURE_FRAME) ? (CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width) * CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height))
                                                                        : (CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width) * CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height) / 2);

    if (m_numSlices > totalMBInFrame)
    {
        CODECHAL_DECODE_ASSERTMESSAGE("Invalid slice number due to larger than MB number.");
        return MOS_STATUS_INVALID_PARAMETER;
    }

    PCODEC_REF_LIST destEntry = m_mpeg2RefList[m_picParams->m_currPic.FrameIdx];
    MOS_ZeroMemory(destEntry, sizeof(CODEC_REF_LIST));
    destEntry->RefPic    = m_picParams->m_currPic;
    destEntry->resRefPic = m_destSurface.OsResource;

    m_statusReportFeedbackNumber = m_picParams->m_statusReportFeedbackNumber;

    MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VLD_SLICE_RECORD)));

    if (m_firstExecuteCall)
    {
        CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(InitializeBeginFrame(),
            "Initial Beginframe in CodecHal failed.");
    }

    uint32_t    firstMbAddress       = 0;
    bool        skippedSlicePresent    = false;
    bool        invalidFrame           = true;
    uint32_t    numMBs               = 0;

    // Determine the number of MBs for MPEG2 VLD
    if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
    {
        CODECHAL_DECODE_CHK_NULL_RETURN(m_sliceParams);

        CodecDecodeMpeg2SliceParams *slc = m_sliceParams;

        if (m_numSlices == 0)
        {
            CODECHAL_DECODE_ASSERTMESSAGE(
                "MPEG2 VLD slice data invalid, unable to determine final MB address.");
            numMBs = m_lastMbAddress = 0;
            return MOS_STATUS_INVALID_PARAMETER;
        }
        else
        {
            uint16_t lastSlice       = 0;
            uint32_t prevSliceMbEnd        = m_lastMbAddress;
            bool firstValidSlice       = m_incompletePicture ? true : false;

            for (uint16_t i = 0; i < m_numSlices; i++)
            {
                uint32_t sliceStartMbOffset =
                    slc->m_sliceHorizontalPosition +
                    (slc->m_sliceVerticalPosition * m_picWidthInMb);

                uint32_t slcLength = ((slc->m_sliceDataSize + 0x0007) >> 3);

                // HW limitation and won't be fixed
                if (slcLength > 0x1FFE0)
                {
                    slcLength = 0x1FFE0;
                }

                uint32_t u32Offset = ((slc ->m_macroblockOffset & 0x0000fff8) >> 3); // #of bytes of header data in bitstream buffer (before video data)

                slcLength                            -= u32Offset;
                m_vldSliceRecord[i].dwLength             = slcLength;
                m_vldSliceRecord[i].dwOffset             = u32Offset;
                m_vldSliceRecord[i].dwSliceStartMbOffset = sliceStartMbOffset;

                if (DetectSliceError(i, prevSliceMbEnd, firstValidSlice))
                {
                    m_vldSliceRecord[i].dwSkip = true;
                    skippedSlicePresent        = true;
                }
                else
                {
                    if (firstValidSlice)
                    {
                        // First MB Address
                        firstMbAddress =
                            slc->m_sliceHorizontalPosition +
                            (slc->m_sliceVerticalPosition * m_picWidthInMb);
                    }

                    lastSlice = i;
                    firstValidSlice = false;
                    invalidFrame = false;
                }

                prevSliceMbEnd =
                    m_vldSliceRecord[i].dwSliceStartMbOffset +
                    slc->m_numMbsForSlice;

                slc++;
            }

            slc -= m_numSlices;
            m_vldSliceRecord[lastSlice].bIsLastSlice = true;

            // Last MB Address
            slc += lastSlice;

            numMBs =
                (uint16_t)(m_vldSliceRecord[lastSlice].dwSliceStartMbOffset +
                           slc->m_numMbsForSlice);
        }
    }
    else if (m_mode == CODECHAL_DECODE_MODE_MPEG2IDCT)
    {
        CODECHAL_DECODE_CHK_NULL_RETURN(m_mbParams);
        numMBs = m_numMacroblocks;
    }

    // It means all slices in the frame are wrong, we just need skip decoding for this frame
    // and don't insert any dummy slices
    if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD &&
        invalidFrame && m_numSlices && !m_incompletePicture)
    {
        CODECHAL_DECODE_ASSERTMESSAGE("Current frame is invalid.");
        return MOS_STATUS_UNKNOWN;
    }

    // MPEG2 Error Concealment for Gen6+
    // Applicable for both IT and VLD modes
    bool copiedDataNeeded = (m_incompletePicture ||
                             (numMBs != (m_picWidthInMb * m_picHeightInMb)));

    if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
    {
        copiedDataNeeded |= (skippedSlicePresent || firstMbAddress);
    }

    if (copiedDataNeeded)
    {
        if (m_dataSize)
        {
            CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface(
                m_dataSize,
                m_resDataBuffer,
                &m_resCopiedDataBuffer[m_currCopiedData],
                &m_copiedDataOffset));
        }

        m_copiedDataBufferInUse = true;
    }

    m_perfType = (uint16_t)m_picParams->m_pictureCodingType;

    m_crrPic      = m_picParams->m_currPic;
    m_secondField = m_picParams->m_secondField ? true : false;

    CODECHAL_DEBUG_TOOL(
        CODECHAL_DECODE_CHK_NULL_RETURN(m_debugInterface);
        m_debugInterface->m_currPic     = m_crrPic;
        m_debugInterface->m_secondField = m_secondField;
        m_debugInterface->m_frameType   = m_perfType;

        if (m_picParams) {
            CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams(
                m_picParams));
        }

        if (m_iqMatrixBuffer) {
            CODECHAL_DECODE_CHK_STATUS_RETURN(DumpIQParams(
                m_iqMatrixBuffer));
        }

        if (m_sliceParams) {
            CODECHAL_DECODE_CHK_STATUS_RETURN(DumpSliceParams(
                m_sliceParams,
                m_numSlices));
        }

        if (m_mbParams) {
            CODECHAL_DECODE_CHK_STATUS_RETURN(DumpMbParams(
                m_mbParams));
        }

    )

    return eStatus;
}

MOS_STATUS CodechalDecodeMpeg2::DecodeStateLevel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    uint8_t fwdRefIdx = (uint8_t)m_picParams->m_forwardRefIdx;
    uint8_t bwdRefIdx = (uint8_t)m_picParams->m_backwardRefIdx;

    // Do not use data that has not been initialized
    if (CodecHal_PictureIsInvalid(m_mpeg2RefList[fwdRefIdx]->RefPic))
    {
        fwdRefIdx = m_picParams->m_currPic.FrameIdx;
    }
    if (CodecHal_PictureIsInvalid(m_mpeg2RefList[bwdRefIdx]->RefPic))
    {
        bwdRefIdx = m_picParams->m_currPic.FrameIdx;
    }

    MOS_COMMAND_BUFFER cmdBuffer;
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));

    MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
    MOS_ZeroMemory(&pipeModeSelectParams, sizeof(pipeModeSelectParams));
    pipeModeSelectParams.Mode                  = m_mode;
    pipeModeSelectParams.bStreamOutEnabled     = m_streamOutEnabled;
    pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
    pipeModeSelectParams.bPreDeblockOutEnable  = !m_deblockingEnabled;

    MHW_VDBOX_SURFACE_PARAMS surfaceParams;
    MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
    surfaceParams.Mode                      = m_mode;
    surfaceParams.psSurface                 = &m_destSurface;

    MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
    MOS_ZeroMemory(&pipeBufAddrParams, sizeof(pipeBufAddrParams));
    pipeBufAddrParams.Mode                      = m_mode;
    if (m_deblockingEnabled)
    {
        pipeBufAddrParams.psPostDeblockSurface = &m_destSurface;
    }
    else
    {
        pipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));

    // when there is not a forward or backward reference,
    // the index is set to the destination frame index
    m_presReferences[CodechalDecodeFwdRefTop] =
        m_presReferences[CodechalDecodeFwdRefBottom] =
            m_presReferences[CodechalDecodeBwdRefTop] =
                m_presReferences[CodechalDecodeBwdRefBottom] = &m_destSurface.OsResource;

    if (fwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
    {
        m_presReferences[CodechalDecodeFwdRefTop] =
            m_presReferences[CodechalDecodeFwdRefBottom] = &m_mpeg2RefList[fwdRefIdx]->resRefPic;
    }
    if (bwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
    {
        m_presReferences[CodechalDecodeBwdRefTop] =
            m_presReferences[CodechalDecodeBwdRefBottom] = &m_mpeg2RefList[bwdRefIdx]->resRefPic;
    }

    // special case for second fields
    if (m_picParams->m_secondField && m_picParams->m_pictureCodingType == P_TYPE)
    {
        if (m_picParams->m_topFieldFirst)
        {
            m_presReferences[CodechalDecodeFwdRefTop] =
                &m_destSurface.OsResource;
        }
        else
        {
            m_presReferences[CodechalDecodeFwdRefBottom] =
                &m_destSurface.OsResource;
        }
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
        pipeBufAddrParams.presReferences,
        sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC,
        m_presReferences,
        sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC));

    pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
        &m_resMfdDeblockingFilterRowStoreScratchBuffer;

    if (m_streamOutEnabled)
    {
        pipeBufAddrParams.presStreamOutBuffer =
            &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));

    CODECHAL_DEBUG_TOOL(
        for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
        {
            if (pipeBufAddrParams.presReferences[i])
            {
                MOS_SURFACE dstSurface;

                MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
                dstSurface.Format     = Format_NV12;
                dstSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
                CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
                    m_osInterface,
                    &dstSurface));

                m_debugInterface->m_refIndex = (uint16_t)i;
                std::string refSurfName      = "RefSurf" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex));
                CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
                    &dstSurface,
                    CodechalDbgAttr::attrReferenceSurfaces,
                    refSurfName.data()));
            }
        }
    )

    //set correctly indirect BSD object base address.
    PMOS_RESOURCE indObjBase;
    if (m_copiedDataBufferInUse)
    {
        indObjBase = &m_resCopiedDataBuffer[m_currCopiedData];
    }
    else
    {
        indObjBase = &m_resDataBuffer;
    }

    MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
    MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
    indObjBaseAddrParams.Mode               = m_mode;
    indObjBaseAddrParams.dwDataSize =
        m_copiedDataBufferInUse ? m_copiedDataBufferSize : m_dataSize;
    indObjBaseAddrParams.presDataBuffer     = indObjBase;

    MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
    MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
    bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;

    MHW_VDBOX_MPEG2_PIC_STATE mpeg2PicState;
    mpeg2PicState.Mode                                  = m_mode;
    mpeg2PicState.pMpeg2PicParams                       = m_picParams;
    mpeg2PicState.bDeblockingEnabled                    = m_deblockingEnabled;
    mpeg2PicState.dwMPEG2ISliceConcealmentMode          = m_mpeg2ISliceConcealmentMode;
    mpeg2PicState.dwMPEG2PBSliceConcealmentMode         = m_mpeg2PbSliceConcealmentMode;
    mpeg2PicState.dwMPEG2PBSlicePredBiDirMVTypeOverride = m_mpeg2PbSlicePredBiDirMvTypeOverride;
    mpeg2PicState.dwMPEG2PBSlicePredMVOverride          = m_mpeg2PbSlicePredMvOverride;

    MHW_VDBOX_QM_PARAMS qmParams;
    qmParams.Standard                       = CODECHAL_MPEG2;
    qmParams.pMpeg2IqMatrix                 = m_iqMatrixBuffer;

    CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
        &cmdBuffer, true));

    if (m_statusQueryReportingEnabled)
    {
        CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(
            &cmdBuffer));
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(
        &cmdBuffer,
        &pipeModeSelectParams));

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(
        &cmdBuffer,
        &surfaceParams));

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(
        &cmdBuffer,
        &pipeBufAddrParams));

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(
        &cmdBuffer,
        &indObjBaseAddrParams));

    if (CodecHalIsDecodeModeVLD(m_mode))
    {
        CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(
            &cmdBuffer,
            &bspBufBaseAddrParams));
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxMpeg2PicCmd(
        &cmdBuffer,
        &mpeg2PicState));

    if (CodecHalIsDecodeModeVLD(m_mode))
    {
        CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(
            &cmdBuffer,
            &qmParams));
    }

    m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);

    return eStatus;
}

MOS_STATUS CodechalDecodeMpeg2::DecodePrimitiveLevel()
{
    if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD)
    {
        return SliceLevel();
    }
    else
    {
        return MacroblockLevel();
    }
}

MOS_STATUS CodechalDecodeMpeg2::SliceLevel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    if ((m_decodePhantomMbs) || (m_incompletePicture))
    {
        if (m_bbInUsePerFrame >= m_bbAllocated / CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP)
        {
            m_bbAllocated += CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP;
            if (m_bbAllocated >= CODECHAL_DECODE_MPEG2_MAXIMUM_BATCH_BUFFERS)
            {
                CODECHAL_DECODE_ASSERTMESSAGE(
                    "The number of MPEG2 second level batch buffer is not big enough to hold the whole frame.");
                return MOS_STATUS_EXCEED_MAX_BB_SIZE;
            }

            for (uint32_t i = 0; i < CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP; i++)
            {
                uint32_t j = m_bbAllocated - i - 1;
                MOS_ZeroMemory(&m_mediaObjectBatchBuffer[j], sizeof(MHW_BATCH_BUFFER));

                uint32_t u32Size = m_standardDecodeSizeNeeded * CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width) * CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height) +
                    m_hwInterface->m_sizeOfCmdBatchBufferEnd;

                CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
                    m_osInterface,
                    &m_mediaObjectBatchBuffer[j],
                    nullptr,
                    u32Size));
                m_mediaObjectBatchBuffer[j].bSecondLevel = true;
            }
        }
    }

    MOS_COMMAND_BUFFER cmdBuffer;
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
        m_osInterface,
        &cmdBuffer,
        0));

    MHW_BATCH_BUFFER batchBuffer = m_mediaObjectBatchBuffer[m_bbInUse];

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
        &cmdBuffer,
        &batchBuffer));

    CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(
        m_osInterface,
        &batchBuffer));

    if (m_decodePhantomMbs)
    {
        CODECHAL_DECODE_CHK_STATUS_RETURN(InsertDummySlices(
            &batchBuffer,
            m_lastMbAddress,
            m_picWidthInMb * m_picHeightInMb));
    }
    else
    {
        CodecDecodeMpeg2SliceParams *slc = m_sliceParams;

        uint16_t prevSliceMBEnd = m_lastMbAddress;

        for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++)
        {
            if (!m_vldSliceRecord[slcCount].dwSkip)
            {
                if (prevSliceMBEnd != m_vldSliceRecord[slcCount].dwSliceStartMbOffset)
                {
                    CODECHAL_DECODE_CHK_STATUS_RETURN(InsertDummySlices(
                        &batchBuffer,
                        prevSliceMBEnd,
                        (uint16_t)m_vldSliceRecord[slcCount].dwSliceStartMbOffset));
                }

                if (m_vldSliceRecord[slcCount].bIsLastSlice)
                {
                    uint16_t expectedFinalMb = m_picWidthInMb * m_picHeightInMb;

                    m_lastMbAddress =
                        (uint16_t)(m_vldSliceRecord[slcCount].dwSliceStartMbOffset +
                                   slc->m_numMbsForSlice);

                    if (m_lastMbAddress < expectedFinalMb)
                    {
                        m_incompletePicture              = true;
                        m_vldSliceRecord[slcCount].bIsLastSlice = false;
                    }
                    else
                    {
                        //Indicate It's complete picture now
                        m_incompletePicture              = false;
                    }
                }

                // static MPEG2 slice parameters
                MHW_VDBOX_MPEG2_SLICE_STATE mpeg2SliceState;
                mpeg2SliceState.presDataBuffer          = &m_resDataBuffer;
                mpeg2SliceState.wPicWidthInMb           = m_picWidthInMb;
                mpeg2SliceState.wPicHeightInMb          = m_picHeightInMb;
                mpeg2SliceState.pMpeg2SliceParams       = slc;
                mpeg2SliceState.dwLength                = m_vldSliceRecord[slcCount].dwLength;
                mpeg2SliceState.dwOffset =
                    m_vldSliceRecord[slcCount].dwOffset + m_copiedDataOffset;
                mpeg2SliceState.dwSliceStartMbOffset = m_vldSliceRecord[slcCount].dwSliceStartMbOffset;
                mpeg2SliceState.bLastSlice           = m_vldSliceRecord[slcCount].bIsLastSlice;

                CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2BsdObject(
                    nullptr,
                    &batchBuffer,
                    &mpeg2SliceState));

                prevSliceMBEnd =
                    (uint16_t)(m_vldSliceRecord[slcCount].dwSliceStartMbOffset +
                               slc->m_numMbsForSlice);
            }

            slc++;
        }
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
        nullptr,
        &batchBuffer));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
            &batchBuffer,
            CODECHAL_NUM_MEDIA_STATES,
            "_DEC"));
    )

    CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(
        m_osInterface,
        &batchBuffer,
        true));

    m_bbInUse = (m_bbInUse + 1) % m_bbAllocated;
    m_bbInUsePerFrame++;

    if (!m_incompletePicture)
    {
        // Check if destination surface needs to be synchronized
        MOS_SYNC_PARAMS syncParams          = g_cInitSyncParams;
        syncParams.GpuContext               = m_videoContext;
        syncParams.presSyncResource         = &m_destSurface.OsResource;
        syncParams.bReadOnly                = false;
        syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
        syncParams.bDisableLockForTranscode = m_disableLockForTranscode;

        if (!CodecHal_PictureIsField(m_picParams->m_currPic) ||
            !m_picParams->m_secondField)
        {
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
                m_osInterface,
                &syncParams));
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
                m_osInterface,
                &syncParams));

            // Update the resource tag (s/w tag) for On-Demand Sync
            m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
        }

        MHW_MI_FLUSH_DW_PARAMS flushDwParams;
        MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
            &cmdBuffer,
            &flushDwParams));

        // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
        if (m_osInterface->bTagResourceSync &&
            (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField))
        {
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
                &cmdBuffer,
                &syncParams));
        }

        if (m_statusQueryReportingEnabled)
        {
            CodechalDecodeStatusReport decodeStatusReport;

            decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
            decodeStatusReport.m_currDecodedPic     = m_picParams->m_currPic;
            decodeStatusReport.m_currDeblockedPic   = m_picParams->m_currPic;
            decodeStatusReport.m_codecStatus        = CODECHAL_STATUS_UNAVAILABLE;
            decodeStatusReport.m_currDecodedPicRes  = m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic;

            CODECHAL_DEBUG_TOOL(
                decodeStatusReport.m_secondField = m_picParams->m_secondField ? true : false;
                decodeStatusReport.m_frameType   = m_perfType;)

            CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
                decodeStatusReport,
                &cmdBuffer));
        }

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
            &cmdBuffer,
            nullptr));

        m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);

        CODECHAL_DEBUG_TOOL(
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
                &cmdBuffer,
                CODECHAL_NUM_MEDIA_STATES,
                "_DEC"));

            //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
            //    m_debugInterface,
            //    &cmdBuffer));
        )

        //Sync up complete frame
        syncParams                      = g_cInitSyncParams;
        syncParams.GpuContext           = m_videoContextForWa;
        syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));

        syncParams                      = g_cInitSyncParams;
        syncParams.GpuContext           = m_videoContext;
        syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
            m_osInterface,
            &cmdBuffer,
            m_videoContextUsesNullHw));

        CODECHAL_DEBUG_TOOL(
            m_mmc->UpdateUserFeatureKey(&m_destSurface);)

        if (m_statusQueryReportingEnabled)
        {
            CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
                m_videoContextUsesNullHw));
        }

        // Needs to be re-set for Linux buffer re-use scenarios
        m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic =
            m_destSurface.OsResource;

        // Send the signal to indicate decode completion, in case On-Demand Sync is not present
        if (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField)
        {
            syncParams                      = g_cInitSyncParams;
            syncParams.GpuContext           = m_videoContext;
            syncParams.presSyncResource     = &m_destSurface.OsResource;

            CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
        }
    }
    else
    {
        m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
    }

    return eStatus;
}

void CodechalDecodeMpeg2::PackMotionVectors(
    CODEC_PICTURE_FLAG          pic_flag,
    PMHW_VDBOX_MPEG2_MB_STATE   mpeg2MbState)
{
    CodecDecodeMpeg2MbParmas *mbParams = mpeg2MbState->pMBParams;

    uint16_t motionType     = mbParams->MBType.m_motionType;
    uint16_t intelMotionType = CODECHAL_MPEG2_IMT_NONE;

    //convert to Intel Motion Type
    if (pic_flag == PICTURE_FRAME)
    {
        switch(motionType)
        {
        case CodechalDecodeMcFrame:
            intelMotionType = CODECHAL_MPEG2_IMT_FRAME_FRAME;
            break;
        case CodechalDecodeMcField:
            intelMotionType = CODECHAL_MPEG2_IMT_FRAME_FIELD;
            break;
        case CodechalDecodeMcDmv:
            intelMotionType = CODECHAL_MPEG2_IMT_FRAME_DUAL_PRIME;
            break;
        default:
            break;
        }
    }
    else // must be field picture...
    {
        switch(motionType)
        {
        case CodechalDecodeMcField:
            intelMotionType = CODECHAL_MPEG2_IMT_FIELD_FIELD;
            break;
        case CodechalDecodeMcDmv:
            intelMotionType = CODECHAL_MPEG2_IMT_FIELD_DUAL_PRIME;
            break;
        case CodechalDecodeMc16x8:
            intelMotionType = CODECHAL_MPEG2_IMT_16X8;
            break;
        default:
            break;
        }
    }

    int16_t *mv = mbParams->m_motionVectors;

    switch (intelMotionType)
    {
    case CODECHAL_MPEG2_IMT_16X8:
    case CODECHAL_MPEG2_IMT_FIELD_FIELD:
    case CODECHAL_MPEG2_IMT_FRAME_FRAME:
    case CODECHAL_MPEG2_IMT_FIELD_DUAL_PRIME:
        mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
        mpeg2MbState->sPackedMVs0[1] = (short)mv[CodechalDecodeRstFirstForwVert];
        mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
        mpeg2MbState->sPackedMVs0[3] = (short)mv[CodechalDecodeRstFirstBackVert];
        break;

    case CODECHAL_MPEG2_IMT_FRAME_FIELD:
    case CODECHAL_MPEG2_IMT_FRAME_DUAL_PRIME:
        mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
        mpeg2MbState->sPackedMVs0[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1) ;
        mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
        mpeg2MbState->sPackedMVs0[3] = (short)(mv[CodechalDecodeRstFirstBackVert] >> 1);
        break;

    default:
        break;
    }

    switch (intelMotionType)
    {
    case CODECHAL_MPEG2_IMT_16X8:
        mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
        mpeg2MbState->sPackedMVs1[1] = (short)mv[CodechalDecodeRstSecndForwVert];
        mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
        mpeg2MbState->sPackedMVs1[3] = (short)mv[CodechalDecodeRstSecndBackVert];
        break;

    case CODECHAL_MPEG2_IMT_FRAME_DUAL_PRIME:
        mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
        mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1);
        mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
        mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
        break;

    case CODECHAL_MPEG2_IMT_FRAME_FIELD:
        mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
        mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstSecndForwVert] >> 1);
        mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
        mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
        break;

    default:
        break;
    }
}
MOS_STATUS CodechalDecodeMpeg2::InsertSkippedMacroblocks(
    PMHW_BATCH_BUFFER               batchBuffer,
    PMHW_VDBOX_MPEG2_MB_STATE       params,
    uint16_t                        nextMBStart,
    uint16_t                        skippedMBs)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    CODECHAL_DECODE_CHK_NULL_RETURN(batchBuffer);
    CODECHAL_DECODE_CHK_NULL_RETURN(params);
    CODECHAL_DECODE_CHK_NULL_RETURN(params->pMBParams);

    //save the original MB params, and restore the orignal MB params when function exit.
    CodechalDecodeRestoreData<CodecDecodeMpeg2MbParmas> MBParamsRestore(params->pMBParams);

    params->dwDCTLength                    = 0;
    params->dwITCoffDataAddrOffset         = 0;
    params->pMBParams->m_codedBlockPattern  = 0;

    MOS_ZeroMemory(params->sPackedMVs0,sizeof(params->sPackedMVs0));
    MOS_ZeroMemory(params->sPackedMVs1,sizeof(params->sPackedMVs1));

    for (uint16_t i = 0; i < skippedMBs; i++)
    {
        params->pMBParams->m_mbAddr = nextMBStart + i;
        CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2ITObject(
            nullptr,
            batchBuffer,
            params));
    }

    return eStatus;
}

MOS_STATUS CodechalDecodeMpeg2::MacroblockLevel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    if ((m_decodePhantomMbs) || (m_incompletePicture))
    {
        if (m_bbInUsePerFrame >= m_bbAllocated / CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP)
        {
            m_bbAllocated += CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP;
            if (m_bbAllocated >= CODECHAL_DECODE_MPEG2_MAXIMUM_BATCH_BUFFERS)
            {
                CODECHAL_DECODE_ASSERTMESSAGE(
                    "The number of MPEG2 second level batch buffer is not big enough to hold the whole frame.");
                return MOS_STATUS_EXCEED_MAX_BB_SIZE;
            }

            for (uint32_t i = 0; i < CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP; i++)
            {
                uint32_t j = m_bbAllocated - i - 1;
                MOS_ZeroMemory(&m_mediaObjectBatchBuffer[j], sizeof(MHW_BATCH_BUFFER));

                uint32_t u32Size = m_standardDecodeSizeNeeded * m_picWidthInMb * m_picHeightInMb +
                                   m_hwInterface->m_sizeOfCmdBatchBufferEnd;

                CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
                    m_osInterface,
                    &m_mediaObjectBatchBuffer[j],
                    nullptr,
                    u32Size));
                m_mediaObjectBatchBuffer[j].bSecondLevel = true;
            }
        }
    }

    MOS_COMMAND_BUFFER cmdBuffer;
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
        m_osInterface,
        &cmdBuffer,
        0));

    MHW_BATCH_BUFFER batchBuffer = m_mediaObjectBatchBuffer[m_bbInUse];

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
        &cmdBuffer,
        &batchBuffer));

    CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, &batchBuffer));

    //static member
    MHW_VDBOX_MPEG2_MB_STATE    mpeg2MbState;
    mpeg2MbState.wPicWidthInMb  = m_picWidthInMb;
    mpeg2MbState.wPicHeightInMb = m_picHeightInMb;
    mpeg2MbState.wPicCodingType = (uint16_t)m_picParams->m_pictureCodingType;

    if (m_decodePhantomMbs)
    {
        uint16_t u16NextMBStart = m_savedMpeg2MbParam.m_mbAddr + 1;  // = 1 + saved last MB's address in this picture.
        uint16_t numMBs      = (mpeg2MbState.wPicWidthInMb * mpeg2MbState.wPicHeightInMb) - u16NextMBStart;

        mpeg2MbState.pMBParams = &m_savedMpeg2MbParam;  //use saved last MB param to insert Skipped MBs.
        CODECHAL_DECODE_CHK_STATUS_RETURN(InsertSkippedMacroblocks(
            &batchBuffer,
            &mpeg2MbState,
            u16NextMBStart,
            numMBs));
        m_incompletePicture = false;
    }
    else
    {
        uint16_t expectedMBAddress = (m_incompletePicture) ? m_lastMbAddress : 0;

        for (uint16_t mbcount = 0; mbcount < m_numMacroblocks; mbcount++)
        {
            if (m_mbParams[mbcount].m_mbAddr >= expectedMBAddress)
            {
                uint16_t skippedMBs = m_mbParams[mbcount].m_mbAddr - expectedMBAddress;

                if (skippedMBs)
                {
                    //insert skipped Macroblock, use the first available MB params to insert skipped MBs.
                    mpeg2MbState.pMBParams = &(m_mbParams[mbcount]);
                    CODECHAL_DECODE_CHK_STATUS_RETURN(InsertSkippedMacroblocks(
                        &batchBuffer,
                        &mpeg2MbState,
                        expectedMBAddress,
                        skippedMBs));
                }
            }

            //common field for MBs in I picture and PB picture .
            mpeg2MbState.pMBParams   = &m_mbParams[mbcount];
            mpeg2MbState.dwDCTLength = 0;
            for (uint32_t i = 0; i < CODEC_NUM_BLOCK_PER_MB; i++)
            {
                mpeg2MbState.dwDCTLength += m_mbParams[mbcount].m_numCoeff[i];
            }

            mpeg2MbState.dwITCoffDataAddrOffset = m_copiedDataOffset + (m_mbParams[mbcount].m_mbDataLoc << 2);  // byte offset

            //only for MB in PB picture.
            if (mpeg2MbState.wPicCodingType != I_TYPE)
            {
                bool intraMB = mpeg2MbState.pMBParams->MBType.m_intraMb? true: false;

                MOS_ZeroMemory(mpeg2MbState.sPackedMVs0,sizeof(mpeg2MbState.sPackedMVs0));
                MOS_ZeroMemory(mpeg2MbState.sPackedMVs1,sizeof(mpeg2MbState.sPackedMVs1));
                if ((!intraMB) && (mpeg2MbState.pMBParams->MBType.m_value &
                    (CODECHAL_DECODE_MPEG2_MB_MOTION_BACKWARD | CODECHAL_DECODE_MPEG2_MB_MOTION_FORWARD)))
                {
                    PackMotionVectors(m_picParams->m_currPic.PicFlags, &mpeg2MbState);
                }
            }

            // add IT OBJECT command for each macroblock
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdMpeg2ITObject(
                nullptr,
                &batchBuffer,
                &mpeg2MbState));

            if (mpeg2MbState.wPicCodingType != I_TYPE && m_mbParams[mbcount].m_mbSkipFollowing)
            {
                uint16_t skippedMBs    = m_mbParams[mbcount].m_mbSkipFollowing;
                uint16_t skippedMBSart = m_mbParams[mbcount].m_mbAddr + 1;

                // Insert Skipped MBs
                CODECHAL_DECODE_CHK_STATUS_RETURN(InsertSkippedMacroblocks(
                    &batchBuffer,
                    &mpeg2MbState,
                    skippedMBSart,
                    skippedMBs));

                m_mbParams[mbcount].m_mbAddr += skippedMBs;
            }

            //save the last MB's parameters for later use to insert skipped MBs.
            m_savedMpeg2MbParam = m_mbParams[mbcount];

            expectedMBAddress = m_mbParams[mbcount].m_mbAddr + 1;

            // insert extra MBs to ensure expected number of MBs sent to HW
            if (mbcount + 1 == m_numMacroblocks)
            {
                uint16_t expectedFinalMB = m_picWidthInMb * m_picHeightInMb;

                if (expectedMBAddress != expectedFinalMB)
                {
                    m_incompletePicture = true;
                    m_lastMbAddress     = expectedMBAddress;
                }
                else
                {
                    m_incompletePicture = false;
                }
            }
        }
    }

    CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
        nullptr,
        &batchBuffer));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
            &batchBuffer,
            CODECHAL_NUM_MEDIA_STATES,
            "_DEC"));
    )

    CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, &batchBuffer, true));

    m_bbInUse = (m_bbInUse + 1) % m_bbAllocated;
    m_bbInUsePerFrame++;

    if (!m_incompletePicture)
    {
        // Check if destination surface needs to be synchronized
        MOS_SYNC_PARAMS syncParams          = g_cInitSyncParams;
        syncParams.GpuContext               = m_videoContext;
        syncParams.presSyncResource         = &m_destSurface.OsResource;
        syncParams.bReadOnly                = false;
        syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
        syncParams.bDisableLockForTranscode = m_disableLockForTranscode;

        if (!CodecHal_PictureIsField(m_picParams->m_currPic) ||
            !m_picParams->m_secondField)
        {
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
                m_osInterface,
                &syncParams));
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
                m_osInterface,
                &syncParams));

            // Update the resource tag (s/w tag) for On-Demand Sync
            m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
        }

        MHW_MI_FLUSH_DW_PARAMS flushDwParams;
        MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
            &cmdBuffer,
            &flushDwParams));

        // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
        if (m_osInterface->bTagResourceSync &&
            (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField))
        {
            CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
                &cmdBuffer,
                &syncParams));
        }

        if (m_statusQueryReportingEnabled)
        {
            CodechalDecodeStatusReport decodeStatusReport;

            decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
            decodeStatusReport.m_currDecodedPic     = m_picParams->m_currPic;
            decodeStatusReport.m_currDeblockedPic   = m_picParams->m_currPic;
            decodeStatusReport.m_codecStatus        = CODECHAL_STATUS_UNAVAILABLE;
            decodeStatusReport.m_currDecodedPicRes =
                m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic;

            CODECHAL_DEBUG_TOOL(
                decodeStatusReport.m_secondField = m_picParams->m_secondField ? true : false;
                decodeStatusReport.m_frameType   = m_perfType;)

            CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
                decodeStatusReport,
                &cmdBuffer));
        }

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
            &cmdBuffer,
            nullptr));

        m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);

        CODECHAL_DEBUG_TOOL(
        CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
            &cmdBuffer,
            CODECHAL_NUM_MEDIA_STATES,
            "_DEC"));

        //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
        //    m_debugInterface,
        //    &cmdBuffer));
        )

        //Sync up complete frame
        syncParams                      = g_cInitSyncParams;
        syncParams.GpuContext           = m_videoContextForWa;
        syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));

        syncParams                      = g_cInitSyncParams;
        syncParams.GpuContext           = m_videoContext;
        syncParams.presSyncResource     = &m_resSyncObjectWaContextInUse;

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));

        CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
            m_osInterface,
            &cmdBuffer,
            m_videoContextUsesNullHw));

        CODECHAL_DEBUG_TOOL(
            m_mmc->UpdateUserFeatureKey(&m_destSurface);)

        if (m_statusQueryReportingEnabled)
        {
            CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
                m_videoContextUsesNullHw));
        }

        // Needs to be re-set for Linux buffer re-use scenarios
        m_mpeg2RefList[m_picParams->m_currPic.FrameIdx]->resRefPic = m_destSurface.OsResource;

        // Send the signal to indicate decode completion, in case On-Demand Sync is not present
        if (!CodecHal_PictureIsField(m_picParams->m_currPic) || m_picParams->m_secondField)
        {
            syncParams                      = g_cInitSyncParams;
            syncParams.GpuContext           = m_videoContext;
            syncParams.presSyncResource     = &m_destSurface.OsResource;

            CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
        }
    }
    else
    {
        m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
    }

    return eStatus;
}

MOS_STATUS CodechalDecodeMpeg2::InitMmcState()
{
#ifdef _MMC_SUPPORTED
    m_mmc = MOS_New(CodechalMmcDecodeMpeg2, m_hwInterface, this);
    CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
#endif
    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalDecodeMpeg2::AllocateStandard (
    CodechalSetting *settings)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_DECODE_FUNCTION_ENTER;

    CODECHAL_DECODE_CHK_NULL_RETURN(settings);

    CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());

    m_width                         = settings->width;
    m_height                        = settings->height;
    m_picWidthInMb                  = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width);
    m_picHeightInMb                 = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height);
    m_bbAllocated                   = CODECHAL_DECODE_MPEG2_BATCH_BUFFERS_PER_GROUP;

    // Picture Level Commands
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetMfxStateCommandsDataSize(
        m_mode,
        &m_commandBufferSizeNeeded,
        &m_commandPatchListSizeNeeded,
        0));

    // Primitive Level Commands
    CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetMfxPrimitiveCommandsDataSize(
        m_mode,
        &m_standardDecodeSizeNeeded,
        &m_standardDecodePatchListSizeNeeded,
        0));

    CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResources());

    return eStatus;
}

CodechalDecodeMpeg2::CodechalDecodeMpeg2 (
    CodechalHwInterface   *hwInterface,
    CodechalDebugInterface* debugInterface,
    PCODECHAL_STANDARD_INFO standardInfo) :
    CodechalDecode(hwInterface, debugInterface, standardInfo)
{
    CODECHAL_DECODE_FUNCTION_ENTER;

    MOS_ZeroMemory(&m_destSurface, sizeof(m_destSurface));
    MOS_ZeroMemory(m_presReferences, sizeof(m_presReferences));
    MOS_ZeroMemory(&m_resDataBuffer, sizeof(m_resDataBuffer));
    MOS_ZeroMemory(&m_resMfdDeblockingFilterRowStoreScratchBuffer, sizeof(m_resMfdDeblockingFilterRowStoreScratchBuffer));
    MOS_ZeroMemory(&m_resBsdMpcRowStoreScratchBuffer, sizeof(m_resBsdMpcRowStoreScratchBuffer));
    MOS_ZeroMemory(m_mpeg2RefList, sizeof(m_mpeg2RefList));
    MOS_ZeroMemory(m_mediaObjectBatchBuffer, sizeof(m_mediaObjectBatchBuffer));
    MOS_ZeroMemory(&m_resMpeg2DummyBistream, sizeof(m_resMpeg2DummyBistream));
    MOS_ZeroMemory(m_resCopiedDataBuffer, sizeof(m_resCopiedDataBuffer));
    MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(m_resSyncObjectWaContextInUse));
    MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(m_resSyncObjectVideoContextInUse));
    MOS_ZeroMemory(&m_savedMpeg2MbParam, sizeof(m_savedMpeg2MbParam));
}

#if USE_CODECHAL_DEBUG_TOOL
MOS_STATUS CodechalDecodeMpeg2::DumpPicParams(
    CodecDecodeMpeg2PicParams *picParams)
{
    CODECHAL_DEBUG_FUNCTION_ENTER;

    if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
    {
        return MOS_STATUS_SUCCESS;
    }

    CODECHAL_DEBUG_CHK_NULL(picParams);

    std::ostringstream oss;
    oss.setf(std::ios::showbase | std::ios::uppercase);

    oss << "m_currPic FrameIdx: " << +picParams->m_currPic.FrameIdx << std::endl;
    oss << "m_currPic PicFlags: " << +picParams->m_currPic.PicFlags << std::endl;
    oss << "m_forwardRefIdx: " << +picParams->m_forwardRefIdx << std::endl;
    oss << "m_backwardRefIdx: " << +picParams->m_backwardRefIdx << std::endl;
    oss << "m_topFieldFirst: " << +picParams->m_topFieldFirst << std::endl;
    oss << "m_secondField: " << +picParams->m_secondField << std::endl;
    oss << "m_statusReportFeedbackNumber: " << +picParams->m_statusReportFeedbackNumber << std::endl;
    //Dump union w0
    oss << "w0 m_value: " << +picParams->W0.m_value << std::endl;
    oss << "m_scanOrder: " << +picParams->W0.m_scanOrder << std::endl;
    oss << "m_intraVlcFormat: " << +picParams->W0.m_intraVlcFormat << std::endl;
    oss << "m_quantizerScaleType: " << +picParams->W0.m_quantizerScaleType << std::endl;
    oss << "m_concealmentMVFlag: " << +picParams->W0.m_concealmentMVFlag << std::endl;
    oss << "m_frameDctPrediction: " << +picParams->W0.m_frameDctPrediction << std::endl;
    oss << "m_topFieldFirst: " << +picParams->W0.m_topFieldFirst << std::endl;
    oss << "m_intraDCPrecision: " << +picParams->W0.m_intraDCPrecision << std::endl;
    //Dump union w1
    oss << "w1 m_value: " << +picParams->W1.m_value << std::endl;
    oss << "m_fcode11: " << +picParams->W1.m_fcode11 << std::endl;
    oss << "m_fcode10: " << +picParams->W1.m_fcode10 << std::endl;
    oss << "m_fcode01: " << +picParams->W1.m_fcode01 << std::endl;
    oss << "m_fcode00: " << +picParams->W1.m_fcode00 << std::endl;
    oss << "m_horizontalSize: " << +picParams->m_horizontalSize << std::endl;
    oss << "m_verticalSize: " << +picParams->m_verticalSize << std::endl;
    oss << "m_pictureCodingType: " << +picParams->m_pictureCodingType << std::endl;

    const char *fileName = m_debugInterface->CreateFileName(
        "_DEC",
        CodechalDbgBufferType::bufPicParams,
        CodechalDbgExtType::txt);

    std::ofstream ofs(fileName, std::ios::out);
    ofs << oss.str();
    ofs.close();
    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalDecodeMpeg2::DumpSliceParams(
    CodecDecodeMpeg2SliceParams *sliceParams,
    uint32_t                     numSlices)
{
    CODECHAL_DEBUG_FUNCTION_ENTER;

    if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
    {
        return MOS_STATUS_SUCCESS;
    }

    CODECHAL_DEBUG_CHK_NULL(sliceParams);

    const char *fileName = m_debugInterface->CreateFileName(
        "_DEC",
        CodechalDbgBufferType::bufSlcParams,
        CodechalDbgExtType::txt);

    std::ostringstream oss;
    oss.setf(std::ios::showbase | std::ios::uppercase);

    CodecDecodeMpeg2SliceParams *sliceControl = nullptr;

    for (uint16_t i = 0; i < numSlices; i++)
    {
        sliceControl = &sliceParams[i];

        oss << "====================================================================================================" << std::endl;
        oss << "Data for Slice number = " << +i << std::endl;
        oss << "m_sliceDataSize: " << +sliceControl->m_sliceDataSize << std::endl;
        oss << "m_sliceDataOffset: " << +sliceControl->m_sliceDataOffset << std::endl;
        oss << "m_macroblockOffset: " << +sliceControl->m_macroblockOffset << std::endl;
        oss << "m_sliceHorizontalPosition: " << +sliceControl->m_sliceHorizontalPosition << std::endl;
        oss << "m_sliceVerticalPosition: " << +sliceControl->m_sliceVerticalPosition << std::endl;
        oss << "m_quantiserScaleCode: " << +sliceControl->m_quantiserScaleCode << std::endl;
        oss << "m_numMbsForSlice: " << +sliceControl->m_numMbsForSlice << std::endl;
        oss << "m_numMbsForSliceOverflow: " << +sliceControl->m_numMbsForSliceOverflow << std::endl;
        oss << "m_reservedBits: " << +sliceControl->m_reservedBits << std::endl;
        oss << "m_startCodeBitOffset: " << +sliceControl->m_startCodeBitOffset << std::endl;

        std::ofstream ofs;
        if (i == 0)
        {
            ofs.open(fileName, std::ios::out);
        }
        else
        {
            ofs.open(fileName, std::ios::app);
        }
        ofs << oss.str();
        ofs.close();
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalDecodeMpeg2::DumpIQParams(
    CodecMpeg2IqMatrix *matrixData)
{
    CODECHAL_DEBUG_FUNCTION_ENTER;

    if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
    {
        return MOS_STATUS_SUCCESS;
    }

    CODECHAL_DEBUG_CHK_NULL(matrixData);

    std::ostringstream oss;
    oss.setf(std::ios::showbase | std::ios::uppercase);

    if (matrixData->m_loadIntraQuantiserMatrix)
    {
        oss << "intra_QmatrixData:" << std::endl;

        for (uint8_t i = 0; i < 56; i += 8)
        {
            oss << "Qmatrix[" << +i / 8 << "]: ";
            for (uint8_t j = 0; j < 8; j++)
                oss << +matrixData->m_intraQuantiserMatrix[i + j] << " ";
            oss << std::endl;
        }
    }
    if (matrixData->m_loadNonIntraQuantiserMatrix)
    {
        oss << "non_intra_QmatrixData:" << std::endl;

        for (uint8_t i = 0; i < 56; i += 8)
        {
            oss << "Qmatrix[" << +i / 8 << "]: ";
            for (uint8_t j = 0; j < 8; j++)
                oss << +matrixData->m_nonIntraQuantiserMatrix[i + j] << " ";
            oss << std::endl;
        }
    }
    if (matrixData->m_loadChromaIntraQuantiserMatrix)
    {
        oss << "chroma_intra_QmatrixData:" << std::endl;

        for (uint8_t i = 0; i < 56; i += 8)
        {
            oss << "Qmatrix[" << +i / 8 << "]: ";
            for (uint8_t j = 0; j < 8; j++)
                oss << +matrixData->m_chromaIntraQuantiserMatrix[i + j] << " ";
            oss << std::endl;
        }
    }
    if (matrixData->m_loadChromaNonIntraQuantiserMatrix)
    {
        oss << "chroma_non_intra_QmatrixData:" << std::endl;

        for (uint8_t i = 0; i < 56; i += 8)
        {
            oss << "Qmatrix[" << +i / 8 << "]: ";
            for (uint8_t j = 0; j < 8; j++)
                oss << +matrixData->m_chromaNonIntraQuantiserMatrix[i + j] << " ";
            oss << std::endl;
        }
    }

    const char *fileName = m_debugInterface->CreateFileName(
        "_DEC",
        CodechalDbgBufferType::bufIqParams,
        CodechalDbgExtType::txt);

    std::ofstream ofs(fileName, std::ios::out);
    ofs << oss.str();
    ofs.close();

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalDecodeMpeg2::DumpMbParams(
    CodecDecodeMpeg2MbParmas *mbParams)
{
    CODECHAL_DEBUG_FUNCTION_ENTER;

    if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrMbParams))
    {
        return MOS_STATUS_SUCCESS;
    }

    CODECHAL_DEBUG_CHK_NULL(mbParams);

    std::ostringstream oss;
    oss.setf(std::ios::showbase | std::ios::uppercase);

    oss << "m_mbAddr: " << +mbParams->m_mbAddr << std::endl;
    //Dump union MBType
    oss << "MBType.m_intraMb: " << +mbParams->MBType.m_intraMb << std::endl;
    oss << "MBType.m_motionFwd: " << +mbParams->MBType.m_motionFwd << std::endl;
    oss << "MBType.m_motionBwd: " << +mbParams->MBType.m_motionBwd << std::endl;
    oss << "MBType.m_motion4mv: " << +mbParams->MBType.m_motion4mv << std::endl;
    oss << "MBType.m_h261Lpfilter: " << +mbParams->MBType.m_h261Lpfilter << std::endl;
    oss << "MBType.m_fieldResidual: " << +mbParams->MBType.m_fieldResidual << std::endl;
    oss << "MBType.m_mbScanMethod: " << +mbParams->MBType.m_mbScanMethod << std::endl;
    oss << "MBType.m_motionType: " << +mbParams->MBType.m_motionType << std::endl;
    oss << "MBType.m_hostResidualDiff: " << +mbParams->MBType.m_hostResidualDiff << std::endl;
    oss << "MBType.m_mvertFieldSel: " << +mbParams->MBType.m_mvertFieldSel << std::endl;
    oss << "m_mbSkipFollowing: " << +mbParams->m_mbSkipFollowing << std::endl;
    oss << "m_mbDataLoc: " << +mbParams->m_mbDataLoc << std::endl;
    oss << "m_codedBlockPattern: " << +mbParams->m_codedBlockPattern << std::endl;

    //Dump NumCoeff[CODEC_NUM_BLOCK_PER_MB]
    for (uint16_t i = 0; i < CODEC_NUM_BLOCK_PER_MB; ++i)
    {
        oss << "m_numCoeff[" << +i << "]: " << +mbParams->m_numCoeff[i] << std::endl;
    }

    //Dump motion_vectors[8],printing them in 4 value chunks per line
    for (uint8_t i = 0; i < 2; ++i)
    {
        oss << "m_motionVectors[" << +i * 4 << "-" << (+i * 4) + 3 << "]: ";
        for (uint8_t j = 0; j < 4; j++)
            oss << +mbParams->m_motionVectors[i * 4 + j] << " ";
        oss << std::endl;
    }

    const char *fileName = m_debugInterface->CreateFileName(
        "_DEC",
        CodechalDbgBufferType::bufMbParams,
        CodechalDbgExtType::txt);

    std::ofstream ofs(fileName, std::ios::out);
    ofs << oss.str();
    ofs.close();
    return MOS_STATUS_SUCCESS;
}

#endif
