[Encode] Rework AVC slice state

- Move MFX_AVC_SLICE_STATE and VDENC_AVC_SLICE_STATE commands to 2nd lvl BB
- Change Rounding table
diff --git a/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.cpp b/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.cpp
index 65ca4ec..85b3cf1 100644
--- a/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.cpp
+++ b/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.cpp
@@ -280,7 +280,7 @@
     }
 
     // add AVC Slice state commands
-    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcSlice(cmdBufferInUse, batchBufferInUse, params));
+    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddMfxAvcSlice(cmdBufferInUse, batchBufferInUse, params));
 
     //insert AU, SPS, PSP headers before first slice header
     if (params->bInsertBeforeSliceHeaders)
@@ -397,7 +397,7 @@
         {
             weightOffsetParams.pAvcPicParams = params->pEncodeAvcPicParams;
             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencAvcWeightsOffsetsStateCmd(cmdBuffer, &weightOffsetParams));
-            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencSliceStateCmd(cmdBuffer, params));
+            CODECHAL_ENCODE_CHK_STATUS_RETURN(AddVdencSliceStateCmd(cmdBuffer, params));
 
             vdencWalkerStateParams.Mode          = CODECHAL_ENCODE_MODE_AVC;
             vdencWalkerStateParams.slcIdx        = params->dwSliceIndex;
@@ -4624,3 +4624,28 @@
     }
     return MOS_STATUS_SUCCESS;
 }
+
+MOS_STATUS CodechalEncodeAvcBase::AddMfxAvcSlice(
+    PMOS_COMMAND_BUFFER        cmdBuffer,
+    PMHW_BATCH_BUFFER          batchBuffer,
+    PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)
+{
+    CODECHAL_ENCODE_FUNCTION_ENTER;
+
+    CODECHAL_ENCODE_CHK_NULL_RETURN(m_mfxInterface);
+    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcSlice(cmdBuffer, batchBuffer, avcSliceState));
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS CodechalEncodeAvcBase::AddVdencSliceStateCmd(
+    PMOS_COMMAND_BUFFER        cmdBuffer,
+    PMHW_VDBOX_AVC_SLICE_STATE params)
+{
+    CODECHAL_ENCODE_FUNCTION_ENTER;
+
+    CODECHAL_ENCODE_CHK_NULL_RETURN(m_vdencInterface);
+    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencSliceStateCmd(cmdBuffer, params));
+
+    return MOS_STATUS_SUCCESS;
+}
\ No newline at end of file
diff --git a/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.h b/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.h
index cde0db4..269c80a 100644
--- a/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.h
+++ b/media_driver/agnostic/common/codec/hal/codechal_encode_avc_base.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, Intel Corporation
+* Copyright (c) 2017-2021, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -1614,6 +1614,15 @@
         PMOS_COMMAND_BUFFER            cmdBuffer,
         uint32_t                       currPass);
 
+    virtual MOS_STATUS AddMfxAvcSlice(
+        PMOS_COMMAND_BUFFER        cmdBuffer,
+        PMHW_BATCH_BUFFER          batchBuffer,
+        PMHW_VDBOX_AVC_SLICE_STATE avcSliceState);
+
+    virtual MOS_STATUS AddVdencSliceStateCmd(
+        PMOS_COMMAND_BUFFER        cmdBuffer,
+        PMHW_VDBOX_AVC_SLICE_STATE params);
+
 #if USE_CODECHAL_DEBUG_TOOL
     MOS_STATUS DumpSeqParams(
         PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,
diff --git a/media_driver/agnostic/common/codec/hal/codechal_hw.cpp b/media_driver/agnostic/common/codec/hal/codechal_hw.cpp
index 901ab47..b1b7a33 100644
--- a/media_driver/agnostic/common/codec/hal/codechal_hw.cpp
+++ b/media_driver/agnostic/common/codec/hal/codechal_hw.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2020, Intel Corporation
+* Copyright (c) 2011-2021, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -757,7 +757,7 @@
     // Set VDENC_COST_STATE command
     constructedCmdBuf.pCmdPtr = (uint32_t *)(data + mfxAvcImgStateSize);
     constructedCmdBuf.iOffset = mfxAvcImgStateSize;
-    m_vdencInterface->AddVdencAvcCostStateCmd(&constructedCmdBuf, nullptr, params);
+    MHW_MI_CHK_STATUS(m_vdencInterface->AddVdencAvcCostStateCmd(&constructedCmdBuf, nullptr, params));
 
     // Set VDENC_IMAGE_STATE command
     constructedCmdBuf.pCmdPtr = (uint32_t *)(data + mfxAvcImgStateSize + vdencAvcCostStateSize);
diff --git a/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.cpp b/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.cpp
index 99096fe..614dad8 100644
--- a/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.cpp
+++ b/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2020, Intel Corporation
+* Copyright (c) 2011-2021, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -5157,7 +5157,7 @@
         }
     }
 
-    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AddVdencBrcImgBuffer(
+    CODECHAL_ENCODE_CHK_STATUS_RETURN(AddVdencBrcImgBuffer(
         &m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx],
         imageStateParams));
     MOS_Delete(imageStateParams);
@@ -6182,6 +6182,10 @@
         }
         else
         {
+            // current location to add cmds in 2nd level batch buffer
+            m_batchBufferForVdencImgStat[0].iCurrent = 0;
+            // reset starting location (offset) executing 2nd level batch buffer for each frame & each pass
+            m_batchBufferForVdencImgStat[0].dwOffset = 0;
             secondLevelBatchBufferUsed = &(m_batchBufferForVdencImgStat[0]);
         }
         MOS_Delete(imageStateParams);
@@ -6292,82 +6296,14 @@
 
     avcSlcParams = m_avcSliceParams;
 
-    CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS packSlcHeaderParams;
-    packSlcHeaderParams.pBsBuffer          = &m_bsBuffer;
-    packSlcHeaderParams.pPicParams         = avcPicParams;
-    packSlcHeaderParams.pSeqParams         = m_avcSeqParam;
-    packSlcHeaderParams.ppRefList          = &(m_refList[0]);
-    packSlcHeaderParams.CurrPic            = m_currOriginalPic;
-    packSlcHeaderParams.CurrReconPic       = m_currReconstructedPic;
-    packSlcHeaderParams.UserFlags          = m_userFlags;
-    packSlcHeaderParams.NalUnitType        = m_nalUnitType;
-    packSlcHeaderParams.wPictureCodingType = m_pictureCodingType;
-    packSlcHeaderParams.bVdencEnabled      = true;
-
-    MHW_VDBOX_AVC_SLICE_STATE sliceState;
-    MOS_ZeroMemory(&sliceState, sizeof(sliceState));
-    sliceState.presDataBuffer      = &m_resMbCodeSurface;
-    sliceState.pAvcPicIdx          = &(m_picIdx[0]);
-    sliceState.pEncodeAvcSeqParams = m_avcSeqParam;
-    sliceState.pEncodeAvcPicParams = avcPicParams;
-    sliceState.pBsBuffer           = &m_bsBuffer;
-    sliceState.ppNalUnitParams     = m_nalUnitParams;
-    sliceState.bBrcEnabled         = false;
-    // Disable Panic mode when min/max QP control is on. kernel may disable it, but disable in driver also.
-    sliceState.bRCPanicEnable                = m_panicEnable && (!m_minMaxQpControlEnabled);
-    sliceState.bAcceleratorHeaderPackingCaps = m_encodeParams.bAcceleratorHeaderPackingCaps;
-    sliceState.wFrameFieldHeightInMB         = m_frameFieldHeightInMb;
+    CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS packSlcHeaderParams = {};
+    MHW_VDBOX_AVC_SLICE_STATE                  sliceState          = {};
+    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCommonSliceState(packSlcHeaderParams, sliceState));
 
     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams;
     for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++)
     {
-        if (m_currPass == 0)
-        {
-            packSlcHeaderParams.pAvcSliceParams = &avcSlcParams[slcCount];
-            if (m_acceleratorHeaderPackingCaps)
-            {
-                slcData[slcCount].SliceOffset = m_bsBuffer.SliceOffset;
-                CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_PackSliceHeader(&packSlcHeaderParams));
-                slcData[slcCount].BitSize = m_bsBuffer.BitSize;
-            }
-            if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE)
-            {
-                slcData[slcCount].CmdOffset = slcCount * m_sliceHeight * m_picWidthInMb * 16 * 4;
-            }
-            else
-            {
-                slcData[slcCount].CmdOffset = packSlcHeaderParams.pAvcSliceParams->first_mb_in_slice * 16 * 4;
-            }
-        }
-
-        sliceState.pEncodeAvcSliceParams = &avcSlcParams[slcCount];
-        sliceState.dwDataBufferOffset =
-            m_slcData[slcCount].CmdOffset + m_mbcodeBottomFieldOffset;
-        sliceState.dwOffset                  = slcData[slcCount].SliceOffset;
-        sliceState.dwLength                  = slcData[slcCount].BitSize;
-        sliceState.uiSkipEmulationCheckCount = slcData[slcCount].SkipEmulationByteCount;
-        sliceState.dwSliceIndex              = (uint32_t)slcCount;
-        sliceState.bFirstPass                = (m_currPass == 0);
-        sliceState.bLastPass                 = (m_currPass == m_numPasses);
-        sliceState.bInsertBeforeSliceHeaders = (slcCount == 0);
-        sliceState.bVdencInUse               = true;
-        // App handles tail insertion for VDEnc dynamic slice in non-cp case
-        sliceState.bVdencNoTailInsertion = m_vdencNoTailInsertion;
-
-        uint32_t batchBufferForPakSlicesStartOffset =
-            (uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iCurrent;
-
-        if (useBatchBufferForPakSlices)
-        {
-            sliceState.pBatchBufferForPakSlices =
-                &m_batchBufferForPakSlices[m_currRecycledBufIdx];
-            sliceState.bSingleTaskPhaseSupported            = true;
-            sliceState.dwBatchBufferForPakSlicesStartOffset = batchBufferForPakSlicesStartOffset;
-        }
-
-        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetRounding(m_avcRoundingParams, &sliceState));
-
-        sliceState.oneOnOneMapping = m_oneOnOneMapping;
+        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceState(packSlcHeaderParams, sliceState, slcCount));
         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSlice(&cmdBuffer, &sliceState));
 
         // Add dumps for 2nd level batch buffer
@@ -6894,7 +6830,7 @@
         }
 
         // VDENC IMG STATE read buffer
-        allocParamsForBufferLinear.dwBytes  = MOS_ALIGN_CEIL(m_hwInterface->m_vdencBrcImgStateBufferSize, CODECHAL_PAGE_SIZE);
+        allocParamsForBufferLinear.dwBytes  = GetVdencBRCImgStateBufferSize();
         allocParamsForBufferLinear.pBufName = "VDENC BRC IMG State Read Buffer";
 
         eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
@@ -7104,7 +7040,7 @@
             m_osInterface,
             &m_batchBufferForVdencImgStat[0],
             nullptr,
-            m_hwInterface->m_vdencBrcImgStateBufferSize));
+            GetVdencBRCImgStateBufferSize()));
     }
 
     // Buffer to store VDEnc TLB MMIO values (registers MFX_LRA_0/1/2)
@@ -8356,6 +8292,129 @@
     return eStatus;
 }
 
+MOS_STATUS CodechalVdencAvcState::AddVdencBrcImgBuffer(
+    PMOS_RESOURCE             vdencBrcImgBuffer,
+    PMHW_VDBOX_AVC_IMG_PARAMS params)
+{
+    CODECHAL_ENCODE_FUNCTION_ENTER;
+
+    CODECHAL_ENCODE_CHK_NULL_RETURN(vdencBrcImgBuffer);
+    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
+    CODECHAL_ENCODE_CHK_NULL_RETURN(m_hwInterface);
+
+    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AddVdencBrcImgBuffer(
+        vdencBrcImgBuffer,
+        params));
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS CodechalVdencAvcState::SetCommonSliceState(
+    CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS &packSlcHeaderParams,
+    MHW_VDBOX_AVC_SLICE_STATE &                 sliceState)
+{
+    CODECHAL_ENCODE_FUNCTION_ENTER;
+
+    auto avcSlcParams = m_avcSliceParams;
+    auto avcPicParams = m_avcPicParams[avcSlcParams->pic_parameter_set_id];
+
+    MOS_ZeroMemory(&packSlcHeaderParams, sizeof(packSlcHeaderParams));
+    packSlcHeaderParams.pBsBuffer          = &m_bsBuffer;
+    packSlcHeaderParams.pPicParams         = avcPicParams;
+    packSlcHeaderParams.pSeqParams         = m_avcSeqParam;
+    packSlcHeaderParams.ppRefList          = &(m_refList[0]);
+    packSlcHeaderParams.CurrPic            = m_currOriginalPic;
+    packSlcHeaderParams.CurrReconPic       = m_currReconstructedPic;
+    packSlcHeaderParams.UserFlags          = m_userFlags;
+    packSlcHeaderParams.NalUnitType        = m_nalUnitType;
+    packSlcHeaderParams.wPictureCodingType = m_pictureCodingType;
+    packSlcHeaderParams.bVdencEnabled      = true;
+
+    MOS_ZeroMemory(&sliceState, sizeof(sliceState));
+    sliceState.presDataBuffer      = &m_resMbCodeSurface;
+    sliceState.pAvcPicIdx          = &(m_picIdx[0]);
+    sliceState.pEncodeAvcSeqParams = m_avcSeqParam;
+    sliceState.pEncodeAvcPicParams = avcPicParams;
+    sliceState.pBsBuffer           = &m_bsBuffer;
+    sliceState.ppNalUnitParams     = m_nalUnitParams;
+    sliceState.bBrcEnabled         = false;
+    // Disable Panic mode when min/max QP control is on. kernel may disable it, but disable in driver also.
+    sliceState.bRCPanicEnable                = m_panicEnable && (!m_minMaxQpControlEnabled);
+    sliceState.bAcceleratorHeaderPackingCaps = m_encodeParams.bAcceleratorHeaderPackingCaps;
+    sliceState.wFrameFieldHeightInMB         = m_frameFieldHeightInMb;
+
+    return MOS_STATUS_SUCCESS;
+}
+
+MOS_STATUS CodechalVdencAvcState::SetSliceState(
+    CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS &packSlcHeaderParams,
+    MHW_VDBOX_AVC_SLICE_STATE &                 sliceState,
+    uint16_t                                    slcIdx)
+{
+    CODECHAL_ENCODE_FUNCTION_ENTER;
+    auto avcSlcParams = m_avcSliceParams;
+    auto slcData      = m_slcData;
+
+    if (m_currPass == 0)
+    {
+        packSlcHeaderParams.pAvcSliceParams = &avcSlcParams[slcIdx];
+        if (m_acceleratorHeaderPackingCaps)
+        {
+            slcData[slcIdx].SliceOffset = m_bsBuffer.SliceOffset;
+            CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_PackSliceHeader(&packSlcHeaderParams));
+            slcData[slcIdx].BitSize = m_bsBuffer.BitSize;
+        }
+        if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE)
+        {
+            slcData[slcIdx].CmdOffset = slcIdx * m_sliceHeight * m_picWidthInMb * 16 * 4;
+        }
+        else
+        {
+            slcData[slcIdx].CmdOffset = packSlcHeaderParams.pAvcSliceParams->first_mb_in_slice * 16 * 4;
+        }
+    }
+
+    sliceState.pEncodeAvcSliceParams = &avcSlcParams[slcIdx];
+    sliceState.dwDataBufferOffset =
+        m_slcData[slcIdx].CmdOffset + m_mbcodeBottomFieldOffset;
+    sliceState.dwOffset                  = slcData[slcIdx].SliceOffset;
+    sliceState.dwLength                  = slcData[slcIdx].BitSize;
+    sliceState.uiSkipEmulationCheckCount = slcData[slcIdx].SkipEmulationByteCount;
+    sliceState.dwSliceIndex              = slcIdx;
+    sliceState.bFirstPass                = (m_currPass == 0);
+    sliceState.bLastPass                 = (m_currPass == m_numPasses);
+    sliceState.bInsertBeforeSliceHeaders = (slcIdx == 0);
+    sliceState.bVdencInUse               = true;
+    // App handles tail insertion for VDEnc dynamic slice in non-cp case
+    sliceState.bVdencNoTailInsertion = m_vdencNoTailInsertion;
+
+    uint32_t batchBufferForPakSlicesStartOffset =
+        (uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iCurrent;
+
+    if (m_avcRoundingParams != nullptr && m_avcRoundingParams->bEnableCustomRoudingIntra)
+    {
+        sliceState.dwRoundingIntraValue = m_avcRoundingParams->dwRoundingIntra;
+    }
+    else
+    {
+        sliceState.dwRoundingIntraValue = 5;
+    }
+    if (m_avcRoundingParams != nullptr && m_avcRoundingParams->bEnableCustomRoudingInter)
+    {
+        sliceState.bRoundingInterEnable = true;
+        sliceState.dwRoundingValue      = m_avcRoundingParams->dwRoundingInter;
+    }
+    else
+    {
+        sliceState.bRoundingInterEnable = m_roundingInterEnable;
+        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetRounding(m_avcRoundingParams, &sliceState));
+    }
+
+    sliceState.oneOnOneMapping = m_oneOnOneMapping;
+
+    return MOS_STATUS_SUCCESS;
+}
+
 void CodechalVdencAvcState::SetBufferToStorePakStatistics()
 {
     CODECHAL_ENCODE_FUNCTION_ENTER;
@@ -8459,7 +8518,7 @@
         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
             &m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx],
             0,
-            m_hwInterface->m_vdencBrcImgStateBufferSize,
+            GetVdencBRCImgStateBufferSize(),
             3,
             "_ImageStateRead",
             isInput,
@@ -8539,7 +8598,7 @@
         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
             &m_batchBufferForVdencImgStat[0].OsResource,
             0,
-            m_hwInterface->m_vdencBrcImgStateBufferSize,
+            GetVdencBRCImgStateBufferSize(),
             6,
             "_ImageStateWrite",
             isInput,
@@ -8574,6 +8633,11 @@
     return MOS_STATUS_SUCCESS;
 }
 
+uint32_t CodechalVdencAvcState::GetPakVDEncPassDumpSize()
+{
+    return m_mfxInterface->GetAvcImgStateSize() + m_vdencInterface->GetVdencAvcCostStateSize() + m_vdencInterface->GetVdencAvcImgStateSize();
+}
+
 MOS_STATUS CodechalVdencAvcState::DumpEncodeImgStats(
     PMOS_COMMAND_BUFFER cmdbuffer)
 {
@@ -8586,7 +8650,7 @@
         return MOS_STATUS_SUCCESS;
     }
 
-    uint32_t size = m_mfxInterface->GetAvcImgStateSize() + m_vdencInterface->GetVdencAvcCostStateSize() + m_vdencInterface->GetVdencAvcImgStateSize();
+    uint32_t size = GetPakVDEncPassDumpSize();
 
     std::string SurfName = "Pak_VDEnc_Pass[" + std::to_string(static_cast<uint32_t>(m_currPass)) + "]";
 
diff --git a/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.h b/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.h
index a48c97c..b4406da 100644
--- a/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.h
+++ b/media_driver/agnostic/common/codec/hal/codechal_vdenc_avc.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2020, Intel Corporation
+* Copyright (c) 2011-2021, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -775,6 +775,15 @@
     //!
     virtual MOS_STATUS ExecuteMeKernel();
 
+    MOS_STATUS SetCommonSliceState(
+        CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS &packSlcHeaderParams,
+        MHW_VDBOX_AVC_SLICE_STATE &                 sliceState);
+
+    MOS_STATUS SetSliceState(
+        CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS &packSlcHeaderParams,
+        MHW_VDBOX_AVC_SLICE_STATE &                 sliceState,
+        uint16_t                                    slcIdx);
+
 protected:
     // AvcGeneraicState functions
     //!
@@ -918,6 +927,8 @@
 
     virtual uint32_t GetBRCCostantDataSize() { return sizeof(AVCVdencBRCCostantData); }
 
+    virtual uint32_t GetVdencBRCImgStateBufferSize() { return MOS_ALIGN_CEIL(m_hwInterface->m_vdencBrcImgStateBufferSize, CODECHAL_PAGE_SIZE); }
+
     virtual MOS_STATUS FillHucConstData(uint8_t *data, uint8_t picType);
 
     //!
@@ -937,6 +948,10 @@
         PMOS_RESOURCE       presSliceSizeStreamoutBuffer,
         PMOS_COMMAND_BUFFER cmdBuffer) override;
 
+    virtual MOS_STATUS AddVdencBrcImgBuffer(
+        PMOS_RESOURCE             vdencBrcImgBuffer,
+        PMHW_VDBOX_AVC_IMG_PARAMS params);
+
     //!
     //! \brief    Add MI_STORE commands in the command buffer to update DMEM from other HW output buffer if needed
     //!
@@ -1150,6 +1165,8 @@
     virtual MOS_STATUS DumpEncodeImgStats(
         PMOS_COMMAND_BUFFER        cmdbuffer);
 
+    virtual uint32_t GetPakVDEncPassDumpSize();
+
     virtual MOS_STATUS DumpSeqParFile() override;
     virtual MOS_STATUS DumpFrameParFile() override;
 
diff --git a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_generic.h b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_generic.h
index f5f5937..3ec886d 100644
--- a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_generic.h
+++ b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_generic.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017-2018, Intel Corporation
+* Copyright (c) 2017-2021, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -2917,6 +2917,11 @@
         return TMfxCmds::MFX_AVC_IMG_STATE_CMD::byteSize;
     }
 
+    inline uint32_t GetAvcSlcStateSize()
+    {
+        return TMfxCmds::MFX_AVC_SLICE_STATE_CMD::byteSize;
+    }
+
 };
 
 #endif
diff --git a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_interface.h b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_interface.h
index f0714fe..25b4260 100644
--- a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_interface.h
+++ b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_mfx_interface.h
@@ -1069,6 +1069,14 @@
     virtual uint32_t GetAvcImgStateSize() = 0;
 
     //!
+    //! \brief    get AVC slc state size
+    //!
+    //! \return   uint32_t
+    //!           AVC slc state size got
+    //!
+    virtual uint32_t GetAvcSlcStateSize() = 0;
+
+    //!
     //! \brief    Decide Which GPU Node to use for Decode
     //! \details  Client facing function to create gpu context used by decoder
     //! \param    [in] gpuNodeLimit
diff --git a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_generic.h b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_generic.h
index 4bdab28..52e9d1b 100644
--- a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_generic.h
+++ b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_generic.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, Intel Corporation
+* Copyright (c) 2017-2021, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -303,6 +303,10 @@
         return 0;
     }
 
+    inline uint32_t GetVdencAvcSlcStateSize()
+    {
+        return 0;
+    }
 };
 
 #endif
\ No newline at end of file
diff --git a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_interface.h b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_interface.h
index 342e573..8e13f9a 100644
--- a/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_interface.h
+++ b/media_driver/agnostic/common/hw/vdbox/mhw_vdbox_vdenc_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017-2020, Intel Corporation
+* Copyright (c) 2017-2021, Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -316,6 +316,14 @@
     virtual uint32_t GetVdencAvcImgStateSize() = 0;
 
     //!
+    //! \brief    get Vdenc slc state size
+    //!
+    //! \return   uint32_t
+    //!           Vdenc slc state size got
+    //!
+    virtual uint32_t GetVdencAvcSlcStateSize() = 0;
+
+    //!
     //! \brief    get Vdenc cost state size
     //!
     //! \return   uint32_t
diff --git a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.cpp b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.cpp
index 24bb8ab..cefe88c 100644
--- a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.cpp
+++ b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.cpp
@@ -308,7 +308,7 @@
 };
 // clang-format on
 
-struct BrcInitDmem
+struct CodechalVdencAvcStateG12::BrcInitDmem
 {
     uint8_t     BRCFunc_U8;                           // 0: Init; 2: Reset
     uint8_t     OpenSourceEnable_U8;                  // 0: disable opensource, 1: enable opensource
@@ -373,9 +373,8 @@
     uint8_t     INIT_New_DeltaQP_Adaptation_U8;       // = 1 to enable new delta QP adaption
     uint8_t     RSVD2[55];                            // must be zero
 };
-using PBrcInitDmem = struct BrcInitDmem*;
 
-struct BrcUpdateDmem
+struct CodechalVdencAvcStateG12::BrcUpdateDmem
 {
     uint8_t     BRCFunc_U8;                           // =1 for Update, other values are reserved for future use
     uint8_t     RSVD[3];
@@ -455,9 +454,11 @@
     uint8_t      UPD_ROM_CURRENT_U8;        // ROM average of current frame
     uint8_t      UPD_ROM_ZERO_U8;           // ROM zero percentage (255 is 100%)
     uint8_t      UPD_TCBRC_SCENARIO_U8;
-    uint8_t      RSVD2[12];
+    uint8_t      UPD_EnableFineGrainLA;
+    int8_t       UPD_DeltaQpDcOffset;
+    uint16_t     UPD_NumSlicesForRounding;
+    uint8_t      RSVD2[8];
 };
-using PBrcUpdateDmem = struct BrcUpdateDmem*;
 
 // clang-format off
 const uint32_t CodechalVdencAvcStateG12::m_mvCostSkipBiasQPel[3][8] =
@@ -1043,7 +1044,7 @@
     MOS_LOCK_PARAMS lockFlagsWriteOnly;
     memset(&lockFlagsWriteOnly, 0, sizeof(MOS_LOCK_PARAMS));
     lockFlagsWriteOnly.WriteOnly = 1;
-    auto hucVDEncBrcInitDmem     = (PBrcInitDmem)m_osInterface->pfnLockResource(
+    auto hucVDEncBrcInitDmem     = (BrcInitDmem *)m_osInterface->pfnLockResource(
         m_osInterface, &m_resVdencBrcInitDmemBuffer[m_currRecycledBufIdx], &lockFlagsWriteOnly);
 
     CODECHAL_ENCODE_CHK_NULL_RETURN(hucVDEncBrcInitDmem);
@@ -1129,7 +1130,7 @@
     MOS_LOCK_PARAMS lockFlags;
     memset(&lockFlags, 0, sizeof(MOS_LOCK_PARAMS));
     lockFlags.WriteOnly  = 1;
-    auto hucVDEncBrcDmem = (PBrcUpdateDmem)m_osInterface->pfnLockResource(
+    auto hucVDEncBrcDmem = (BrcUpdateDmem *)m_osInterface->pfnLockResource(
         m_osInterface, &m_resVdencBrcUpdateDmemBuffer[m_currRecycledBufIdx][m_currPass], &lockFlags);
     CODECHAL_ENCODE_CHK_NULL_RETURN(hucVDEncBrcDmem);
     SetDmemHuCBrcUpdateImpl<BrcUpdateDmem>(hucVDEncBrcDmem);
@@ -1176,6 +1177,8 @@
 
     hucVDEncBrcDmem->UPD_TCBRC_SCENARIO_U8 = m_avcSeqParam->bAutoMaxPBFrameSizeForSceneChange;
 
+    hucVDEncBrcDmem->UPD_NumSlicesForRounding = GetAdaptiveRoundingNumSlices();
+
     CODECHAL_DEBUG_TOOL(
         CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateBrcUpdateParam(hucVDEncBrcDmem));
         CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpParsedBRCUpdateDmem(hucVDEncBrcDmem));
@@ -1900,7 +1903,7 @@
     CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
 
     // To make sure that DMEM doesn't changed and parsed dump contains all DMEM fields
-    CODECHAL_DEBUG_ASSERT(sizeof(dmem->RSVD2) == 12);
+    CODECHAL_DEBUG_ASSERT(sizeof(dmem->RSVD2) == 8);
 
     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrHuCDmem))
     {
@@ -1985,6 +1988,9 @@
     FIELD_TO_SS(UPD_ROM_CURRENT_U8);
     FIELD_TO_SS(UPD_ROM_ZERO_U8);
     FIELD_TO_SS(UPD_TCBRC_SCENARIO_U8);
+    FIELD_TO_SS(UPD_EnableFineGrainLA);
+    FIELD_TO_SS(UPD_DeltaQpDcOffset);
+    FIELD_TO_SS(UPD_NumSlicesForRounding);
     ARRAY_TO_SS(RSVD2);
 
     std::string bufName = std::string("ENC-HucDmemUpdate_Parsed_PASS") + std::to_string((uint32_t)m_currPass);
diff --git a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.h b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.h
index 3824d60..ea81d2a 100644
--- a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.h
+++ b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_avc_g12.h
@@ -181,6 +181,8 @@
 
    protected:
     class SfdCurbe;
+    struct BrcInitDmem;
+    struct BrcUpdateDmem;
     bool                  m_vdencUltraModeEnable = false;   //!< Enable VDEnc ultra mode
     bool                  m_forcedTCBRC = false;            //!< TCBRC forced instead of LowDelayBRC
 
@@ -207,6 +209,8 @@
 
     virtual void CopyMBQPDataToStreamIn(CODECHAL_VDENC_STREAMIN_STATE* pData, uint8_t* pInputData);
 
+    virtual uint16_t GetAdaptiveRoundingNumSlices() { return 0; }
+
 #if USE_CODECHAL_DEBUG_TOOL
 protected:
     virtual MOS_STATUS PopulateBrcInitParam(
@@ -225,7 +229,6 @@
 
     virtual MOS_STATUS ModifyEncodedFrameSizeWithFakeHeaderSize( PMOS_COMMAND_BUFFER cmdBuffer) override;
 
-private:
     MOS_STATUS DumpParsedBRCInitDmem(
         struct BrcInitDmem* dmem);