/*
* Copyright (c) 2016-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_encode_hevc.cpp
//! \brief    Defines base class for HEVC dual-pipe encoder.
//!

#include "codechal_encode_hevc.h"
#include "codechal_mmc_encode_hevc.h"

uint32_t CodechalEncHevcState::GetStartCodeOffset(uint8_t* addr, uint32_t size)
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    uint32_t count = 0;

    if (addr)
    {
        // count # 0 bytes before end of start code to determine header offset
        // (ie. 00 00 00 00 01 = 4)
        while (count < size && *addr != 0x01)
        {
            // Damage control if start code is non-existent or malformed
            // so header will still be a reasonable size
            if (*addr != 0)
                break;

            count++;
            addr++;
        }
    }

    return count + 1; // +1 to account for 01 byte
}

uint32_t CodechalEncHevcState::GetPicHdrSize()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    uint32_t firstHdrSz = 0;
    for(auto i = 0 ; i < HEVC_MAX_NAL_UNIT_TYPE ; i++)
    {
        if (m_nalUnitParams[i]->uiSize != 0)
        {
            firstHdrSz = m_nalUnitParams[i]->uiSize;
            break;
        }
    }

    uint8_t* hdrPtr = m_bsBuffer.pBase;
    // hdr offset = # 0's + 01 byte (start code) + offset over temporal ID and NAL type byte
    uint32_t hdrBegin = GetStartCodeOffset(hdrPtr, firstHdrSz) + HEVC_START_CODE_NAL_OFFSET;

    uint32_t accum = 0, numEmuBytes = 0;
    for(auto i = 0 ; i < HEVC_MAX_NAL_UNIT_TYPE ; i++)
    {
        if (m_nalUnitParams[i]->uiSize == 0)
            continue;
        uint32_t origSize = m_nalUnitParams[i]->uiSize;

        if (m_hevcPicParams->bEmulationByteInsertion)
        {
            hdrPtr = m_bsBuffer.pBase + accum;
            uint32_t hdrOffset = GetStartCodeOffset(hdrPtr, origSize);
            hdrPtr += hdrOffset;

            uint32_t zeroCount = 0;
            for (uint32_t j = 0 ; j < origSize - hdrOffset ; j++)
            {
                // Check if Emulation Prevention Byte needed for hex 00 00 00/00 00 01/00 00 02/00 00 03
                if (zeroCount == 2 && !(*hdrPtr & 0xFC))
                {
                    zeroCount = 0;
                    numEmuBytes++;   //increment by prevention byte
                }

                if (*hdrPtr == 0x00)
                {
                    zeroCount++;
                }
                else
                {
                    zeroCount = 0;
                }

                *hdrPtr++;
            }
        }

        accum += origSize;
    }

    // Add emulation bytes found
    accum += numEmuBytes;

    // Make sure that header size is valid or cap to provided hdr size
    hdrBegin = MOS_MIN(hdrBegin, accum);

    // Hdr size is in # bits
    return (accum - hdrBegin) * 8;
}

MOS_STATUS CodechalEncHevcState::ValidateRefFrameData(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(slcParams);

    uint8_t maxNumRef0 = 0;
    uint8_t maxNumRef1 = 0;

    GetMaxRefFrames(maxNumRef0, maxNumRef1);

    if (slcParams->num_ref_idx_l0_active_minus1 > maxNumRef0 - 1)
    {
        CODECHAL_ENCODE_ASSERT(false);
        slcParams->num_ref_idx_l0_active_minus1 = maxNumRef0 - 1;
    }

    if (slcParams->num_ref_idx_l1_active_minus1 > maxNumRef1 - 1)
    {
        CODECHAL_ENCODE_ASSERT(false);
        slcParams->num_ref_idx_l1_active_minus1 = maxNumRef1 - 1;
    }

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::SetSequenceStructs()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeHevcBase::SetSequenceStructs());

    m_cqpEnabled = (m_hevcSeqParams->RateControlMethod == RATECONTROL_CQP);

    if (m_hevcSeqParams->ParallelBRC == false)
    {
        m_brcBuffers.uiCurrBrcPakStasIdxForRead = m_brcBuffers.uiCurrBrcPakStasIdxForWrite = 0;
    }

    // check LCU size
    if (m_2xMeSupported &&
        m_hevcSeqParams->log2_max_coding_block_size_minus3 == 3)
    {
        // LCU64 support
        m_isMaxLcu64       = true;
        m_2xScalingEnabled = true;
    }
    else
    {
        if (m_hevcSeqParams->log2_max_coding_block_size_minus3 != 2)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Invalid LCU.");
            eStatus = MOS_STATUS_INVALID_PARAMETER;
            return eStatus;
        }

        m_isMaxLcu64       = false;
        m_2xScalingEnabled = false;
    }

    // allocate resources only needed in LCU64 kernel
    if (m_firstFrame && m_isMaxLcu64)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateEncResourcesLCU64());
    }

    if (m_hevcSeqParams->FrameRate.Denominator == 0)
    {
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        CODECHAL_ENCODE_ASSERTMESSAGE("FrameRate Denominator can not be zero.");
        return eStatus;
    }
    uint8_t framerate = m_hevcSeqParams->FrameRate.Numerator / m_hevcSeqParams->FrameRate.Denominator;

    m_slidingWindowSize = MOS_MIN(framerate, 60);

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::SetPictureStructs()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeHevcBase::SetPictureStructs());

    // do not support interlaced coding now
    if (CodecHal_PictureIsField(m_currOriginalPic))
    {
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        return eStatus;
    }

        // Set min/max QP values based on frame type if atleast one of them is non-zero
    if (m_hevcPicParams->BRCMinQp || m_hevcPicParams->BRCMaxQp)
    {
        m_minMaxQpControlEnabled = true;
        if (m_hevcPicParams->CodingType == I_TYPE)
        {
            m_maxQpForI = MOS_MIN(MOS_MAX(m_hevcPicParams->BRCMaxQp, 1), 51);           // Clamp to the max QP to [1, 51] . Zero is not used by our Kernel.
            m_minQpForI = MOS_MIN(MOS_MAX(m_hevcPicParams->BRCMinQp, 1), m_maxQpForI);  // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
            if (!m_minMaxQpControlForP)
            {
                m_minQpForP = m_minQpForI;
                m_maxQpForP = m_maxQpForI;
            }
            if (!m_minMaxQpControlForB)
            {
                m_minQpForB = m_minQpForI;
                m_maxQpForB = m_maxQpForI;
            }
        }
        else if (m_hevcPicParams->CodingType == P_TYPE)
        {
            m_minMaxQpControlForP = true;
            m_maxQpForP           = MOS_MIN(MOS_MAX(m_hevcPicParams->BRCMaxQp, 1), 51);           // Clamp to the max QP to [1, 51]. Zero is not used by our Kernel.
            m_minQpForP           = MOS_MIN(MOS_MAX(m_hevcPicParams->BRCMinQp, 1), m_maxQpForP);  // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
            if (!m_minMaxQpControlForB)
            {
                m_minQpForB = m_minQpForP;
                m_maxQpForB = m_maxQpForP;
            }
        }
        else if (m_hevcPicParams->CodingType == B_TYPE)
        {
            m_minMaxQpControlForB = true;
            m_maxQpForB           = MOS_MIN(MOS_MAX(m_hevcPicParams->BRCMaxQp, 1), 51);           // Clamp to the max QP to [1, 51]. Zero is not used by our Kernel.
            m_minQpForB           = MOS_MIN(MOS_MAX(m_hevcPicParams->BRCMinQp, 1), m_maxQpForB);  // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
        }
    }

    // CQP with Fast Surveillance [Distortion Surface needs to be allocated]
    if (m_brcEnabled || m_hevcSeqParams->bVideoSurveillance || m_cqpEnabled)
    {
        m_brcDistortion = (m_pictureCodingType == I_TYPE) ? &m_brcBuffers.sBrcIntraDistortionBuffer : &m_brcBuffers.sMeBrcDistortionBuffer;
    }

    if (m_brcEnabled)
    {
        // For ICQ mode or when min/max QP used, ignore BRCPrecision sent by the app and set the number of passes internally
        if ((m_hevcSeqParams->RateControlMethod == RATECONTROL_ICQ) || (m_minMaxQpControlEnabled))
        {
            m_numPasses = 0;  // no IPCM for HEVC
        }
        else
        {
            m_numPasses = (uint8_t)(m_mfxInterface->GetBrcNumPakPasses() - 1);  // 1 original plus extra to handle BRC
        }
    }
    else
    {
        m_numPasses = 0;  // no IPCM for HEVC
    }

    //add for FEI multiple Pass Pak
    if (CodecHalIsFeiEncode(m_codecFunction))
    {
        CODECHAL_ENCODE_CHK_NULL_RETURN(m_hevcFeiPicParams);
        if (m_hevcFeiPicParams->dwMaxFrameSize != 0)
        {
            m_numPasses = (uint8_t)m_hevcFeiPicParams->dwNumPasses;
        }
    }

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::SetSliceStructs()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeHevcBase::SetSliceStructs());

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::ReadBrcPakStats(
    PMOS_COMMAND_BUFFER cmdBuffer)
{
    MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    uint32_t offset = (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
        m_encodeStatusBuf.dwNumPassesOffset +   // Num passes offset
        sizeof(uint32_t)* 2;                               // pEncodeStatus is offset by 2 DWs in the resource

    EncodeReadBrcPakStatsParams   readBrcPakStatsParams;
    readBrcPakStatsParams.pHwInterface               = m_hwInterface;
    readBrcPakStatsParams.presBrcPakStatisticBuffer  = &m_brcBuffers.resBrcPakStatisticBuffer[m_brcBuffers.uiCurrBrcPakStasIdxForWrite];
    readBrcPakStatsParams.presStatusBuffer           = &m_encodeStatusBuf.resStatusBuffer;
    readBrcPakStatsParams.dwStatusBufNumPassesOffset = offset;
    readBrcPakStatsParams.ucPass                     = (uint8_t)GetCurrentPass();
    readBrcPakStatsParams.VideoContext               = m_videoContext;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadBrcPakStatistics(
        cmdBuffer,
        &readBrcPakStatsParams));

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::AddHcpPipeModeSelectCmd(MOS_COMMAND_BUFFER* cmdBuffer)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
    SetHcpPipeModeSelectParams(pipeModeSelectParams);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeModeSelectCmd(cmdBuffer, &pipeModeSelectParams));

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::AddHcpSurfaceStateCmds(MOS_COMMAND_BUFFER* cmdBuffer)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    MHW_VDBOX_SURFACE_PARAMS srcSurfaceParams;
    SetHcpSrcSurfaceParams(srcSurfaceParams);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(cmdBuffer, &srcSurfaceParams));

    MHW_VDBOX_SURFACE_PARAMS reconSurfaceParams;
    SetHcpReconSurfaceParams(reconSurfaceParams);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(cmdBuffer, &reconSurfaceParams));

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::AddHcpPictureStateCmd(MOS_COMMAND_BUFFER* cmdBuffer)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    MHW_VDBOX_HEVC_PIC_STATE picStateParams;
    SetHcpPicStateParams(picStateParams);

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPicStateCmd(cmdBuffer, &picStateParams));

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::ExecutePictureLevel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    PerfTagSetting perfTag;
    CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE);

    CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifyCommandBufferSize());

    if (!m_singleTaskPhaseSupportedInPak)
    {
        // Command buffer or patch list size are too small and so we cannot submit multiple pass of PAKs together
        m_firstTaskInPhase = true;
        m_lastTaskInPhase  = true;
    }

    if (m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex())
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("ERROR - vdbox index exceed the maximum");
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        return eStatus;
    }

    MOS_COMMAND_BUFFER cmdBuffer;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCommandBuffer(&cmdBuffer));

    if ((!m_singleTaskPhaseSupported) || m_firstTaskInPhase)
    {
        // Send command buffer header at the beginning (OS dependent)
        // frame tracking tag is only added in the last command buffer header
        bool requestFrameTracking = m_singleTaskPhaseSupported ?
            m_firstTaskInPhase :
            m_lastTaskInPhase;

        // When brc + 2 pass sao is enabled need to disable frame tracking for first cmd buffer
        if (m_brcEnabled && m_hevcSeqParams->SAO_enabled_flag)
        {
            requestFrameTracking = false;
        }

        CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
    }

    // Enable frame tracking for the last cmd buffer when brc + 2 pass sao is on
    if (m_brcEnabled && m_hevcSeqParams->SAO_enabled_flag && m_currPass == m_uc2NdSaoPass)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, true));
    }

    if (m_brcEnabled &&
        !IsFirstPass() &&
        m_currPass != m_uc2NdSaoPass)  // Only the regular BRC passes have the conditional batch buffer end
    {
        // Insert conditional batch buffer end
        MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams;
        MOS_ZeroMemory(
            &miConditionalBatchBufferEndParams,
            sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));
        uint32_t baseOffset = (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
                sizeof(uint32_t) * 2;  // pEncodeStatus is offset by 2 DWs in the resource       ;

        CODECHAL_ENCODE_ASSERT((m_encodeStatusBuf.dwImageStatusMaskOffset & 7) == 0); // Make sure uint64_t aligned
        CODECHAL_ENCODE_ASSERT((m_encodeStatusBuf.dwImageStatusMaskOffset + sizeof(uint32_t)) == m_encodeStatusBuf.dwImageStatusCtrlOffset);

        miConditionalBatchBufferEndParams.presSemaphoreBuffer = &m_encodeStatusBuf.resStatusBuffer;
        miConditionalBatchBufferEndParams.dwOffset = baseOffset + m_encodeStatusBuf.dwImageStatusMaskOffset;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
            &cmdBuffer,
            &miConditionalBatchBufferEndParams));

        auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex);
        MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams;
        MHW_MI_COPY_MEM_MEM_PARAMS miCpyMemMemParams;
        // Write back the HCP image control register for RC6 may clean it out
        MHW_MI_LOAD_REGISTER_MEM_PARAMS miLoadRegMemParams;
        MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
        miLoadRegMemParams.presStoreBuffer = &m_encodeStatusBuf.resStatusBuffer;
        miLoadRegMemParams.dwOffset = baseOffset + m_encodeStatusBuf.dwImageStatusCtrlOffset;
        miLoadRegMemParams.dwRegister = mmioRegisters->hcpEncImageStatusCtrlRegOffset;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(&cmdBuffer, &miLoadRegMemParams));

        MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
        miStoreRegMemParams.presStoreBuffer = &m_brcBuffers.resBrcPakStatisticBuffer[m_brcBuffers.uiCurrBrcPakStasIdxForWrite];
        miStoreRegMemParams.dwOffset = CODECHAL_OFFSETOF(CODECHAL_ENCODE_HEVC_PAK_STATS_BUFFER, HCP_IMAGE_STATUS_CONTROL_FOR_LAST_PASS);
        miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncImageStatusCtrlRegOffset;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(&cmdBuffer, &miStoreRegMemParams));

        MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
        miStoreRegMemParams.presStoreBuffer =  &m_encodeStatusBuf.resStatusBuffer;
        miStoreRegMemParams.dwOffset = baseOffset + m_encodeStatusBuf.dwImageStatusCtrlOfLastBRCPassOffset;
        miStoreRegMemParams.dwRegister = mmioRegisters->hcpEncImageStatusCtrlRegOffset;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(&cmdBuffer, &miStoreRegMemParams));
    }

    if (IsFirstPass() && m_osInterface->bTagResourceSync)
    {
        // This is a short term solution to solve the sync tag issue: the sync tag write for PAK is inserted at the end of 2nd pass PAK BB
        // which may be skipped in multi-pass PAK enabled case. The idea here is to insert the previous frame's tag at the beginning
        // of the BB and keep the current frame's tag at the end of the BB. There will be a delay for tag update but it should be fine
        // as long as Dec/VP/Enc won't depend on this PAK so soon.

        PMOS_RESOURCE globalGpuContextSyncTagBuffer = nullptr;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource(
            m_osInterface,
            globalGpuContextSyncTagBuffer));
        CODECHAL_ENCODE_CHK_NULL_RETURN(globalGpuContextSyncTagBuffer);

        MHW_MI_STORE_DATA_PARAMS params;
        params.pOsResource = globalGpuContextSyncTagBuffer;
        params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
        uint32_t value = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
        params.dwValue = (value > 0) ? (value - 1) : 0;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &params));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpPipeModeSelectCmd(&cmdBuffer));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpSurfaceStateCmds(&cmdBuffer));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpPipeBufAddrCmd(&cmdBuffer));

    MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
    SetHcpIndObjBaseAddrParams(indObjBaseAddrParams);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));

    MHW_VDBOX_QM_PARAMS fqmParams, qmParams;
    SetHcpQmStateParams(fqmParams, qmParams);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpFqmStateCmd(&cmdBuffer, &fqmParams));
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpQmStateCmd(&cmdBuffer, &qmParams));

    if (m_brcEnabled)
    {
        if (m_hevcSeqParams->SAO_enabled_flag && m_currPass == m_uc2NdSaoPass)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpPictureStateCmd(&cmdBuffer));
        }
        else
        {
            uint32_t picStateCmdOffset;
            picStateCmdOffset = GetCurrentPass();

            MHW_BATCH_BUFFER batchBuffer;
            MOS_ZeroMemory(&batchBuffer, sizeof(batchBuffer));
            batchBuffer.OsResource = m_brcBuffers.resBrcImageStatesWriteBuffer[m_currRecycledBufIdx];
            batchBuffer.dwOffset = picStateCmdOffset * (m_brcBuffers.dwBrcHcpPicStateSize / CODECHAL_ENCODE_BRC_MAXIMUM_NUM_PASSES);
            batchBuffer.bSecondLevel = true;

            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
                &cmdBuffer,
                &batchBuffer));
        }
    }
    else
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpPictureStateCmd(&cmdBuffer));
    }

    // Send HEVC_VP9_RDOQ_STATE command
    if (m_hevcRdoqEnabled)
    {
        MHW_VDBOX_HEVC_PIC_STATE picStateParams;
        SetHcpPicStateParams(picStateParams);

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpHevcVp9RdoqStateCmd(&cmdBuffer, &picStateParams));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(ReturnCommandBuffer(&cmdBuffer));

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::AddHcpWeightOffsetStateCmd(
    PMOS_COMMAND_BUFFER             cmdBuffer,
    PMHW_BATCH_BUFFER               batchBuffer,
    PCODEC_HEVC_ENCODE_SLICE_PARAMS hevcSlcParams)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(hevcSlcParams);

    if (cmdBuffer == nullptr && batchBuffer == nullptr)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
        return MOS_STATUS_NULL_POINTER;
    }

    MHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS hcpWeightOffsetParams;
    MOS_ZeroMemory(&hcpWeightOffsetParams, sizeof(hcpWeightOffsetParams));

    for (auto k = 0; k < 2; k++) // k=0: LIST_0, k=1: LIST_1
    {
        // Luma, Chroma offset
        for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
        {
            hcpWeightOffsetParams.LumaOffsets[k][i] = (int16_t)hevcSlcParams->luma_offset[k][i];
            // Cb, Cr
            for (auto j = 0; j < 2; j++)
            {
                hcpWeightOffsetParams.ChromaOffsets[k][i][j] = (int16_t)hevcSlcParams->chroma_offset[k][i][j];
            }
        }

        // Luma Weight
        CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
            &hcpWeightOffsetParams.LumaWeights[k],
            sizeof(hcpWeightOffsetParams.LumaWeights[k]),
            &hevcSlcParams->delta_luma_weight[k],
            sizeof(hevcSlcParams->delta_luma_weight[k])));

        // Chroma Weight
        CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
            &hcpWeightOffsetParams.ChromaWeights[k],
            sizeof(hcpWeightOffsetParams.ChromaWeights[k]),
            &hevcSlcParams->delta_chroma_weight[k],
            sizeof(hevcSlcParams->delta_chroma_weight[k])));
    }

    if (hevcSlcParams->slice_type == CODECHAL_ENCODE_HEVC_P_SLICE || hevcSlcParams->slice_type == CODECHAL_ENCODE_HEVC_B_SLICE)
    {
        hcpWeightOffsetParams.ucList = LIST_0;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpWeightOffsetStateCmd(cmdBuffer, batchBuffer, &hcpWeightOffsetParams));
    }

    if (hevcSlcParams->slice_type == CODECHAL_ENCODE_HEVC_B_SLICE)
    {
        hcpWeightOffsetParams.ucList = LIST_1;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpWeightOffsetStateCmd(cmdBuffer, batchBuffer, &hcpWeightOffsetParams));
    }

    return eStatus;
}

//------------------------------------------------------------------------------------
// Build slices with header insertion
//------------------------------------------------------------------------------------
MOS_STATUS CodechalEncHevcState::SendHwSliceEncodeCommand(
    PMOS_COMMAND_BUFFER             cmdBuffer,
    PMHW_VDBOX_HEVC_SLICE_STATE     params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pHevcPicIdx);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->presDataBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeHevcSeqParams);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeHevcPicParams);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pEncodeHevcSliceParams);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppNalUnitParams);

    PMHW_BATCH_BUFFER batchBufferInUse = nullptr;
    PMOS_COMMAND_BUFFER cmdBufferInUse = nullptr;

    if (params->bSingleTaskPhaseSupported)
    {
        CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBatchBufferForPakSlices);
        batchBufferInUse = params->pBatchBufferForPakSlices;
    }
    else
    {
        cmdBufferInUse = cmdBuffer;
    }

    // add HCP_REF_IDX command
    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpRefIdxCmd(cmdBufferInUse, batchBufferInUse, params));

    if (params->bWeightedPredInUse)
    {
        //add weghtoffset command
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpWeightOffsetStateCmd(cmdBufferInUse, batchBufferInUse, m_hevcSliceParams));
    }

    // add HEVC Slice state commands
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSliceStateCmd(cmdBufferInUse, params));

    // add HCP_PAK_INSERT_OBJECTS command
    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpPakInsertNALUs(cmdBufferInUse, batchBufferInUse, params));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHcpPakInsertSliceHeader(cmdBufferInUse, batchBufferInUse, params));

    if (params->bSingleTaskPhaseSupported && batchBufferInUse)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, batchBufferInUse));

        MHW_BATCH_BUFFER secondLevelBatchBuffer;
        MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
        secondLevelBatchBuffer.OsResource = batchBufferInUse->OsResource;
        secondLevelBatchBuffer.dwOffset = params->dwBatchBufferForPakSlicesStartOffset;
        secondLevelBatchBuffer.bSecondLevel = true;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));
    }

    // Insert Batch Buffer Start command to send HCP_PAK_OBJ data for LCUs in this slice
    MHW_BATCH_BUFFER secondLevelBatchBuffer;
    MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
    secondLevelBatchBuffer.OsResource = *params->presDataBuffer;
    secondLevelBatchBuffer.dwOffset = params->dwDataBufferOffset;
    secondLevelBatchBuffer.bSecondLevel = true;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::ExecuteSliceLevel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(m_slcData);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetBatchBufferForPakSlices());

    MOS_COMMAND_BUFFER cmdBuffer;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCommandBuffer(&cmdBuffer));

    SetHcpSliceStateCommonParams(*m_sliceStateParams);

    PCODEC_ENCODER_SLCDATA slcData = m_slcData;
    for (uint32_t startLCU = 0, SlcCount = 0; SlcCount < m_numSlices; SlcCount++)
    {
        if (m_currPass == 0)
        {
            slcData[SlcCount].CmdOffset = startLCU * (m_hcpInterface->GetHcpPakObjSize()) * sizeof(uint32_t);
        }

        SetHcpSliceStateParams(*m_sliceStateParams, slcData, SlcCount);

        CODECHAL_ENCODE_CHK_STATUS_RETURN(SendHwSliceEncodeCommand(&cmdBuffer, m_sliceStateParams));

        startLCU += m_hevcSliceParams[SlcCount].NumLCUsInSlice;

        m_batchBufferForPakSlicesStartOffset =
            (uint32_t)m_batchBufferForPakSlices[m_currPakSliceIdx].iCurrent;
    }

    if (m_useBatchBufferForPakSlices)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_UnlockBb(
            m_osInterface,
            &m_batchBufferForPakSlices[m_currPakSliceIdx],
            m_lastTaskInPhase));
    }

    // Insert end of sequence/stream if set
    if (m_lastPicInStream || m_lastPicInSeq)
    {
        MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
        MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
        pakInsertObjectParams.bLastPicInSeq     = m_lastPicInSeq;
        pakInsertObjectParams.bLastPicInStream  = m_lastPicInStream;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPakInsertObject(&cmdBuffer, &pakInsertObjectParams));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadHcpStatus(&cmdBuffer));

    // BRC PAK statistics different for each pass
    if (m_brcEnabled)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadBrcPakStats(&cmdBuffer));
    }

    if (!Mos_ResourceIsNull(&m_resFrameStatStreamOutBuffer))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadSseStatistics(&cmdBuffer));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
    }

    std::string pakPassName = "PAK_PASS" + std::to_string(static_cast<uint32_t>(m_currPass));
    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN( m_debugInterface->DumpCmdBuffer(
            &cmdBuffer,
            CODECHAL_NUM_MEDIA_STATES,
            pakPassName.data()));)

    CODECHAL_ENCODE_CHK_STATUS_RETURN(ReturnCommandBuffer(&cmdBuffer));

    if ((!m_pakOnlyTest) &&  // In the PAK only test, no need to wait for ENC's completion
        (m_currPass == 0) &&
        !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
    {
        MOS_SYNC_PARAMS syncParams = g_cInitSyncParams;
        syncParams.GpuContext = m_videoContext;
        syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;

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

    bool renderingFlags = m_videoContextUsesNullHw;

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderingFlags));

        CODECHAL_DEBUG_TOOL(
            if (m_mmcState)
            {
                m_mmcState->UpdateUserFeatureKey(&m_reconSurface);
            }
        )

        if ((m_currPass == m_numPasses) &&
            m_signalEnc &&
            m_currRefSync &&
            !Mos_ResourceIsNull(&m_currRefSync->resSyncObject))
        {
            // signal semaphore
            MOS_SYNC_PARAMS syncParams = g_cInitSyncParams;
            syncParams.GpuContext = m_videoContext;
            syncParams.presSyncResource = &m_currRefSync->resSyncObject;

            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
            m_currRefSync->uiSemaphoreObjCount++;
            m_currRefSync->bInUsed = true;
        }
    }

    // Reset parameters for next PAK execution
    if (m_currPass == m_numPasses)
    {
        if (!m_singleTaskPhaseSupported)
        {
            m_osInterface->pfnResetPerfBufferID(m_osInterface);
        }

        m_currPakSliceIdx = (m_currPakSliceIdx + 1) % CODECHAL_HEVC_NUM_PAK_SLICE_BATCH_BUFFERS;

        if (m_hevcSeqParams->ParallelBRC)
        {
            m_brcBuffers.uiCurrBrcPakStasIdxForWrite =
                (m_brcBuffers.uiCurrBrcPakStasIdxForWrite + 1) % CODECHAL_ENCODE_RECYCLED_BUFFER_NUM;
        }

        m_newPpsHeader = 0;
        m_newSeqHeader = 0;
        m_frameNum++;
    }

    return eStatus;
}

//------------------------------------------------------------------------------
//| Purpose:    Retrieves the HCP registers and stores them in the status report
//| Return:     N/A
//------------------------------------------------------------------------------
MOS_STATUS CodechalEncHevcState::ReadHcpStatus(PMOS_COMMAND_BUFFER cmdBuffer)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeHevcBase::ReadHcpStatus(cmdBuffer));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadImageStatus(cmdBuffer))

    return eStatus;
}

uint8_t CodechalEncHevcState::CalculateROIRatio()
{
    uint32_t roiSize = 0;
    for (uint32_t i = 0; i < m_hevcPicParams->NumROI; ++i)
    {
        roiSize += (ENCODE_DP_HEVC_ROI_BLOCK_Width * (MOS_ABS(m_hevcPicParams->ROI[i].Top - m_hevcPicParams->ROI[i].Bottom) + 1 )) *
                   (ENCODE_DP_HEVC_ROI_BLOCK_HEIGHT * (MOS_ABS(m_hevcPicParams->ROI[i].Right - m_hevcPicParams->ROI[i].Left) + 1));
    }

    uint32_t roiRatio = 0;
    if (roiSize)
    {
        uint32_t numMBs = m_picWidthInMb * m_picHeightInMb;
        roiRatio = 2 * (numMBs * 256 / roiSize - 1);
        roiRatio = MOS_MIN(51, roiRatio);
    }

    return (uint8_t)roiRatio;
}

int16_t CodechalEncHevcState::ComputeTemporalDifference(const CODEC_PICTURE& refPic)
{
    int16_t diff_poc = 0;

    if (!CodecHal_PictureIsInvalid(refPic))
    {
        diff_poc = m_hevcPicParams->CurrPicOrderCnt - m_hevcPicParams->RefFramePOCList[refPic.FrameIdx];

        if(diff_poc < -128)
        {
            diff_poc = -128;
        }
        else if(diff_poc > 127)
        {
            diff_poc = 127;
        }
    }

    return diff_poc;
}

MOS_STATUS CodechalEncHevcState::WaitForRefFrameReady(uint8_t mbCodeIdx)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    if (!m_refSync[mbCodeIdx].bInUsed)
    {
        return eStatus;
    }

    MOS_SYNC_PARAMS syncParams = g_cInitSyncParams;
    syncParams.GpuContext = m_renderContext;
    syncParams.presSyncResource = &m_refSync[mbCodeIdx].resSyncObject;
    syncParams.uiSemaphoreCount = m_refSync[mbCodeIdx].uiSemaphoreObjCount;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
    m_refSync[mbCodeIdx].uiSemaphoreObjCount = 0;
    m_refSync[mbCodeIdx].bInUsed             = false;

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::WaitForPak()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    if (m_pictureCodingType == I_TYPE && !m_brcEnabled)
    {
        return eStatus;
    }

    if (!m_firstFrame && m_brcEnabled && !m_hevcSeqParams->ParallelBRC)
    {
        // When there is no parallel BRC, we still need to wait for previous PAK
        CODECHAL_ENCODE_CHK_STATUS_RETURN(WaitForRefFrameReady(m_lastMbCodeIndex));
        return eStatus;
    }

    // check all reference frames. If one of them has not be waited, then it needs to be wait and ensure it has been encoded completely.
    auto slcParams = m_hevcSliceParams;
    for (uint32_t s = 0; s < m_numSlices; s++, slcParams++)
    {
        for (auto ll = 0; ll < 2; ll++)
        {
            uint32_t uiNumRef = (ll == 0) ? slcParams->num_ref_idx_l0_active_minus1 :
                slcParams->num_ref_idx_l1_active_minus1;

            for (uint32_t i = 0; i <= uiNumRef; i++)
            {
                CODEC_PICTURE refPic = slcParams->RefPicList[ll][i];
                if (!CodecHal_PictureIsInvalid(refPic) &&
                    !CodecHal_PictureIsInvalid(m_hevcPicParams->RefFrameList[refPic.FrameIdx]))
                {
                    uint32_t idx       = m_hevcPicParams->RefFrameList[refPic.FrameIdx].FrameIdx;
                    uint8_t  mbCodeIdx = m_refList[idx]->ucMbCodeIdx;
                    CODECHAL_ENCODE_CHK_STATUS_RETURN(WaitForRefFrameReady(mbCodeIdx));
                }
            }
        }
    }

    if (!m_firstTwoFrames && m_brcEnabled && m_hevcSeqParams->ParallelBRC)
    {
        // When parallel BRC, we still need to wait for the (N-2) PAK
        CODECHAL_ENCODE_CHK_STATUS_RETURN(WaitForRefFrameReady(m_currMinus2MbCodeIndex));
        return eStatus;
    }

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::UserFeatureKeyReport()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeHevcBase::UserFeatureKeyReport());

    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_HEVC_ENCODE_REGION_NUMBER_ID, m_numRegionsInSlice, m_osInterface->pOsContext);

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::InitSurfaceCodecParams2D(
    CODECHAL_SURFACE_CODEC_PARAMS* params,
    PMOS_SURFACE surface,
    uint32_t cacheabilityControl,
    uint32_t bindingTableOffset,
    uint32_t verticalLineStride,
    bool isWritable)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params);

    MOS_ZeroMemory(params, sizeof(*params));
    params->bIs2DSurface = true;
    params->bMediaBlockRW = true; // Use media block RW for DP 2D surface access
    params->psSurface = surface;
    params->dwCacheabilityControl = cacheabilityControl;
    params->dwBindingTableOffset = bindingTableOffset;
    params->dwVerticalLineStride = verticalLineStride;
    params->bIsWritable =
    params->bRenderTarget = isWritable;

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::InitSurfaceCodecParamsVME(
    CODECHAL_SURFACE_CODEC_PARAMS* params,
    PMOS_SURFACE surface,
    uint32_t cacheabilityControl,
    uint32_t bindingTableOffset)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params);

    MOS_ZeroMemory(params, sizeof(*params));
    params->bUseAdvState = true;
    params->psSurface = surface;
    params->dwCacheabilityControl= cacheabilityControl;
    params->dwBindingTableOffset = bindingTableOffset;
    params->ucVDirection = CODECHAL_VDIRECTION_FRAME;

    // surface has valid values and have support for the formats specified below
    if (surface != nullptr && (surface->Format == Format_YUY2V || surface->Format == Format_Y216V))
    {
        params->dwWidthInUse = surface->dwWidth;
        params->dwHeightInUse = surface->dwHeight;
    }

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::InitSurfaceCodecParams1D(
    CODECHAL_SURFACE_CODEC_PARAMS* params,
    PMOS_RESOURCE buffer,
    uint32_t size,
    uint32_t offset,
    uint32_t cacheabilityControl,
    uint32_t bindingTableOffset,
    bool isWritable)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params);

    MOS_ZeroMemory(params, sizeof(*params));
    params->presBuffer = buffer;
    params->dwSize = size;
    params->dwOffset = offset;
    params->dwCacheabilityControl = cacheabilityControl;
    params->dwBindingTableOffset = bindingTableOffset;
    params->bIsWritable =
    params->bRenderTarget = isWritable;

    return eStatus;
}

CodechalEncHevcState::CodechalEncHevcState(
    CodechalHwInterface* hwInterface,
    CodechalDebugInterface* debugInterface,
    PCODECHAL_STANDARD_INFO standardInfo)
    :CodechalEncodeHevcBase(hwInterface, debugInterface, standardInfo)
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    m_noMeKernelForPFrame = true;

    // initialze class members
    MOS_ZeroMemory(&m_formatConvertedSurface, sizeof(m_formatConvertedSurface));
    MOS_ZeroMemory(&m_brcBuffers, sizeof(m_brcBuffers));
}

CodechalEncHevcState::~CodechalEncHevcState()
{
    if (m_hmeKernel)
    {
        MOS_Delete(m_hmeKernel);
        m_hmeKernel = nullptr;
    }
}

MOS_STATUS CodechalEncHevcState::AllocateBrcResources()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    // initiate allocation paramters and lock flags
    MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
    MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
    allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
    allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
    allocParamsForBufferLinear.Format = Format_Buffer;

    MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
    MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
    allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
    allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
    allocParamsForBuffer2D.Format = Format_Buffer_2D;

    MOS_LOCK_PARAMS lockFlagsWriteOnly;
    MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
    lockFlagsWriteOnly.WriteOnly = true;

    // BRC history buffer
    uint32_t size = m_brcHistoryBufferSize;
    allocParamsForBufferLinear.dwBytes = size;
    allocParamsForBufferLinear.pBufName = "BRC History Buffer";

    MOS_STATUS eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
        m_osInterface,
        &allocParamsForBufferLinear,
        &m_brcBuffers.resBrcHistoryBuffer);

    if (eStatus != MOS_STATUS_SUCCESS)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC History Buffer.");
        return eStatus;
    }

    uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
        m_osInterface,
        &(m_brcBuffers.resBrcHistoryBuffer),
        &lockFlagsWriteOnly);

    if (data == nullptr)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC History Buffer.");
        eStatus = MOS_STATUS_UNKNOWN;
        return eStatus;
    }

    MOS_ZeroMemory(data, size);
    m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHistoryBuffer);

    // BRC Intra Distortion Surface
    uint32_t width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 3), 64);
    uint32_t height = MOS_ALIGN_CEIL((m_downscaledHeightInMb4x << 2), 8) << 1;
    allocParamsForBuffer2D.dwWidth = width;
    allocParamsForBuffer2D.dwHeight = height;
    allocParamsForBuffer2D.pBufName = "BRC Distortion Surface Buffer";

    CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
                                                  m_osInterface,
                                                  &allocParamsForBuffer2D,
                                                  &m_brcBuffers.sBrcIntraDistortionBuffer.OsResource),
        "Failed to allocate  ME BRC Distortion Buffer.");

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &m_brcBuffers.sBrcIntraDistortionBuffer));
    m_brcBuffers.sBrcIntraDistortionBuffer.bArraySpacing = true;
    size                                                 = m_brcBuffers.sBrcIntraDistortionBuffer.dwHeight * m_brcBuffers.sBrcIntraDistortionBuffer.dwPitch;

    CODECHAL_ENCODE_CHK_NULL_RETURN(data = (uint8_t *)m_osInterface->pfnLockResource(
                                        m_osInterface,
                                        &m_brcBuffers.sBrcIntraDistortionBuffer.OsResource,
                                        &lockFlagsWriteOnly));

    MOS_ZeroMemory(data, size);
    m_osInterface->pfnUnlockResource(
        m_osInterface, &m_brcBuffers.sBrcIntraDistortionBuffer.OsResource);

    // PAK Statistics buffer
    size                                = m_hevcBrcPakStatisticsSize;
    allocParamsForBufferLinear.dwBytes = size;
    allocParamsForBufferLinear.pBufName = "BRC PAK Statistics Buffer";

    for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &m_brcBuffers.resBrcPakStatisticBuffer[i]);

        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC PAK Statistics Buffer.");
            return eStatus;
        }

        data = (uint8_t *)m_osInterface->pfnLockResource(
            m_osInterface,
            &(m_brcBuffers.resBrcPakStatisticBuffer[i]),
            &lockFlagsWriteOnly);

        if (data == nullptr)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC PAK Statistics Buffer.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }

        MOS_ZeroMemory(data, size);
        m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcPakStatisticBuffer[i]);
    }

    // PAK HCP_PICTURE_STATEs buffer
    size                                = m_brcBuffers.dwBrcHcpPicStateSize;
    allocParamsForBufferLinear.dwBytes = size;
    allocParamsForBufferLinear.pBufName = "PAK HCP PICTURE State Read Buffer";

    for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &m_brcBuffers.resBrcImageStatesReadBuffer[i]);

        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate HCP PICTURE State Read Buffer.");
            return eStatus;
        }

        data = (uint8_t *)m_osInterface->pfnLockResource(
            m_osInterface,
            &(m_brcBuffers.resBrcImageStatesReadBuffer[i]),
            &lockFlagsWriteOnly);

        if (data == nullptr)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock HCP PICTURE State Read Buffer.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }

        MOS_ZeroMemory(data, size);
        m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcImageStatesReadBuffer[i]);
    }

    allocParamsForBufferLinear.pBufName = "PAK HCP PICTURE State Write Buffer";
    for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &m_brcBuffers.resBrcImageStatesWriteBuffer[i]);

        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(eStatus, "Failed to allocate HCP PICTURE State Write Buffer.");

        data = (uint8_t *)m_osInterface->pfnLockResource(
            m_osInterface,
            &m_brcBuffers.resBrcImageStatesWriteBuffer[i],
            &lockFlagsWriteOnly);

        if (data == nullptr)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock HCP PICTURE State Write Buffer.");
            eStatus = MOS_STATUS_NULL_POINTER;
            return eStatus;
        }

        MOS_ZeroMemory(data, size);
        m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcImageStatesWriteBuffer[i]);
    }

    // BRC constant data surface
    allocParamsForBuffer2D.dwWidth  = MOS_ALIGN_CEIL(m_brcBuffers.dwBrcConstantSurfaceWidth, 64);
    allocParamsForBuffer2D.dwHeight = m_brcBuffers.dwBrcConstantSurfaceHeight;
    allocParamsForBuffer2D.pBufName = "BRC Constant Data Buffer";

    for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBuffer2D,
            &m_brcBuffers.sBrcConstantDataBuffer[i].OsResource);

        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC Constant Data Buffer.");
            return eStatus;
        }

        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &m_brcBuffers.sBrcConstantDataBuffer[i]));
        m_brcBuffers.sBrcConstantDataBuffer[i].bArraySpacing = true;
    }

    // Use the Mb QP buffer in BrcBuffer for LCU-based Qp surface in HEVC
    MOS_ZeroMemory(&m_brcBuffers.sBrcMbQpBuffer, sizeof(m_brcBuffers.sBrcMbQpBuffer));

    // original picture size in MB units aligned to 64 bytes along width and 8 bytes along height
    width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * SCALE_FACTOR_4x), 64);
    height = MOS_ALIGN_CEIL((m_downscaledHeightInMb4x * SCALE_FACTOR_4x), 8);
    size = width * height;

    allocParamsForBuffer2D.dwWidth = width;
    allocParamsForBuffer2D.dwHeight = height;
    allocParamsForBuffer2D.pBufName = "BRC MB QP Buffer";

    eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
        m_osInterface,
        &allocParamsForBuffer2D,
        &m_brcBuffers.sBrcMbQpBuffer.OsResource);

    if (eStatus != MOS_STATUS_SUCCESS)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC MB QP Buffer.");
        return eStatus;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &m_brcBuffers.sBrcMbQpBuffer));
    m_brcBuffers.sBrcMbQpBuffer.bArraySpacing = true;

    data = (uint8_t *)m_osInterface->pfnLockResource(
        m_osInterface,
        &(m_brcBuffers.sBrcMbQpBuffer.OsResource),
        &lockFlagsWriteOnly);

    if (data == nullptr)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC MB QP Buffer.");
        eStatus = MOS_STATUS_UNKNOWN;
        return eStatus;
    }

    MOS_ZeroMemory(data, size);
    m_osInterface->pfnUnlockResource(
        m_osInterface,
        &m_brcBuffers.sBrcMbQpBuffer.OsResource);

    // ROI surface
    MOS_ZeroMemory(&m_brcBuffers.sBrcRoiSurface, sizeof(m_brcBuffers.sBrcRoiSurface));

    // original picture size in MB units aligned to 64 bytes along width and 8 bytes along height
    // ROI buffer size uses MB units for HEVC, not LCU
    width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 4), 64);
    height = MOS_ALIGN_CEIL((m_downscaledHeightInMb4x << 2), 8);

    MOS_ZeroMemory(&m_brcBuffers.sBrcRoiSurface, sizeof(m_brcBuffers.sBrcRoiSurface));
    m_brcBuffers.sBrcRoiSurface.TileType       = MOS_TILE_LINEAR;
    m_brcBuffers.sBrcRoiSurface.bArraySpacing  = true;
    m_brcBuffers.sBrcRoiSurface.Format         = Format_Buffer_2D;
    m_brcBuffers.sBrcRoiSurface.dwWidth        = width;
    m_brcBuffers.sBrcRoiSurface.dwPitch        = width;
    m_brcBuffers.sBrcRoiSurface.dwHeight       = height;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
        &m_brcBuffers.sBrcRoiSurface,
        width,
        height,
        "ROI Buffer"));
    
    return eStatus;
}

MOS_STATUS CodechalEncHevcState::FreeBrcResources()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &m_brcBuffers.resBrcHistoryBuffer);

    for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_brcBuffers.resBrcPakStatisticBuffer[i]);

        m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_brcBuffers.resBrcImageStatesReadBuffer[i]);

        m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_brcBuffers.resBrcImageStatesWriteBuffer[i]);

        m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_brcBuffers.sBrcConstantDataBuffer[i].OsResource);
    }

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &m_brcBuffers.sBrcIntraDistortionBuffer.OsResource);

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &m_brcBuffers.sBrcMbQpBuffer.OsResource);

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &m_brcBuffers.sBrcRoiSurface.OsResource);

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalEncHevcState::AllocateEncStatsResources()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    if (Mos_ResourceIsNull(&m_encStatsBuffers.m_puStatsSurface.OsResource))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
            &m_encStatsBuffers.m_puStatsSurface,
            m_widthAlignedMaxLcu,
            m_heightAlignedMaxLcu >> 5,
            "32x32 PU statistics Data Dump surface"));
    }

    if (Mos_ResourceIsNull(&m_encStatsBuffers.m_8x8PuHaarDist.OsResource))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
            &m_encStatsBuffers.m_8x8PuHaarDist,
            m_widthAlignedMaxLcu,
            m_heightAlignedMaxLcu >> 4,
            "8x8 PU Haar distortion for 16x16 surface"));
    }

    if (Mos_ResourceIsNull(&m_encStatsBuffers.m_8x8PuFrameStats.sResource))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
                    &m_encStatsBuffers.m_8x8PuFrameStats,
                    m_8x8PuFrameStatsSize,
                    "8x8 PU frame statistics surface"));
    }

    if (Mos_ResourceIsNull(&m_encStatsBuffers.m_mbEncStatsSurface.OsResource))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
            &m_encStatsBuffers.m_mbEncStatsSurface,
            m_widthAlignedMaxLcu,
            m_heightAlignedMaxLcu >> 5,
            "MB Enc Statistics data dump surface"));
    }

    if (Mos_ResourceIsNull(&m_encStatsBuffers.m_mbEncFrameStats.sResource))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
                    &m_encStatsBuffers.m_mbEncFrameStats,
                    m_mbEncFrameStatsSize,
                    "MB Enc frame statistics surface"));
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalEncHevcState::FreeEncStatsResources()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_encStatsBuffers.m_puStatsSurface.OsResource);

    m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_encStatsBuffers.m_8x8PuHaarDist.OsResource);

    m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_encStatsBuffers.m_8x8PuFrameStats.sResource);

    m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_encStatsBuffers.m_mbEncStatsSurface.OsResource);

    m_osInterface->pfnFreeResource(
            m_osInterface,
            &m_encStatsBuffers.m_mbEncFrameStats.sResource);

    return MOS_STATUS_SUCCESS;
}

bool CodechalEncHevcState::CheckSupportedFormat(PMOS_SURFACE surface)
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    bool isColorFormatSupported = false;

    if (nullptr == surface)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Invalid (nullptr) Pointer.");
        return isColorFormatSupported;
    }

    switch (surface->Format)
    {
    case Format_NV12:
        isColorFormatSupported = IS_Y_MAJOR_TILE_FORMAT(surface->TileType);
        break;
    case Format_P010:
        isColorFormatSupported = true;
    case Format_YUY2:
    case Format_YUYV:
    case Format_A8R8G8B8:
        break;
    default:
        CODECHAL_ENCODE_ASSERTMESSAGE("Input surface color format = %d not supported!", surface->Format);
        break;
    }

    return isColorFormatSupported;
}

MOS_STATUS CodechalEncHevcState::Initialize(CodechalSetting * settings)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    // common initilization
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeHevcBase::Initialize(settings));

    m_brcBuffers.dwBrcHcpPicStateSize       = BRC_IMG_STATE_SIZE_PER_PASS * CODECHAL_ENCODE_BRC_MAXIMUM_NUM_PASSES;
    m_brcBuffers.uiCurrBrcPakStasIdxForRead = 0;
    //Reading buffer is with 2 frames late for BRC kernel uses the PAK statstic info of the frame before the previous frame
    m_brcBuffers.uiCurrBrcPakStasIdxForWrite =
        (m_brcBuffers.uiCurrBrcPakStasIdxForRead + 2) % CODECHAL_ENCODE_RECYCLED_BUFFER_NUM;

    m_widthAlignedLcu32  = MOS_ALIGN_CEIL(m_frameWidth, 32);
    m_heightAlignedLcu32 = MOS_ALIGN_CEIL(m_frameHeight, 32);

    m_hucCommandsSize = m_hwInterface->m_hucCommandBufferSize * CODECHAL_HEVC_MAX_NUM_BRC_PASSES;

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::GetFrameBrcLevel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    if (m_lowDelay)
    {
        // LDB
        if (m_pictureCodingType == I_TYPE)
        {
            if (m_hevcPicParams->HierarchLevelPlus1 == 0)
            {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_I;
            }
            else
            {
                CODECHAL_ENCODE_ASSERTMESSAGE("FrameLevel can only be 0 for I type for LDB\n");
                return MOS_STATUS_INVALID_PARAMETER;
            }
        }
        else if ((m_pictureCodingType == P_TYPE) || (m_pictureCodingType == B_TYPE))
        {
            if (m_hevcPicParams->HierarchLevelPlus1 == 0)
            {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_P_OR_LB;
            }
            else if (m_hevcPicParams->HierarchLevelPlus1 == 1)
            {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_B;
            }
            else if (m_hevcPicParams->HierarchLevelPlus1 == 2)
            {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_B1;
            }
            else if (m_hevcPicParams->HierarchLevelPlus1 == 3)
            {
                CODECHAL_ENCODE_ASSERTMESSAGE("FrameLevel 3 is not supported for LDB\n");
                return MOS_STATUS_INVALID_PARAMETER;
            }
            else
            {
                CODECHAL_ENCODE_ASSERT(false);
                return MOS_STATUS_INVALID_PARAMETER;
            }
        }
        else if ((m_pictureCodingType == B1_TYPE) || (m_pictureCodingType == B2_TYPE))
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("B1 & B2 Type is not supported for LDB\n");
            return MOS_STATUS_INVALID_PARAMETER;
        }
        else
        {
            CODECHAL_ENCODE_ASSERT(false);
            return MOS_STATUS_INVALID_PARAMETER;
        }
    }
    else
    {
        // HB
        if (m_pictureCodingType == I_TYPE)
        {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_I;
        }
        else if (m_pictureCodingType == B_TYPE)
        {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_B;
        }
        else if (m_pictureCodingType == B1_TYPE)
        {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_B1;
        }
        else if (m_pictureCodingType == B2_TYPE)
        {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_B2;
        }
        else if (m_pictureCodingType == P_TYPE)
        {
                m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_P_OR_LB;
        }
        else
        {
                CODECHAL_ENCODE_ASSERT(false);
                return MOS_STATUS_INVALID_PARAMETER;
        }
    }

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::InitializePicture(const EncoderParams& params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeHevcBase::InitializePicture(params));
    CODECHAL_ENCODE_CHK_STATUS_RETURN(GetFrameBrcLevel());
    
    return eStatus;
}

MOS_STATUS CodechalEncHevcState::SetMeCurbeParams(
    CodechalKernelHme::CurbeParam &curbeParams)
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    // Setup ME Params
    MOS_ZeroMemory(&curbeParams, sizeof(curbeParams));
    curbeParams.subPelMode        = 3;
    curbeParams.currOriginalPic   = m_hevcPicParams->CurrOriginalPic;
    curbeParams.qpPrimeY          = m_hevcPicParams->QpY + m_hevcSliceParams->slice_qp_delta;
    curbeParams.targetUsage       = m_hevcSeqParams->TargetUsage;
    curbeParams.maxMvLen          = CODECHAL_ENCODE_HEVC_MAX_MV_LEN_AVC_LEVEL_51;
    curbeParams.numRefIdxL0Minus1 = m_hevcSliceParams->num_ref_idx_l0_active_minus1;
    curbeParams.numRefIdxL1Minus1 = m_hevcSliceParams->num_ref_idx_l1_active_minus1;
    curbeParams.bmeMethodTable    = m_bmeMethodTable;
    curbeParams.meMethodTable     = m_meMethodTable;

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalEncHevcState::SetMeSurfaceParams(
    CodechalKernelHme::SurfaceParams     &surfaceParams)
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    // Setup ME Params
    MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
    surfaceParams.mbaffEnabled                     = false;
    surfaceParams.numRefIdxL0ActiveMinus1          = m_hevcSliceParams->num_ref_idx_l0_active_minus1;
    surfaceParams.numRefIdxL1ActiveMinus1          = m_hevcSliceParams->num_ref_idx_l1_active_minus1;
    surfaceParams.verticalLineStride               = m_verticalLineStride;
    surfaceParams.verticalLineStrideOffset         = m_verticalLineStrideOffset;
    surfaceParams.meBrcDistortionBuffer            = &m_brcBuffers.sMeBrcDistortionBuffer;
    surfaceParams.meBrcDistortionBottomFieldOffset = m_brcBuffers.dwMeBrcDistortionBottomFieldOffset;
    surfaceParams.refList                          = &m_refList[0];
    surfaceParams.picIdx                           = &m_picIdx[0];
    surfaceParams.currOriginalPic                  = &m_currOriginalPic;
    surfaceParams.refL0List                        = &(m_hevcSliceParams->RefPicList[LIST_0][0]);
    surfaceParams.refL1List                        = &(m_hevcSliceParams->RefPicList[LIST_1][0]);

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalEncHevcState::EncodeMeKernel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    // Walker must be used for HME call and scaling one
    CODECHAL_ENCODE_ASSERT(m_hwWalker);

    if (m_hmeKernel && m_hmeKernel->Is4xMeEnabled())
    {
        CodechalKernelHme::CurbeParam curbeParam;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetMeCurbeParams(curbeParam));

        CodechalKernelHme::SurfaceParams surfaceParam;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetMeSurfaceParams(surfaceParam));
        if (m_hmeKernel->Is16xMeEnabled())
        {
            if (m_hmeKernel->Is32xMeEnabled())
            {
                surfaceParam.downScaledWidthInMb         = m_downscaledWidthInMb32x;
                surfaceParam.downScaledHeightInMb        = m_downscaledFrameFieldHeightInMb32x;
                surfaceParam.downScaledBottomFieldOffset = m_scaled32xBottomFieldOffset;
                CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel32x));
            }
            surfaceParam.downScaledWidthInMb         = m_downscaledWidthInMb16x;
            surfaceParam.downScaledHeightInMb        = m_downscaledFrameFieldHeightInMb16x;
            surfaceParam.downScaledBottomFieldOffset = m_scaled16xBottomFieldOffset;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel16x));
        }
        surfaceParam.downScaledWidthInMb         = m_downscaledWidthInMb4x;
        surfaceParam.downScaledHeightInMb        = m_downscaledFrameFieldHeightInMb4x;
        surfaceParam.downScaledBottomFieldOffset = m_scaledBottomFieldOffset;
        m_lastTaskInPhase = true;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel4x));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpHMESurfaces());

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::DumpHMESurfaces()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_DEBUG_TOOL(
    if (m_hmeEnabled) {
        PMOS_SURFACE dumpBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer);
        if (dumpBuffer)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &dumpBuffer->OsResource,
                CodechalDbgAttr::attrOutput,
                "MvData",
                dumpBuffer->dwHeight *dumpBuffer->dwPitch,
                CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) * (m_downscaledFrameFieldHeightInMb4x * 4) : 0,
                CODECHAL_MEDIA_STATE_4X_ME));
        }

        dumpBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer);
        if (dumpBuffer)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &dumpBuffer->OsResource,
                CodechalDbgAttr::attrOutput,
                "MeDist",
                dumpBuffer->dwHeight * dumpBuffer->dwPitch,
                CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64) * MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4), 8) : 0,
                CODECHAL_MEDIA_STATE_4X_ME));
        }

        if (m_b16XMeEnabled)
        {
            dumpBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me16xMvDataBuffer);
            //    &meOutputParams));

            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &dumpBuffer->OsResource,
                CodechalDbgAttr::attrOutput,
                "MvData",
                dumpBuffer->dwHeight *dumpBuffer->dwPitch,
                CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) * (m_downscaledFrameFieldHeightInMb16x * 4) : 0,
                CODECHAL_MEDIA_STATE_16X_ME));

            if (m_b32XMeEnabled)
            {
                dumpBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me32xMvDataBuffer);
                CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                    &dumpBuffer->OsResource,
                    CodechalDbgAttr::attrOutput,
                    "MvData",
                    dumpBuffer->dwHeight *dumpBuffer->dwPitch,
                    CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) * (m_downscaledFrameFieldHeightInMb32x * 4) : 0,
                    CODECHAL_MEDIA_STATE_32X_ME));
            }
        }
    })

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalEncHevcState::SetupROISurface()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    MOS_LOCK_PARAMS ReadOnly;
    MOS_ZeroMemory(&ReadOnly, sizeof(ReadOnly));
    ReadOnly.ReadOnly = 1;
    uint32_t * dataPtr = (uint32_t *)m_osInterface->pfnLockResource(m_osInterface, &m_brcBuffers.sBrcRoiSurface.OsResource, &ReadOnly);
    if (!dataPtr)
    {
        eStatus = MOS_STATUS_INVALID_HANDLE;
        return eStatus;
    }

    uint32_t bufferWidthInByte  = m_brcBuffers.sBrcRoiSurface.dwPitch;
    uint32_t bufferHeightInByte = MOS_ALIGN_CEIL((m_downscaledHeightInMb4x << 2), 8);
    uint32_t numMBs = m_picWidthInMb * m_picHeightInMb;
    for (uint32_t uMB = 0; uMB <= numMBs; uMB++)
    {
        int32_t curMbY = uMB / m_picWidthInMb;
        int32_t curMbX = uMB - curMbY * m_picWidthInMb;

        uint32_t outdata = 0;
        for (int32_t roiIdx = (m_hevcPicParams->NumROI - 1); roiIdx >= 0; roiIdx--)
        {
            int32_t qpLevel;
            if (m_roiValueInDeltaQp)
            {
                qpLevel = m_hevcPicParams->ROI[roiIdx].PriorityLevelOrDQp;
            }
            else
            {
                // QP Level sent to ROI surface is (priority * 5)
                //qpLevel = m_hevcPicParams->ROI[roiIdx].PriorityLevelOrDQp * 6;
                CODECHAL_ENCODE_ASSERTMESSAGE("error: ROI does not support priority level for now.");
                return MOS_STATUS_INVALID_PARAMETER;
            }

            if (qpLevel == 0)
            {
                continue;
            }

            if ((curMbX >= (int32_t)m_hevcPicParams->ROI[roiIdx].Left) && (curMbX < (int32_t)m_hevcPicParams->ROI[roiIdx].Right) &&
                (curMbY >= (int32_t)m_hevcPicParams->ROI[roiIdx].Top) && (curMbY < (int32_t)m_hevcPicParams->ROI[roiIdx].Bottom))
            {
                outdata = 15 | ((qpLevel & 0xFF) << 16);
            }
            else if (m_roiRegionSmoothEnabled)
            {
                if ((curMbX >= (int32_t)m_hevcPicParams->ROI[roiIdx].Left - 1) && (curMbX < (int32_t)m_hevcPicParams->ROI[roiIdx].Right + 1) &&
                    (curMbY >= (int32_t)m_hevcPicParams->ROI[roiIdx].Top - 1) && (curMbY < (int32_t)m_hevcPicParams->ROI[roiIdx].Bottom + 1))
                {
                    outdata = 14 | ((qpLevel & 0xFF) << 16);
                }
                else if ((curMbX >= (int32_t)m_hevcPicParams->ROI[roiIdx].Left - 2) && (curMbX < (int32_t)m_hevcPicParams->ROI[roiIdx].Right + 2) &&
                         (curMbY >= (int32_t)m_hevcPicParams->ROI[roiIdx].Top - 2) && (curMbY < (int32_t)m_hevcPicParams->ROI[roiIdx].Bottom + 2))
                {
                    outdata = 13 | ((qpLevel & 0xFF) << 16);
                }
                else if ((curMbX >= (int32_t)m_hevcPicParams->ROI[roiIdx].Left - 3) && (curMbX < (int32_t)m_hevcPicParams->ROI[roiIdx].Right + 3) &&
                         (curMbY >= (int32_t)m_hevcPicParams->ROI[roiIdx].Top - 3) && (curMbY < (int32_t)m_hevcPicParams->ROI[roiIdx].Bottom + 3))
                {
                    outdata = 12 | ((qpLevel & 0xFF) << 16);
                }
            }
        }
        dataPtr[(curMbY * (bufferWidthInByte >> 2)) + curMbX] = outdata;
    }

    m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.sBrcRoiSurface.OsResource);

    uint32_t bufferSize = bufferWidthInByte * bufferHeightInByte;
    CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
        &m_brcBuffers.sBrcRoiSurface.OsResource,
        CodechalDbgAttr::attrROISurface,
        "ROIInputSurface",
        bufferSize,
        0,
        CODECHAL_NUM_MEDIA_STATES)));

    return eStatus;
}

MOS_STATUS CodechalEncHevcState::GetRoundingIntraInterToUse()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    if (m_hevcPicParams->CustomRoundingOffsetsParams.fields.EnableCustomRoudingIntra)
    {
        m_roundingIntraInUse = m_hevcPicParams->CustomRoundingOffsetsParams.fields.RoundingOffsetIntra;
    }
    else
    {
        if (m_hevcSeqParams->NumOfBInGop[1] != 0 || m_hevcSeqParams->NumOfBInGop[2] != 0)
        {
            //Hierachical B GOP
            if (m_hevcPicParams->CodingType == I_TYPE || 
                m_hevcPicParams->CodingType == P_TYPE)
            {
                m_roundingIntraInUse = 4;
            }
            else if (m_hevcPicParams->CodingType == B_TYPE)
            {
                m_roundingIntraInUse = 3;
            }
            else
            {
                m_roundingIntraInUse = 2;
            }
        }
        else
        {
            m_roundingIntraInUse = 10;
        }
    }

    if (m_hevcPicParams->CustomRoundingOffsetsParams.fields.EnableCustomRoudingInter)
    {
        m_roundingInterInUse = m_hevcPicParams->CustomRoundingOffsetsParams.fields.RoundingOffsetInter;
    }
    else
    {
        if (m_hevcSeqParams->NumOfBInGop[1] != 0 || m_hevcSeqParams->NumOfBInGop[2] != 0)
        {
            //Hierachical B GOP 
            if (m_hevcPicParams->CodingType == I_TYPE || 
                m_hevcPicParams->CodingType == P_TYPE)
            {
                m_roundingInterInUse = 4;
            }
            else if (m_hevcPicParams->CodingType == B_TYPE)
            {
                m_roundingInterInUse = 3;
            }
            else
            {
                m_roundingInterInUse = 2;
            }
        }
        else
        {
            m_roundingInterInUse = 4;
        }
    }

    return eStatus;
}

