﻿/*
* Copyright (c) 2011-2020, 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_avc.cpp
//! \brief    This file implements the base C++ class/interface for AVC DualPipe encoding
//!           to be used across CODECHAL components.
//!

#include "codechal_encode_avc.h"
#include "codechal_encode_wp.h"
#include "codeckrnheader.h"
#include "hal_oca_interface.h"
#include "mos_os_cp_interface_specific.h"

#define CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_DPB_LIST_SIZE       128
#define CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_FINAL_LIST_SIZE     128
#define CODECHAL_ENCODE_AVC_CQP_NUM_OF_PASSES                               2       // 1 additional pass for IPCM
#define CODECHAL_ENCODE_AVC_ICQ_NUM_OF_PASSES                               2       // 1 additional pass for IPCM
#define CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_ROUNDING                  6
#define CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE                                 10240   // 10K is just estimation
#define CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON               52
#define CODECHAL_ENCODE_AVC_SKIP_BIAS_ADJUSTMENT_QP_THRESHOLD               22
#define CODECHAL_ENCODE_AVC_HME_FIRST_STEP                                  0
#define CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP                              1
#define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_32x                             1
#define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_16x                             2
#define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_4x                              2
#define CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_16x                       1
#define CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_4x                        0
#define CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_INTRA_ROUNDING            5

const uint32_t CodechalEncodeAvcEnc::MaxLenSP[NUM_TARGET_USAGE_MODES] =
{
    0, 57, 57, 25, 25, 25, 16, 9
};

const uint32_t CodechalEncodeAvcEnc::FTQBasedSkip[NUM_TARGET_USAGE_MODES] =
{
    0, 3, 3, 3, 3, 3, 3, 0
};

const uint32_t CodechalEncodeAvcEnc::HMEBCombineLen[NUM_TARGET_USAGE_MODES] =
{
    0, 8, 8, 8, 8, 8, 8, 8
};

const uint32_t CodechalEncodeAvcEnc::HMECombineLen[NUM_TARGET_USAGE_MODES] =
{
    0, 8, 8, 8, 8, 8, 16, 8
};

const uint32_t CodechalEncodeAvcEnc::SearchX[NUM_TARGET_USAGE_MODES] =
{
    0, 48, 48, 48, 48, 48, 48, 28
};

const uint32_t CodechalEncodeAvcEnc::SearchY[NUM_TARGET_USAGE_MODES] =
{
    0, 40, 40, 40, 40, 40, 40, 28
};

const uint32_t CodechalEncodeAvcEnc::BSearchX[NUM_TARGET_USAGE_MODES] =
{
    0, 32, 32, 32, 32, 32, 32, 24
};

const uint32_t CodechalEncodeAvcEnc::BSearchY[NUM_TARGET_USAGE_MODES] =
{
    0, 32, 32, 32, 32, 32, 32, 24
};

const uint32_t CodechalEncodeAvcEnc::EnableAdaptiveSearch[NUM_TARGET_USAGE_MODES] =
{
    0, 1, 1, 1, 1, 1, 0, 0
};

const uint32_t CodechalEncodeAvcEnc:: InterRoundingP_TQ[NUM_TARGET_USAGE_MODES] =
{
    0, 3, 3, 3, 3, 3, 3, 3
};

const uint32_t CodechalEncodeAvcEnc:: InterRoundingBRef_TQ[NUM_TARGET_USAGE_MODES] =
{
    0, 2, 2, 2, 2, 2, 2, 2
};

const uint32_t CodechalEncodeAvcEnc:: InterRoundingB_TQ[NUM_TARGET_USAGE_MODES] =
{
    0, 0, 0, 0, 0, 0, 0, 0
};

const uint32_t CodechalEncodeAvcEnc:: TrellisQuantizationEnable[NUM_TARGET_USAGE_MODES] =
{
    0, 1, 0, 0, 0, 0, 0, 0
};

const uint32_t CodechalEncodeAvcEnc:: EnableAdaptiveTrellisQuantization[NUM_TARGET_USAGE_MODES] =
{
    0, 1, 0, 0, 0, 0, 0, 0
};

// Lambda values for Trellis Quantization
const uint32_t CodechalEncodeAvcEnc::TQ_LAMBDA_I_FRAME[CODEC_AVC_NUM_QP][2] =
{
    {0x00070000, 0x00060000},
    {0x00080000, 0x00080000},
    {0x000a0000, 0x00090000},
    {0x000d0000, 0x000c0000},
    {0x00110000, 0x000f0000},
    {0x00150000, 0x00130000},
    {0x001b0000, 0x00180000},
    {0x00220000, 0x001f0000},
    {0x002b0000, 0x00270000},
    {0x00360000, 0x00310000},
    {0x00440000, 0x003e0000},
    {0x00550000, 0x004e0000},
    {0x006c0000, 0x00630000},
    {0x00870000, 0x007d0000},
    {0x00ab0000, 0x009d0000},
    {0x00d70000, 0x00c70000},
    {0x010f0000, 0x00fb0000},
    {0x01560000, 0x013d0000},
    {0x01af0000, 0x01900000},
    {0x021f0000, 0x01f90000},
    {0x02ac0000, 0x027e0000},
    {0x035e0000, 0x03260000},
    {0x043e0000, 0x03fa0000},
    {0x057a0000, 0x05070000},
    {0x06f90000, 0x065a0000},
    {0x08770000, 0x08060000},
    {0x0af50000, 0x0a240000},
    {0x0d720000, 0x0cd10000},
    {0x10ef0000, 0x10340000},
    {0x156a0000, 0x147b0000},
    {0x1ae50000, 0x19e50000},
    {0x225d0000, 0x20be0000},
    {0x2ad50000, 0x29670000},
    {0x36490000, 0x345c0000},
    {0x443b0000, 0x423a0000},
    {0x56290000, 0x53c50000},
    {0x6c930000, 0x69f90000},
    {0x88770000, 0x86130000},
    {0xabd30000, 0xa9a40000},
    {0xd8a60000, 0xd6aa0000},

    // Rounding offsets
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000},
    {0xfffa0000, 0xfffa0000}
};

const uint32_t CodechalEncodeAvcEnc::TQ_LAMBDA_P_FRAME[CODEC_AVC_NUM_QP][2] =
{
    {0x00070009, 0x00060009},
    {0x0008000c, 0x0008000c},
    {0x000a000f, 0x0009000f},
    {0x000d0013, 0x000c0013},
    {0x00110018, 0x000f0018},
    {0x0015001e, 0x0013001e},
    {0x001b0026, 0x00180026},
    {0x00220030, 0x001f0030},
    {0x002b003c, 0x0027003c},
    {0x0036004c, 0x0031004c},
    {0x00440060, 0x003e0060},
    {0x00550079, 0x004e0079},
    {0x006c0099, 0x00630099},
    {0x008700c1, 0x007d00c1},
    {0x00ab00f3, 0x009d00f3},
    {0x00d70132, 0x00c70133},
    {0x010f0181, 0x00fb0183},
    {0x015601e5, 0x013d01e8},
    {0x01af0264, 0x01900268},
    {0x021f0303, 0x01f90309},
    {0x02ac03cb, 0x027e03d5},
    {0x035e04c8, 0x032604d5},
    {0x043e0606, 0x03fa061a},
    {0x057a07c7, 0x050707b3},
    {0x06f909e6, 0x065a09b8},
    {0x08770c05, 0x08060c45},
    {0x0af50f8e, 0x0a240f7e},
    {0x0d721317, 0x0cd1138f},
    {0x10ef180a, 0x103418b2},
    {0x156a1e67, 0x147b1f30},
    {0x1ae5262e, 0x19e52762},
    {0x225d30c9, 0x20be31bd},
    {0x2ad53cce, 0x29673ed2},
    {0x36494d11, 0x345c4f59},
    {0x443b60dd, 0x423a643c},
    {0x56297a51, 0x53c57e9f},
    {0x6c939a22, 0x69f99ff9},
    {0x8877c1ba, 0x8613ca1e},
    {0xabd3ffef, 0xa9a4ffef},
    {0xd8a6ffef, 0xd6aaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef}
};

const uint32_t CodechalEncodeAvcEnc::TQ_LAMBDA_B_FRAME[CODEC_AVC_NUM_QP][2] =
{
    {0x00070009, 0x00060009},
    {0x0008000c, 0x0008000c},
    {0x000a000f, 0x0009000f},
    {0x000d0013, 0x000c0013},
    {0x00110018, 0x000f0018},
    {0x0015001e, 0x0013001e},
    {0x001b0026, 0x00180026},
    {0x00220030, 0x001f0030},
    {0x002b003c, 0x0027003c},
    {0x0036004c, 0x0031004c},
    {0x00440060, 0x003e0060},
    {0x00550079, 0x004e0079},
    {0x006c0099, 0x00630099},
    {0x008700c1, 0x007d00c1},
    {0x00ab00f3, 0x009d00f3},
    {0x00d70132, 0x00c70133},
    {0x010f0181, 0x00fb0183},
    {0x015601e5, 0x013d01e8},
    {0x01af0264, 0x01900268},
    {0x021f0303, 0x01f90309},
    {0x02ac03cb, 0x027e03d5},
    {0x035e04c8, 0x032604d5},
    {0x043e0606, 0x03fa061a},
    {0x057a07c7, 0x050707b3},
    {0x06f909e6, 0x065a09b8},
    {0x08770c05, 0x08060c45},
    {0x0af50f8e, 0x0a240f7e},
    {0x0d721317, 0x0cd1138f},
    {0x10ef180a, 0x103418b2},
    {0x156a1e67, 0x147b1f30},
    {0x1ae5262e, 0x19e52762},
    {0x225d30c9, 0x20be31bd},
    {0x2ad53cce, 0x29673ed2},
    {0x36494d11, 0x345c4f59},
    {0x443b60dd, 0x423a643c},
    {0x56297a51, 0x53c57e9f},
    {0x6c939a22, 0x69f99ff9},
    {0x8877c1ba, 0x8613ca1e},
    {0xabd3ffef, 0xa9a4ffef},
    {0xd8a6ffef, 0xd6aaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef},
    {0xfffaffef, 0xfffaffef}
};

typedef enum _CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_ME_CM
{
    CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE_CM = 0,
    CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE_CM = 1,
    CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE_CM = 1,
    CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE_CM = 2,
    CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION_CM = 3,
    CODECHAL_ENCODE_AVC_ME_RESERVED0_CM = 4,
    CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF_CM = 5,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX0_CM = 6,
    CODECHAL_ENCODE_AVC_ME_RESERVED1_CM = 7,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX1_CM = 8,
    CODECHAL_ENCODE_AVC_ME_RESERVED2_CM = 9,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX2_CM = 10,
    CODECHAL_ENCODE_AVC_ME_RESERVED3_CM = 11,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX3_CM = 12,
    CODECHAL_ENCODE_AVC_ME_RESERVED4_CM = 13,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX4_CM = 14,
    CODECHAL_ENCODE_AVC_ME_RESERVED5_CM = 15,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX5_CM = 16,
    CODECHAL_ENCODE_AVC_ME_RESERVED6_CM = 17,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX6_CM = 18,
    CODECHAL_ENCODE_AVC_ME_RESERVED7_CM = 19,
    CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX7_CM = 20,
    CODECHAL_ENCODE_AVC_ME_RESERVED8_CM = 21,
    CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF_CM = 22,
    CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX0_CM = 23,
    CODECHAL_ENCODE_AVC_ME_RESERVED9_CM = 24,
    CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX1_CM = 25,
    CODECHAL_ENCODE_AVC_ME_VDENC_STREAMIN_CM = 26,
    CODECHAL_ENCODE_AVC_ME_NUM_SURFACES_CM = 27
} CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_ME_CM;

// binding table for State Content Detection
typedef enum _CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_SFD_COMMON
{
    CODECHAL_ENCODE_AVC_SFD_VDENC_INPUT_IMAGE_STATE_COMMON = 0,
    CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON = 1,
    CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON = 2,
    CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON = 3,
    CODECHAL_ENCODE_AVC_SFD_VDENC_OUTPUT_IMAGE_STATE_COMMON = 4,
    CODECHAL_ENCODE_AVC_SFD_NUM_SURFACES = 5
} CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_SFD_COMMON;

// QP is from 0 - 51, pad it to 64 since BRC needs array size to be 64 bytes
const uint8_t CodechalEncodeAvcEnc::IntraScalingFactor_Cm_Common[64] =
{
    0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
    0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
    0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// QP is from 0 - 51, pad it to 64 since BRC needs array size to be 64 bytes
const uint8_t CodechalEncodeAvcEnc::AdaptiveIntraScalingFactor_Cm_Common[64] =
{
    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c,
    0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e,
    0x0e, 0x0e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const uint32_t CodechalEncodeAvcEnc::OldIntraModeCost_Cm_Common[CODEC_AVC_NUM_QP] =
{
    0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a,
    0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a,
    0x2e06001a, 0x2e06001a, 0x2e06001a, 0x2e06001a, 0x3b09001f, 0x3b09001f, 0x3b09001f, 0x3e0c002a,
    0x3e0c002a, 0x3e0c002a, 0x490f002d, 0x4b19002f, 0x4b19002f, 0x4c1b0039, 0x4e1c003a, 0x581e003b,
    0x591f003d, 0x5a28003e, 0x5b2a0048, 0x5c2b0049, 0x5e2c004a, 0x682e004b, 0x692f004d, 0x6a39004e,
    0x6b390058, 0x6d3b0059, 0x6e3c005a, 0x783e005b, 0x793f005d, 0x7a48005e, 0x7b4a0068, 0x7c4b0069,
    0x7e4c006a, 0x884e006b, 0x894f006d, 0x8a59006e
};

const uint32_t CodechalEncodeAvcEnc::MvCost_PSkipAdjustment_Cm_Common[CODEC_AVC_NUM_QP] =
{
    0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500,
    0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500,
    0x190c0a00, 0x190c0a00, 0x190c0a00, 0x190c0a00, 0x1e190f00, 0x1e190f00, 0x1e190f00, 0x291c1a00,
    0x291c1a00, 0x291c1a00, 0x2b1f1d00, 0x2e291f00, 0x2e291f00, 0x382b2900, 0x392c2a00, 0x3a2e2b00,
    0x3b2f2d00, 0x3c382e00, 0x3f3a3800, 0x483b3900, 0x493c3a00, 0x4a3e3b00, 0x4b3f3d00, 0x4d493e00,
    0x4e494800, 0x584b4900, 0x594c4a00, 0x5a4e4b00, 0x5b4f4d00, 0x5d584e00, 0x5e5a5800, 0x685b5900,
    0x695c5a00, 0x6a5e5b00, 0x6b5f5d00, 0x6d695e00
};

const uint16_t CodechalEncodeAvcEnc::SkipVal_B_Common[2][2][64] =
{
    {
        // Block Based Skip = 0 and Transform Flag = 0
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0024,
            0x0024, 0x0060, 0x0060, 0x0099, 0x0099, 0x00cf, 0x00cf, 0x0105,
            0x0105, 0x0141, 0x0141, 0x0183, 0x0183, 0x01ce, 0x01ce, 0x0228,
            0x0228, 0x0291, 0x0291, 0x030c, 0x030c, 0x039f, 0x039f, 0x0447,
            0x0447, 0x050d, 0x050d, 0x05f1, 0x05f1, 0x06f6, 0x06f6, 0x0822,
            0x0822, 0x0972, 0x0972, 0x0aef, 0x0aef, 0x0c96, 0x0c96, 0x0e70,
            0x0e70, 0x107a, 0x107a, 0x1284, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        },
    // Block Based Skip = 0 and Transform Flag = 1
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0024,
            0x0024, 0x0060, 0x0060, 0x0099, 0x0099, 0x00cf, 0x00cf, 0x0105,
            0x0105, 0x0141, 0x0141, 0x0183, 0x0183, 0x01ce, 0x01ce, 0x0228,
            0x0228, 0x0291, 0x0291, 0x030c, 0x030c, 0x039f, 0x039f, 0x0447,
            0x0447, 0x050d, 0x050d, 0x05f1, 0x05f1, 0x06f6, 0x06f6, 0x0822,
            0x0822, 0x0972, 0x0972, 0x0aef, 0x0aef, 0x0c96, 0x0c96, 0x0e70,
            0x0e70, 0x107a, 0x107a, 0x1284, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        }
    },
    {
        // Block Based Skip = 1 and Transform Flag = 0
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006,
            0x0006, 0x0010, 0x0010, 0x0019, 0x0019, 0x0022, 0x0022, 0x002b,
            0x002b, 0x0035, 0x0035, 0x0040, 0x0040, 0x004d, 0x004d, 0x005c,
            0x005c, 0x006d, 0x006d, 0x0082, 0x0082, 0x009a, 0x009a, 0x00b6,
            0x00b6, 0x00d7, 0x00d7, 0x00fd, 0x00fd, 0x0129, 0x0129, 0x015b,
            0x015b, 0x0193, 0x0193, 0x01d2, 0x01d2, 0x0219, 0x0219, 0x0268,
            0x0268, 0x02bf, 0x02bf, 0x0316, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        },
    // Block Based Skip = 1 and Transform Flag = 1
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c,
            0x000c, 0x0020, 0x0020, 0x0033, 0x0033, 0x0045, 0x0045, 0x0057,
            0x0057, 0x006b, 0x006b, 0x0081, 0x0081, 0x009a, 0x009a, 0x00b8,
            0x00b8, 0x00db, 0x00db, 0x0104, 0x0104, 0x0135, 0x0135, 0x016d,
            0x016d, 0x01af, 0x01af, 0x01fb, 0x01fb, 0x0252, 0x0252, 0x02b6,
            0x02b6, 0x0326, 0x0326, 0x03a5, 0x03a5, 0x0432, 0x0432, 0x04d0,
            0x04d0, 0x057e, 0x057e, 0x062c, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        }
    }
};

// AVC MBEnc SkipVal Table, index [BlockBasedSkip][TransformFlag][SliceQP]
// QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes.
const uint16_t CodechalEncodeAvcEnc::SkipVal_P_Common[2][2][64] =
{
    {
        // Block Based Skip = 0 and Transform Flag = 0
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006,
            0x0006, 0x000c, 0x000c, 0x0015, 0x0015, 0x0021, 0x0021, 0x0033,
            0x0033, 0x004b, 0x004b, 0x0069, 0x0069, 0x0096, 0x0096, 0x00cc,
            0x00cc, 0x0111, 0x0111, 0x0165, 0x0165, 0x01cb, 0x01cb, 0x0246,
            0x0246, 0x02d3, 0x02d3, 0x0378, 0x0378, 0x0438, 0x0438, 0x0510,
            0x0510, 0x0603, 0x0603, 0x0714, 0x0714, 0x0846, 0x0846, 0x0999,
            0x0999, 0x0b10, 0x0b10, 0x0c3c, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        },

    // Block Based Skip = 0 and Transform Flag = 1
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006,
            0x0006, 0x000c, 0x000c, 0x0015, 0x0015, 0x0021, 0x0021, 0x0033,
            0x0033, 0x004b, 0x004b, 0x0069, 0x0069, 0x0096, 0x0096, 0x00cc,
            0x00cc, 0x0111, 0x0111, 0x0165, 0x0165, 0x01cb, 0x01cb, 0x0246,
            0x0246, 0x02d3, 0x02d3, 0x0378, 0x0378, 0x0438, 0x0438, 0x0510,
            0x0510, 0x0603, 0x0603, 0x0714, 0x0714, 0x0846, 0x0846, 0x0999,
            0x0999, 0x0b10, 0x0b10, 0x0c3c, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        }
    },
    {
        // Block Based Skip = 1 and Transform Flag = 0
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
            0x0001, 0x0002, 0x0002, 0x0003, 0x0003, 0x0005, 0x0005, 0x0008,
            0x0008, 0x000c, 0x000c, 0x0011, 0x0011, 0x0019, 0x0019, 0x0022,
            0x0022, 0x002d, 0x002d, 0x003b, 0x003b, 0x004c, 0x004c, 0x0061,
            0x0061, 0x0078, 0x0078, 0x0094, 0x0094, 0x00b4, 0x00b4, 0x00d8,
            0x00d8, 0x0100, 0x0100, 0x012e, 0x012e, 0x0161, 0x0161, 0x0199,
            0x0199, 0x01d8, 0x01d8, 0x020a, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        },

    // Block Based Skip = 1 and Transform Flag = 1
        {
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002,
            0x0002, 0x0004, 0x0004, 0x0007, 0x0007, 0x000b, 0x000b, 0x0011,
            0x0011, 0x0019, 0x0019, 0x0023, 0x0023, 0x0032, 0x0032, 0x0044,
            0x0044, 0x005b, 0x005b, 0x0077, 0x0077, 0x0099, 0x0099, 0x00c2,
            0x00c2, 0x00f1, 0x00f1, 0x0128, 0x0128, 0x0168, 0x0168, 0x01b0,
            0x01b0, 0x0201, 0x0201, 0x025c, 0x025c, 0x02c2, 0x02c2, 0x0333,
            0x0333, 0x03b0, 0x03b0, 0x0414, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        }
    }
};

const uint32_t CodechalEncodeAvcEnc::PreProcFtqLut_Cm_Common[CODEC_AVC_NUM_QP][16] =
{
    //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3),   MVCOST(4),   QP(5),       FTQ Thds(6), FTQ Thds(7), RefCost(8),  SkipVal(9),  IntraSF(10) ,Zero(11),  Zero(12),   Zero(13),   Zero(14) ,  Zero(15)
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff010101,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff020202,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff030303,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff040404,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff050505,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff060606,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff070707,  0x01010001,  0x01010101,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff080808,  0x01010001,  0x01010101,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff090909,  0x03030003,  0x03030303,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff0a0a0a,  0x03030003,  0x03030303,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff0b0b0b,  0x06060006,  0x06060606,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff0c0c0c,  0x06060006,  0x06060606,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff0d0d0d,  0x08080008,  0x08080808,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff0e0e0e,  0x08080008,  0x08080808,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff0f0f0f,  0x0b0b000b,  0x0b0b0b0b,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff101010,  0x0b0b000b,  0x0b0b0b0b,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff111111,  0x0d0d000d,  0x0d0d0d0d,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff121212,  0x0d0d000d,  0x0d0d0d0d,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff131313,  0x10100010,  0x10101010,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff141414,  0x10100010,  0x10101010,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff151515,  0x13130013,  0x13131313,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff161616,  0x13130013,  0x13131313,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff171717,  0x16160016,  0x16161616,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff181818,  0x16160016,  0x16161616,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff191919,  0x1a1a001a,  0x1a1a1a1a,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff1a1a1a,  0x1a1a001a,  0x1a1a1a1a,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff1b1b1b,  0x1e1e001e,  0x1e1e1e1e,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff1c1c1c,  0x1e1e001e,  0x1e1e1e1e,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff1d1d1d,  0x22220022,  0x22222222,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff1e1e1e,  0x22220022,  0x22222222,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff1f1f1f,  0x27270027,  0x27272727,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff202020,  0x27270027,  0x27272727,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff212121,  0x2c2c002c,  0x2c2c2c2c,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff222222,  0x2c2c002c,  0x2c2c2c2c,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff232323,  0x32320032,  0x32323232,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff242424,  0x32320032,  0x32323232,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff252525,  0x38380038,  0x38383838,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff262626,  0x38380038,  0x38383838,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff272727,  0x3e3e003e,  0x3e3e3e3e,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff282828,  0x3e3e003e,  0x3e3e3e3e,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff292929,  0x45450045,  0x45454545,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff2a2a2a,  0x45450045,  0x45454545,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff2b2b2b,  0x4d4d004d,  0x4d4d4d4d,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff2c2c2c,  0x4d4d004d,  0x4d4d4d4d,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff2d2d2d,  0x55550055,  0x55555555,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff2e2e2e,  0x55550055,  0x55555555,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff2f2f2f,  0x5e5e005e,  0x5e5e5e5e,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff303030,  0x5e5e005e,  0x5e5e5e5e,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff313131,  0x68680068,  0x68686868,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff323232,  0x68680068,  0x68686868,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
    { 0x00000000,   0x00000000,  0x00000000,  0x00000000,  0x00000000,  0xff333333,  0x73730073,  0x73737373,  0x00000000,  0x00000000,  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
};

// SkipVal (DW offset 9) in the following table needs to be changed by Driver based on the BlockbasedSkip and Transform Flag.
// Kernel indexes this table based on the MB QP. it's different with g75, but mainline did not support g75 anymore
const uint32_t CodechalEncodeAvcEnc::MBBrcConstantData_Cm_Common[3][CODEC_AVC_NUM_QP][16] =
{
    //I-slice
    {
        //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3),   MVCOST(4),   QP(5),       FTQ Thds(6), FTQ Thds(7), RefCost(8),  SkipVal(9),  IntraSF(10) ,Zero(11),  Zero(12),   Zero(13),   Zero(14) ,  Zero(15)
        { 0x0d000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x0f000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x19000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x1a000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x1b000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff040404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x1c000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x1e000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x28000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff070707, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x29000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff080808, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x2a00000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff090909, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x2b00000b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0a0a0a, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x2c00000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0b0b0b, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x2e00000e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0c0c0c, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x38000018, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0d0d0d, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x39000019, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0e0e0e, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a00001b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3b00001c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff101010, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3c00001d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff111111, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3e00001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff121212, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x48020028, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff131313, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x49020029, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff141414, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4a03002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff151515, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4b03002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff161616, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4c04002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff171717, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4e04002c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff181818, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5805002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff191919, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5905002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5a06002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5b07002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5c080039, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1d1d1d, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5e09003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1e1e1e, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6828003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1f1f1f, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6929003b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff202020, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6a2a003c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff212121, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6b2c003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff222222, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6c3a003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff232323, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6e3b0048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff242424, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x783c0049, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff252525, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x793e004a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff262626, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7a3e004b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff272727, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7b48004c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff282828, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7c49004e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff292929, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7e4a0058, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2a2a2a, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x884d0059, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x894f005a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8a58005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2d2d2d, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8b59005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2e2e2e, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8c5c005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8e5d005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff303030, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f5f005d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff313131, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f68005f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff323232, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f690068, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff333333, 0x73730073, 0x73737373, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
    },
    //P-slice
    {
        //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3),   MVCOST(4),   QP(5),       FTQ Thds(6), FTQ Thds(7), RefCost(8),  SkipVal(9),  IntraSF(10) ,Zero(11),  Zero(12),   Zero(13),   Zero(14) ,  Zero(15)
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff040404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff070707, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff080808, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff090909, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff131313, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff141414, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff151515, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff161616, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff171717, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff181818, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5b493d29, 0x281c0d2b, 0x001a001e, 0x2b1d1a05, 0x39392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5f4c492c, 0x2c28192f, 0x001e002a, 0x38291e07, 0x3d3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x694e4a2e, 0x2d291b39, 0x0028002b, 0x392a2808, 0x3f3e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6a584b38, 0x2f2a1c3a, 0x0029002c, 0x3a2b2909, 0x48483e3b, 0xff1f1f1f, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6b594d39, 0x382c1d3b, 0x002a002e, 0x3b2d2a0a, 0x49493f3d, 0xff202020, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6c5a4e3a, 0x392d1f3c, 0x002b002f, 0x3c2e2b0b, 0x4a4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6e5b583b, 0x3b2f293e, 0x002d0039, 0x3f382d0d, 0x4c4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6f5c593c, 0x3c38293f, 0x002e003a, 0x48392e0e, 0x4d4c4b49, 0xff232323, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x795e5a3e, 0x3d392b49, 0x0038003b, 0x493a3818, 0x4f4e4c4a, 0xff242424, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7a685b48, 0x3f3a2c4a, 0x0039003c, 0x4a3b3919, 0x58584e4b, 0xff252525, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7b695d49, 0x483c2d4b, 0x003a003e, 0x4b3d3a1a, 0x59594f4d, 0xff262626, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7d6a5e4a, 0x4a3d2f4c, 0x003c0048, 0x4d3e3c1c, 0x5b5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7e6b684b, 0x4a3e384d, 0x003d0049, 0x4e483d1d, 0x5c5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x886d694d, 0x4c483a4f, 0x003f004a, 0x58493f1f, 0x5e5d5b59, 0xff292929, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x896e6a4e, 0x4d493b59, 0x0048004b, 0x594a4828, 0x5f5e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8a786b58, 0x4f4a3c5a, 0x0049004c, 0x5a4b4929, 0x68685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8b796d59, 0x584c3d5b, 0x004a004e, 0x5b4d4a2a, 0x69695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8c7a6e5a, 0x594d3f5c, 0x004b004f, 0x5d4e4b2b, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8e7b785b, 0x5b4f485e, 0x004d0059, 0x5e584d2d, 0x6c6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f7c795c, 0x5c58495f, 0x004e005a, 0x68594e2e, 0x6d6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f7e7a5e, 0x5d594b69, 0x0058005b, 0x695a5838, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f887b68, 0x5f5a4c6a, 0x0059005c, 0x6a5b5939, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f897d69, 0x685c4d6b, 0x005a005e, 0x6b5d5a3a, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f8a7e6a, 0x695d4f6c, 0x005b0068, 0x6d5e5b3b, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
    },
    //B-slice
    {
        //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3),   MVCOST(4),   QP(5),       FTQ Thds(6), FTQ Thds(7), RefCost(8),  SkipVal(9),  IntraSF(10) ,Zero(11),  Zero(12),   Zero(13),   Zero(14) ,  Zero(15)
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff040404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff070707, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff080808, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff090909, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff131313, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff141414, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff151515, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff161616, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff171717, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff181818, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5d4d4b29, 0x2d2b282f, 0x001a0a1f, 0x1f0a0a00, 0x3a392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x69594f2c, 0x392f2b3b, 0x001e0e2b, 0x2b0e0e00, 0x3e3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6a5a592e, 0x3b392d3c, 0x0028182c, 0x2c181800, 0x483e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6b5b5a38, 0x3c3a2f3e, 0x0029192e, 0x2e191900, 0x49483e3b, 0xff1f1f1f, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6d5d5b39, 0x3d3b383f, 0x002a1a2f, 0x2f1a1a00, 0x4a493f3d, 0xff202020, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x6e5e5c3a, 0x3e3c3948, 0x002b1b38, 0x381b1b00, 0x4b4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x78685e3b, 0x493e3b4a, 0x002d1d3a, 0x3a1d1d00, 0x4d4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x79695f3c, 0x493f3b4b, 0x002e1e3b, 0x3b1e1e00, 0x4e4c4b49, 0xff232323, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7a6a693e, 0x4b493d4c, 0x0038283c, 0x3c282800, 0x584e4c4a, 0xff242424, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7b6b6a48, 0x4c4a3f4e, 0x0039293e, 0x3e292900, 0x59584e4b, 0xff252525, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7d6d6b49, 0x4d4b484f, 0x003a2a3f, 0x3f2a2a00, 0x5a594f4d, 0xff262626, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x7e6e6c4a, 0x4f4c4959, 0x003c2c49, 0x492c2c00, 0x5c5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x88786d4b, 0x584d4a59, 0x003d2d49, 0x492d2d00, 0x5d5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x89796f4d, 0x5a4f4c5b, 0x003f2f4b, 0x4b2f2f00, 0x5f5d5b59, 0xff292929, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8a7a794e, 0x5b594d5c, 0x0048384c, 0x4c383800, 0x685e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8b7b7a58, 0x5c5a4f5e, 0x0049394e, 0x4e393900, 0x69685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8d7d7b59, 0x5d5b585f, 0x004a3a4f, 0x4f3a3a00, 0x6a695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8e7e7c5a, 0x5f5c5968, 0x004b3b58, 0x583b3b00, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f887e5b, 0x685e5a6a, 0x004d3d5a, 0x5a3d3d00, 0x6d6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f897f5c, 0x695f5c6b, 0x004e3e5b, 0x5b3e3e00, 0x6e6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f8a895e, 0x6b695d6c, 0x0058485c, 0x5c484800, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f8b8a68, 0x6c6a5f6e, 0x0059495e, 0x5e494900, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f8d8b69, 0x6d6b686f, 0x005a4a5f, 0x5f4a4a00, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
        { 0x8f8e8c6a, 0x6f6c6979, 0x005b4b69, 0x694b4b00, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
    }
};

// AVC MBEnc ModeCost and MVCost tables, index [CodingType][QP] and
const uint32_t CodechalEncodeAvcEnc::ModeMvCost_Common[3][CODEC_AVC_NUM_QP][8] =
{
    // I-Frame
    {
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff010101, 0x00000000, 0x00000000 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff020202, 0x00000000, 0x00000000 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff030303, 0x00000000, 0x00000000 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff040404, 0x00000000, 0x00000000 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff050505, 0x00000000, 0x00000000 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff060606, 0x00000000, 0x00000000 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff070707, 0x01010001, 0x01010101 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff080808, 0x01010001, 0x01010101 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff090909, 0x03030003, 0x03030303 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0a0a0a, 0x03030003, 0x03030303 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0b0b0b, 0x06060006, 0x06060606 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0c0c0c, 0x06060006, 0x06060606 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0d0d0d, 0x08080008, 0x08080808 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0e0e0e, 0x08080008, 0x08080808 },
        { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b },
        { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff101010, 0x0b0b000b, 0x0b0b0b0b },
        { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff111111, 0x0d0d000d, 0x0d0d0d0d },
        { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff121212, 0x0d0d000d, 0x0d0d0d0d },
        { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff131313, 0x10100010, 0x10101010 },
        { 0x3b09001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff141414, 0x10100010, 0x10101010 },
        { 0x3b09001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff151515, 0x13130013, 0x13131313 },
        { 0x3b09001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff161616, 0x13130013, 0x13131313 },
        { 0x3e0c002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff171717, 0x16160016, 0x16161616 },
        { 0x3e0c002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff181818, 0x16160016, 0x16161616 },
        { 0x3e0c002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff191919, 0x1a1a001a, 0x1a1a1a1a },
        { 0x490f002d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a },
        { 0x4b19002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e },
        { 0x4b19002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e },
        { 0x4c1b0039, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1d1d1d, 0x22220022, 0x22222222 },
        { 0x4e1c003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1e1e1e, 0x22220022, 0x22222222 },
        { 0x581e003b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1f1f1f, 0x27270027, 0x27272727 },
        { 0x591f003d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff202020, 0x27270027, 0x27272727 },
        { 0x5a28003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff212121, 0x2c2c002c, 0x2c2c2c2c },
        { 0x5b2a0048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff222222, 0x2c2c002c, 0x2c2c2c2c },
        { 0x5c2b0049, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff232323, 0x32320032, 0x32323232 },
        { 0x5e2c004a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff242424, 0x32320032, 0x32323232 },
        { 0x682e004b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff252525, 0x38380038, 0x38383838 },
        { 0x692f004d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff262626, 0x38380038, 0x38383838 },
        { 0x6a39004e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff272727, 0x3e3e003e, 0x3e3e3e3e },
        { 0x6b390058, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff282828, 0x3e3e003e, 0x3e3e3e3e },
        { 0x6d3b0059, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff292929, 0x45450045, 0x45454545 },
        { 0x6e3c005a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2a2a2a, 0x45450045, 0x45454545 },
        { 0x783e005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d },
        { 0x793f005d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d },
        { 0x7a48005e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2d2d2d, 0x55550055, 0x55555555 },
        { 0x7b4a0068, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2e2e2e, 0x55550055, 0x55555555 },
        { 0x7c4b0069, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e },
        { 0x7e4c006a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff303030, 0x5e5e005e, 0x5e5e5e5e },
        { 0x884e006b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff313131, 0x68680068, 0x68686868 },
        { 0x894f006d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff323232, 0x68680068, 0x68686868 },
        { 0x8a59006e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff333333, 0x73730073, 0x73737373 },
    },
    // P-Frame
    {
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff000000, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff010101, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff020202, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff030303, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff040404, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff050505, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff060606, 0x00000000, 0x00000000 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff070707, 0x01010001, 0x01010101 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff080808, 0x01010001, 0x01010101 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff090909, 0x03030003, 0x03030303 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 },
        { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d },
        { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff131313, 0x10100010, 0x10101010 },
        { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff141414, 0x10100010, 0x10101010 },
        { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff151515, 0x13130013, 0x13131313 },
        { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff161616, 0x13130013, 0x13131313 },
        { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff171717, 0x16160016, 0x16161616 },
        { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff181818, 0x16160016, 0x16161616 },
        { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a },
        { 0x5b493d29, 0x281c0d2b, 0x001a001e, 0x2b1d1a05, 0x39392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a },
        { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e },
        { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e },
        { 0x5f4c492c, 0x2c28192f, 0x001e002a, 0x38291e07, 0x3d3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 },
        { 0x694e4a2e, 0x2d291b39, 0x0028002b, 0x392a2808, 0x3f3e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 },
        { 0x6a584b38, 0x2f2a1c3a, 0x0029002c, 0x3a2b2909, 0x48483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 },
        { 0x6b594d39, 0x382c1d3b, 0x002a002e, 0x3b2d2a0a, 0x49493f3d, 0xff202020, 0x27270027, 0x27272727 },
        { 0x6c5a4e3a, 0x392d1f3c, 0x002b002f, 0x3c2e2b0b, 0x4a4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c },
        { 0x6e5b583b, 0x3b2f293e, 0x002d0039, 0x3f382d0d, 0x4c4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c },
        { 0x6f5c593c, 0x3c38293f, 0x002e003a, 0x48392e0e, 0x4d4c4b49, 0xff232323, 0x32320032, 0x32323232 },
        { 0x795e5a3e, 0x3d392b49, 0x0038003b, 0x493a3818, 0x4f4e4c4a, 0xff242424, 0x32320032, 0x32323232 },
        { 0x7a685b48, 0x3f3a2c4a, 0x0039003c, 0x4a3b3919, 0x58584e4b, 0xff252525, 0x38380038, 0x38383838 },
        { 0x7b695d49, 0x483c2d4b, 0x003a003e, 0x4b3d3a1a, 0x59594f4d, 0xff262626, 0x38380038, 0x38383838 },
        { 0x7d6a5e4a, 0x4a3d2f4c, 0x003c0048, 0x4d3e3c1c, 0x5b5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e },
        { 0x7e6b684b, 0x4a3e384d, 0x003d0049, 0x4e483d1d, 0x5c5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e },
        { 0x886d694d, 0x4c483a4f, 0x003f004a, 0x58493f1f, 0x5e5d5b59, 0xff292929, 0x45450045, 0x45454545 },
        { 0x896e6a4e, 0x4d493b59, 0x0048004b, 0x594a4828, 0x5f5e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 },
        { 0x8a786b58, 0x4f4a3c5a, 0x0049004c, 0x5a4b4929, 0x68685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d },
        { 0x8b796d59, 0x584c3d5b, 0x004a004e, 0x5b4d4a2a, 0x69695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d },
        { 0x8c7a6e5a, 0x594d3f5c, 0x004b004f, 0x5d4e4b2b, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 },
        { 0x8e7b785b, 0x5b4f485e, 0x004d0059, 0x5e584d2d, 0x6c6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 },
        { 0x8f7c795c, 0x5c58495f, 0x004e005a, 0x68594e2e, 0x6d6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e },
        { 0x8f7e7a5e, 0x5d594b69, 0x0058005b, 0x695a5838, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e },
        { 0x8f887b68, 0x5f5a4c6a, 0x0059005c, 0x6a5b5939, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 },
        { 0x8f897d69, 0x685c4d6b, 0x005a005e, 0x6b5d5a3a, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 },
        { 0x8f8a7e6a, 0x695d4f6c, 0x005b0068, 0x6d5e5b3b, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 },
    },
    // B-Frame
    {
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff000000, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff010101, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff020202, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff030303, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff040404, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff050505, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff060606, 0x00000000, 0x00000000 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff070707, 0x01010001, 0x01010101 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff080808, 0x01010001, 0x01010101 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff090909, 0x03030003, 0x03030303 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 },
        { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d },
        { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff131313, 0x10100010, 0x10101010 },
        { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff141414, 0x10100010, 0x10101010 },
        { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff151515, 0x13130013, 0x13131313 },
        { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff161616, 0x13130013, 0x13131313 },
        { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff171717, 0x16160016, 0x16161616 },
        { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff181818, 0x16160016, 0x16161616 },
        { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a },
        { 0x5d4d4b29, 0x2d2b282f, 0x001a0a1f, 0x1f0a0a00, 0x3a392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a },
        { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e },
        { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e },
        { 0x69594f2c, 0x392f2b3b, 0x001e0e2b, 0x2b0e0e00, 0x3e3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 },
        { 0x6a5a592e, 0x3b392d3c, 0x0028182c, 0x2c181800, 0x483e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 },
        { 0x6b5b5a38, 0x3c3a2f3e, 0x0029192e, 0x2e191900, 0x49483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 },
        { 0x6d5d5b39, 0x3d3b383f, 0x002a1a2f, 0x2f1a1a00, 0x4a493f3d, 0xff202020, 0x27270027, 0x27272727 },
        { 0x6e5e5c3a, 0x3e3c3948, 0x002b1b38, 0x381b1b00, 0x4b4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c },
        { 0x78685e3b, 0x493e3b4a, 0x002d1d3a, 0x3a1d1d00, 0x4d4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c },
        { 0x79695f3c, 0x493f3b4b, 0x002e1e3b, 0x3b1e1e00, 0x4e4c4b49, 0xff232323, 0x32320032, 0x32323232 },
        { 0x7a6a693e, 0x4b493d4c, 0x0038283c, 0x3c282800, 0x584e4c4a, 0xff242424, 0x32320032, 0x32323232 },
        { 0x7b6b6a48, 0x4c4a3f4e, 0x0039293e, 0x3e292900, 0x59584e4b, 0xff252525, 0x38380038, 0x38383838 },
        { 0x7d6d6b49, 0x4d4b484f, 0x003a2a3f, 0x3f2a2a00, 0x5a594f4d, 0xff262626, 0x38380038, 0x38383838 },
        { 0x7e6e6c4a, 0x4f4c4959, 0x003c2c49, 0x492c2c00, 0x5c5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e },
        { 0x88786d4b, 0x584d4a59, 0x003d2d49, 0x492d2d00, 0x5d5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e },
        { 0x89796f4d, 0x5a4f4c5b, 0x003f2f4b, 0x4b2f2f00, 0x5f5d5b59, 0xff292929, 0x45450045, 0x45454545 },
        { 0x8a7a794e, 0x5b594d5c, 0x0048384c, 0x4c383800, 0x685e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 },
        { 0x8b7b7a58, 0x5c5a4f5e, 0x0049394e, 0x4e393900, 0x69685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d },
        { 0x8d7d7b59, 0x5d5b585f, 0x004a3a4f, 0x4f3a3a00, 0x6a695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d },
        { 0x8e7e7c5a, 0x5f5c5968, 0x004b3b58, 0x583b3b00, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 },
        { 0x8f887e5b, 0x685e5a6a, 0x004d3d5a, 0x5a3d3d00, 0x6d6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 },
        { 0x8f897f5c, 0x695f5c6b, 0x004e3e5b, 0x5b3e3e00, 0x6e6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e },
        { 0x8f8a895e, 0x6b695d6c, 0x0058485c, 0x5c484800, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e },
        { 0x8f8b8a68, 0x6c6a5f6e, 0x0059495e, 0x5e494900, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 },
        { 0x8f8d8b69, 0x6d6b686f, 0x005a4a5f, 0x5f4a4a00, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 },
        { 0x8f8e8c6a, 0x6f6c6979, 0x005b4b69, 0x694b4b00, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 },
    }
};

// AVC MBEnc RefCost tables, index [CodingType][QP]
// QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes
const uint16_t CodechalEncodeAvcEnc::RefCost_Common[3][64] =
{
    // I-frame
    {
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000
    },
    // P-slice
    {
        0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
        0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 0x0008, 0x0008, 0x0008,
        0x000C, 0x000C, 0x000C, 0x0010, 0x0010, 0x0010, 0x0014, 0x0018, 0x0018, 0x001C,
        0x0020, 0x0024, 0x0028, 0x002C, 0x0034, 0x0038, 0x0040, 0x0048, 0x0050, 0x005C,
        0x0064, 0x0074, 0x0080, 0x0090, 0x00A0, 0x00B4, 0x00CC, 0x00E4, 0x0100, 0x0120,
        0x0144, 0x016C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000
    },
    //B-slice
    {
        0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
        0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 0x0008, 0x0008, 0x0008,
        0x000C, 0x000C, 0x000C, 0x0010, 0x0010, 0x0010, 0x0014, 0x0018, 0x0018, 0x001C,
        0x0020, 0x0024, 0x0028, 0x002C, 0x0034, 0x0038, 0x0040, 0x0048, 0x0050, 0x005C,
        0x0064, 0x0074, 0x0080, 0x0090, 0x00A0, 0x00B4, 0x00CC, 0x00E4, 0x0100, 0x0120,
        0x0144, 0x016C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        0x0000, 0x0000, 0x0000, 0x0000
    }
};

const uint8_t CodechalEncodeAvcEnc::MaxRefIdx0_Progressive_4K[NUM_TARGET_USAGE_MODES] =
{
    0, 3, 3, 2, 2, 2, 0, 0
};

const uint8_t CodechalEncodeAvcEnc::MaxRefIdx0[NUM_TARGET_USAGE_MODES] =
{
    0, 7, 5, 2, 2, 2, 0, 0
};

const uint8_t CodechalEncodeAvcEnc::MaxBRefIdx0[NUM_TARGET_USAGE_MODES] =
{
    0, 3, 3, 1, 1, 1, 0, 0
};

const uint8_t CodechalEncodeAvcEnc::MaxRefIdx1[NUM_TARGET_USAGE_MODES] =
{
    0, 1, 1, 1, 1, 1, 0, 0
};

const uint32_t CodechalEncodeAvcEnc::SuperHME[NUM_TARGET_USAGE_MODES] =
{
    0, 1, 1, 1, 1, 1, 1, 1
};

const uint32_t CodechalEncodeAvcEnc::UltraHME[NUM_TARGET_USAGE_MODES] =
{
    0, 1, 1, 1, 1, 1, 1, 0
};

const uint32_t CodechalEncodeAvcEnc::ModeMvCost_Cm[3][52][8] =
{
// I-Frame
{
    { 0x0d000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000 },
    { 0x0f000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff010101, 0x00000000, 0x00000000 },
    { 0x19000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff020202, 0x00000000, 0x00000000 },
    { 0x1a000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff030303, 0x00000000, 0x00000000 },
    { 0x1b000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff040404, 0x00000000, 0x00000000 },
    { 0x1c000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff050505, 0x00000000, 0x00000000 },
    { 0x1e000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff060606, 0x00000000, 0x00000000 },
    { 0x28000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff070707, 0x01010001, 0x01010101 },
    { 0x29000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff080808, 0x01010001, 0x01010101 },
    { 0x2a00000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff090909, 0x03030003, 0x03030303 },
    { 0x2b00000b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0a0a0a, 0x03030003, 0x03030303 },
    { 0x2c00000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0b0b0b, 0x06060006, 0x06060606 },
    { 0x2e00000e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0c0c0c, 0x06060006, 0x06060606 },
    { 0x38000018, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0d0d0d, 0x08080008, 0x08080808 },
    { 0x39000019, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0e0e0e, 0x08080008, 0x08080808 },
    { 0x3a00001b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b },
    { 0x3b00001c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff101010, 0x0b0b000b, 0x0b0b0b0b },
    { 0x3c00001d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff111111, 0x0d0d000d, 0x0d0d0d0d },
    { 0x3e00001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff121212, 0x0d0d000d, 0x0d0d0d0d },
    { 0x48020028, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff131313, 0x10100010, 0x10101010 },
    { 0x49020029, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff141414, 0x10100010, 0x10101010 },
    { 0x4a03002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff151515, 0x13130013, 0x13131313 },
    { 0x4b03002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff161616, 0x13130013, 0x13131313 },
    { 0x4c04002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff171717, 0x16160016, 0x16161616 },
    { 0x4e04002c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff181818, 0x16160016, 0x16161616 },
    { 0x5805002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff191919, 0x1a1a001a, 0x1a1a1a1a },
    { 0x5905002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a },
    { 0x5a06002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e },
    { 0x5b07002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e },
    { 0x5c080039, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1d1d1d, 0x22220022, 0x22222222 },
    { 0x5e09003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1e1e1e, 0x22220022, 0x22222222 },
    { 0x6828003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1f1f1f, 0x27270027, 0x27272727 },
    { 0x6929003b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff202020, 0x27270027, 0x27272727 },
    { 0x6a2a003c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff212121, 0x2c2c002c, 0x2c2c2c2c },
    { 0x6b2c003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff222222, 0x2c2c002c, 0x2c2c2c2c },
    { 0x6c3a003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff232323, 0x32320032, 0x32323232 },
    { 0x6e3b0048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff242424, 0x32320032, 0x32323232 },
    { 0x783c0049, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff252525, 0x38380038, 0x38383838 },
    { 0x793e004a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff262626, 0x38380038, 0x38383838 },
    { 0x7a3e004b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff272727, 0x3e3e003e, 0x3e3e3e3e },
    { 0x7b48004c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff282828, 0x3e3e003e, 0x3e3e3e3e },
    { 0x7c49004e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff292929, 0x45450045, 0x45454545 },
    { 0x7e4a0058, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2a2a2a, 0x45450045, 0x45454545 },
    { 0x884d0059, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d },
    { 0x894f005a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d },
    { 0x8a58005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2d2d2d, 0x55550055, 0x55555555 },
    { 0x8b59005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2e2e2e, 0x55550055, 0x55555555 },
    { 0x8c5c005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e },
    { 0x8e5d005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff303030, 0x5e5e005e, 0x5e5e5e5e },
    { 0x8f5f005d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff313131, 0x68680068, 0x68686868 },
    { 0x8f68005f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff323232, 0x68680068, 0x68686868 },
    { 0x8f690068, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff333333, 0x73730073, 0x73737373 }
},
    // P-Frame
{
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff000000, 0x00000000, 0x00000000 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff010101, 0x00000000, 0x00000000 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff020202, 0x00000000, 0x00000000 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff030303, 0x00000000, 0x00000000 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff040404, 0x00000000, 0x00000000 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff050505, 0x00000000, 0x00000000 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff060606, 0x00000000, 0x00000000 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff070707, 0x01010001, 0x01010101 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff080808, 0x01010001, 0x01010101 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff090909, 0x03030003, 0x03030303 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 },
    { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b },
    { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b },
    { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d },
    { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d },
    { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff131313, 0x10100010, 0x10101010 },
    { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff141414, 0x10100010, 0x10101010 },
    { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff151515, 0x13130013, 0x13131313 },
    { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff161616, 0x13130013, 0x13131313 },
    { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff171717, 0x16160016, 0x16161616 },
    { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff181818, 0x16160016, 0x16161616 },
    { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a },
    { 0x5b493d29, 0x281c0d2b, 0x001a001e, 0x2b1d1a05, 0x39392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a },
    { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e },
    { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e },
    { 0x5f4c492c, 0x2c28192f, 0x001e002a, 0x38291e07, 0x3d3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 },
    { 0x694e4a2e, 0x2d291b39, 0x0028002b, 0x392a2808, 0x3f3e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 },
    { 0x6a584b38, 0x2f2a1c3a, 0x0029002c, 0x3a2b2909, 0x48483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 },
    { 0x6b594d39, 0x382c1d3b, 0x002a002e, 0x3b2d2a0a, 0x49493f3d, 0xff202020, 0x27270027, 0x27272727 },
    { 0x6c5a4e3a, 0x392d1f3c, 0x002b002f, 0x3c2e2b0b, 0x4a4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c },
    { 0x6e5b583b, 0x3b2f293e, 0x002d0039, 0x3f382d0d, 0x4c4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c },
    { 0x6f5c593c, 0x3c38293f, 0x002e003a, 0x48392e0e, 0x4d4c4b49, 0xff232323, 0x32320032, 0x32323232 },
    { 0x795e5a3e, 0x3d392b49, 0x0038003b, 0x493a3818, 0x4f4e4c4a, 0xff242424, 0x32320032, 0x32323232 },
    { 0x7a685b48, 0x3f3a2c4a, 0x0039003c, 0x4a3b3919, 0x58584e4b, 0xff252525, 0x38380038, 0x38383838 },
    { 0x7b695d49, 0x483c2d4b, 0x003a003e, 0x4b3d3a1a, 0x59594f4d, 0xff262626, 0x38380038, 0x38383838 },
    { 0x7d6a5e4a, 0x4a3d2f4c, 0x003c0048, 0x4d3e3c1c, 0x5b5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e },
    { 0x7e6b684b, 0x4a3e384d, 0x003d0049, 0x4e483d1d, 0x5c5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e },
    { 0x886d694d, 0x4c483a4f, 0x003f004a, 0x58493f1f, 0x5e5d5b59, 0xff292929, 0x45450045, 0x45454545 },
    { 0x896e6a4e, 0x4d493b59, 0x0048004b, 0x594a4828, 0x5f5e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 },
    { 0x8a786b58, 0x4f4a3c5a, 0x0049004c, 0x5a4b4929, 0x68685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d },
    { 0x8b796d59, 0x584c3d5b, 0x004a004e, 0x5b4d4a2a, 0x69695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d },
    { 0x8c7a6e5a, 0x594d3f5c, 0x004b004f, 0x5d4e4b2b, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 },
    { 0x8e7b785b, 0x5b4f485e, 0x004d0059, 0x5e584d2d, 0x6c6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 },
    { 0x8f7c795c, 0x5c58495f, 0x004e005a, 0x68594e2e, 0x6d6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e },
    { 0x8f7e7a5e, 0x5d594b69, 0x0058005b, 0x695a5838, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e },
    { 0x8f887b68, 0x5f5a4c6a, 0x0059005c, 0x6a5b5939, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 },
    { 0x8f897d69, 0x685c4d6b, 0x005a005e, 0x6b5d5a3a, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 },
    { 0x8f8a7e6a, 0x695d4f6c, 0x005b0068, 0x6d5e5b3b, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 }
},
    // B-Frame
{
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff000000, 0x00000000, 0x00000000 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff010101, 0x00000000, 0x00000000 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff020202, 0x00000000, 0x00000000 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff030303, 0x00000000, 0x00000000 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff040404, 0x00000000, 0x00000000 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff050505, 0x00000000, 0x00000000 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff060606, 0x00000000, 0x00000000 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff070707, 0x01010001, 0x01010101 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff080808, 0x01010001, 0x01010101 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff090909, 0x03030003, 0x03030303 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 },
    { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b },
    { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b },
    { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d },
    { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d },
    { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff131313, 0x10100010, 0x10101010 },
    { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff141414, 0x10100010, 0x10101010 },
    { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff151515, 0x13130013, 0x13131313 },
    { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff161616, 0x13130013, 0x13131313 },
    { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff171717, 0x16160016, 0x16161616 },
    { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff181818, 0x16160016, 0x16161616 },
    { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a },
    { 0x5d4d4b29, 0x2d2b282f, 0x001a0a1f, 0x1f0a0a00, 0x3a392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a },
    { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e },
    { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e },
    { 0x69594f2c, 0x392f2b3b, 0x001e0e2b, 0x2b0e0e00, 0x3e3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 },
    { 0x6a5a592e, 0x3b392d3c, 0x0028182c, 0x2c181800, 0x483e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 },
    { 0x6b5b5a38, 0x3c3a2f3e, 0x0029192e, 0x2e191900, 0x49483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 },
    { 0x6d5d5b39, 0x3d3b383f, 0x002a1a2f, 0x2f1a1a00, 0x4a493f3d, 0xff202020, 0x27270027, 0x27272727 },
    { 0x6e5e5c3a, 0x3e3c3948, 0x002b1b38, 0x381b1b00, 0x4b4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c },
    { 0x78685e3b, 0x493e3b4a, 0x002d1d3a, 0x3a1d1d00, 0x4d4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c },
    { 0x79695f3c, 0x493f3b4b, 0x002e1e3b, 0x3b1e1e00, 0x4e4c4b49, 0xff232323, 0x32320032, 0x32323232 },
    { 0x7a6a693e, 0x4b493d4c, 0x0038283c, 0x3c282800, 0x584e4c4a, 0xff242424, 0x32320032, 0x32323232 },
    { 0x7b6b6a48, 0x4c4a3f4e, 0x0039293e, 0x3e292900, 0x59584e4b, 0xff252525, 0x38380038, 0x38383838 },
    { 0x7d6d6b49, 0x4d4b484f, 0x003a2a3f, 0x3f2a2a00, 0x5a594f4d, 0xff262626, 0x38380038, 0x38383838 },
    { 0x7e6e6c4a, 0x4f4c4959, 0x003c2c49, 0x492c2c00, 0x5c5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e },
    { 0x88786d4b, 0x584d4a59, 0x003d2d49, 0x492d2d00, 0x5d5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e },
    { 0x89796f4d, 0x5a4f4c5b, 0x003f2f4b, 0x4b2f2f00, 0x5f5d5b59, 0xff292929, 0x45450045, 0x45454545 },
    { 0x8a7a794e, 0x5b594d5c, 0x0048384c, 0x4c383800, 0x685e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 },
    { 0x8b7b7a58, 0x5c5a4f5e, 0x0049394e, 0x4e393900, 0x69685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d },
    { 0x8d7d7b59, 0x5d5b585f, 0x004a3a4f, 0x4f3a3a00, 0x6a695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d },
    { 0x8e7e7c5a, 0x5f5c5968, 0x004b3b58, 0x583b3b00, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 },
    { 0x8f887e5b, 0x685e5a6a, 0x004d3d5a, 0x5a3d3d00, 0x6d6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 },
    { 0x8f897f5c, 0x695f5c6b, 0x004e3e5b, 0x5b3e3e00, 0x6e6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e },
    { 0x8f8a895e, 0x6b695d6c, 0x0058485c, 0x5c484800, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e },
    { 0x8f8b8a68, 0x6c6a5f6e, 0x0059495e, 0x5e494900, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 },
    { 0x8f8d8b69, 0x6d6b686f, 0x005a4a5f, 0x5f4a4a00, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 },
    { 0x8f8e8c6a, 0x6f6c6979, 0x005b4b69, 0x694b4b00, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 }
}
};

// QP is from 0 - 51, pad it to 64 since BRC needs array size to be 64 bytes
const uint8_t CodechalEncodeAvcEnc::m_qpDistMaxFrameAdjustmentCm[576] =
{
    0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00, 0x01, 0x02, 0x03, 0xff,
    0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xfe, 0xfe, 0xff, 0x00, 0x01, 0xfd, 0xfd,
    0xff, 0xff, 0x00, 0xfb, 0xfd, 0xfe, 0xff, 0xff, 0xfa, 0xfb, 0xfd, 0xfe, 0xff, 0x00, 0x04, 0x1e,
    0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x01, 0x01, 0x02, 0x03, 0xff,
    0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff,
    0xff, 0xff, 0x00, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x04, 0x1e,
    0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00, 0x01, 0x01, 0x02, 0xff,
    0x00, 0x00, 0x01, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff,
    0xff, 0xff, 0x00, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x02, 0x14,
    0x28, 0x46, 0x82, 0xa0, 0xc8, 0xff, 0x04, 0x04, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,
    0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe,
    0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,
    0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe,
    0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,
    0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe,
    0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const uint32_t CodechalEncodeAvcEnc::MultiPred[NUM_TARGET_USAGE_MODES] =
{
0, 3, 3, 0, 0, 0, 0, 0
};
const uint32_t CodechalEncodeAvcEnc::MRDisableQPCheck[NUM_TARGET_USAGE_MODES] =
{
0, 1, 0, 0, 0, 0, 0, 0
};
// AVC MBEnc RefCost tables, index [CodingType][QP]
// QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes
const uint16_t CodechalEncodeAvcEnc::RefCost_MultiRefQp[NUM_PIC_TYPES][64] =
{
// I-frame
{
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000
},
// P-slice
{
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000
},
//B-slice
{
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000
}
};

// 1 for P, 3 for P & B
const uint32_t CodechalEncodeAvcEnc::CODECHAL_ENCODE_AVC_AllFractional_Common[NUM_TARGET_USAGE_MODES] =
{
    0, 3, 3, 3, 3, 3, 3, 0
};

uint16_t CodechalEncodeAvcEnc::CalcSkipVal(bool encBlockBasedSkipEn, bool transform8x8Flag, uint16_t skipVal)
{
    if(!encBlockBasedSkipEn)
    {
        skipVal *= 3;
    }
    else if(!transform8x8Flag)
    {
        skipVal /= 2;
    }

    return skipVal;
}

uint32_t CodechalEncodeAvcEnc::GetMaxMvsPer2Mb(uint8_t levelIdc)
{
    uint32_t maxMvsPer2Mb = 32;

    // See JVT Spec Annex A Table A-1 Level limits for below mapping
    switch (levelIdc)
    {
    case CODEC_AVC_LEVEL_3:
        maxMvsPer2Mb = 32;
        break;
    case CODEC_AVC_LEVEL_31:
    case CODEC_AVC_LEVEL_32:
    case CODEC_AVC_LEVEL_4:
    case CODEC_AVC_LEVEL_41:
    case CODEC_AVC_LEVEL_42:
    case CODEC_AVC_LEVEL_5:
    case CODEC_AVC_LEVEL_51:
    case CODEC_AVC_LEVEL_52:
        maxMvsPer2Mb = 16;
        break;
    default:
        break;
    }

    return maxMvsPer2Mb;
}

// Indicates if reference picture is a FIELD picture, if check ppRefList, the flags is always the second field flag;
// because the first field flag will be overwrited by the second one.
// if check the reference flag is top or bottom, using pParams->pSlcParams->RefPicList[list][index].PicFlags is better
uint32_t CodechalEncodeAvcEnc::GetRefPicFieldFlag(
    PCODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS     params,
    uint32_t                                    list,
    uint32_t                                    index)
{
    CODEC_PICTURE       refPic;
    uint32_t            refPicFieldFlag;

    refPicFieldFlag = 0;

    if(params == nullptr){
        CODECHAL_ENCODE_ASSERTMESSAGE("Invalid (NULL) Pointer.");
        return refPicFieldFlag;
    }

    CODECHAL_ENCODE_ASSERT(list == LIST_0 || list == LIST_1);
    CODECHAL_ENCODE_ASSERT(index < 32);

    refPic = params->pSlcParams->RefPicList[list][index];
    if (!CodecHal_PictureIsInvalid(refPic))
    {
        refPic = params->pPicParams->RefFrameList[refPic.FrameIdx];
        if (!CodecHal_PictureIsInvalid(refPic))
        {
            refPicFieldFlag = CodecHal_PictureIsField(params->ppRefList[refPic.FrameIdx]->RefPic);
        }
    }

    return refPicFieldFlag;
}

uint8_t CodechalEncodeAvcEnc::AVCGetQPValueFromRefList(
    PCODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS params,
    uint32_t                                list,
    uint32_t                                index)
{
    uint8_t                             picIdx;
    CODEC_PICTURE                       picture;

    if(params == nullptr){
        CODECHAL_ENCODE_ASSERTMESSAGE("Invalid (NULL) Pointer.");
        return 0;
    }

    CODECHAL_ENCODE_ASSERT(list == LIST_0 || list == LIST_1);
    CODECHAL_ENCODE_ASSERT(index < CODEC_AVC_MAX_NUM_REF_FRAME * 2);

    picture = params->pSlcParams->RefPicList[list][index];

    if (!CodecHal_PictureIsInvalid(picture) && params->pPicIdx[picture.FrameIdx].bValid)
    {
        picIdx = params->pPicIdx[picture.FrameIdx].ucPicIdx;
        if (CodecHal_PictureIsBottomField(picture))
        {
            return params->ppRefList[picIdx]->ucQPValue[1];
        }
        else
        {
            return params->ppRefList[picIdx]->ucQPValue[0];
        }
    }
    else
    {
        return 0;
    }

    return 0;
}

//------------------------------------------------------------------------------------
// Send surfaces for the AVC BRC Block Copy kernel
//------------------------------------------------------------------------------------
MOS_STATUS CodechalEncodeAvcEnc::SendBrcBlockCopySurfaces(
    CodechalHwInterface                        *hwInterface,
    PMOS_COMMAND_BUFFER                         cmdBuffer,
    PMHW_KERNEL_STATE                           mbEncKernelState,
    PMHW_KERNEL_STATE                           kernelState,
    PMOS_RESOURCE                               advancedDsh)
{
    MOS_SURFACE                                 dshBuffer;
    CODECHAL_SURFACE_CODEC_PARAMS               surfaceCodecParams;
    MOS_RESOURCE                                *dsh = nullptr;
    MOS_STATUS                                  eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface);
    CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(mbEncKernelState);
    CODECHAL_ENCODE_CHK_NULL_RETURN(kernelState);

    // Set up artificial MOS_SURFACE for DSH buffers
    MOS_ZeroMemory(&dshBuffer, sizeof(dshBuffer));
    dshBuffer.TileType         = MOS_TILE_LINEAR;
    dshBuffer.bArraySpacing    = true;
    dshBuffer.Format           = Format_Buffer_2D;
    dshBuffer.dwWidth          = CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH;
    dshBuffer.dwHeight         =
    mbEncKernelState->m_dshRegion.GetSize() / CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH;
    dshBuffer.dwPitch          = CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH;

    // Input
    dshBuffer.dwOffset         = mbEncKernelState->m_dshRegion.GetOffset();
    CODECHAL_ENCODE_CHK_NULL_RETURN(dsh = mbEncKernelState->m_dshRegion.GetResource());
    dshBuffer.OsResource = *dsh;

    MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
    surfaceCodecParams.bIs2DSurface          = true;
    surfaceCodecParams.bMediaBlockRW         = true;
    surfaceCodecParams.psSurface             = &dshBuffer;
    surfaceCodecParams.dwBindingTableOffset  = CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_INPUT;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        hwInterface,
        cmdBuffer,
        &surfaceCodecParams,
        kernelState));

    // Output
    dshBuffer.dwOffset         = 0;
    dshBuffer.OsResource       = *advancedDsh;

    MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
    surfaceCodecParams.bIs2DSurface          = true;
    surfaceCodecParams.bMediaBlockRW         = true;
    surfaceCodecParams.psSurface             = &dshBuffer;
    surfaceCodecParams.dwBindingTableOffset  = CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_OUTPUT;
    surfaceCodecParams.bRenderTarget         = true;
    surfaceCodecParams.bIsWritable           = true;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        hwInterface,
        cmdBuffer,
        &surfaceCodecParams,
        kernelState));

    return eStatus;
}

CodechalEncodeAvcEnc::CodechalEncodeAvcEnc(
    CodechalHwInterface *   hwInterface,
    CodechalDebugInterface *debugInterface,
    PCODECHAL_STANDARD_INFO standardInfo) : CodechalEncodeAvcBase(hwInterface, debugInterface, standardInfo)

{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    InitializeDataMember();

    // Setup initial data
    bBrcInit = true;
    // enable codec specific user feature key reporting for AVC
    m_userFeatureKeyReport = true;

    m_kuid = IDR_CODEC_AllAVCEnc;

    m_swBrcMode = nullptr;

    m_cmKernelEnable = true;
    bBrcSplitEnable = true;
    bBrcRoiSupported = true;
    bHighTextureModeCostEnable = true;

    for (uint8_t i = 0; i < CODECHAL_ENCODE_BRC_IDX_NUM; i++)
    {
        BrcKernelStates[i] = MHW_KERNEL_STATE();
    }

    if (m_cmKernelEnable)
    {
        m_useCmScalingKernel = 1;
    }
    CODECHAL_DEBUG_TOOL(
        m_mmcUserFeatureUpdated = false;
    )
}

CodechalEncodeAvcEnc::~CodechalEncodeAvcEnc()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    if (SeiData.pSEIBuffer)
    {
        MOS_FreeMemory(SeiData.pSEIBuffer);
        SeiData.pSEIBuffer = nullptr;
    }

    if (pWPKernelState)
    {
        MOS_Delete(pWPKernelState);
        pWPKernelState = nullptr;
    }

    MOS_Delete(pSFDKernelState);
    pSFDKernelState = nullptr;

    if (m_pakEnabled)
    {
        // release skip frame copy buffer
        m_osInterface->pfnFreeResource(m_osInterface, &resSkipFrameBuffer);
    }

    if (m_encEnabled)
    {
        ReleaseResourcesBrc();
        ReleaseResourcesMbBrc();
        m_osInterface->pfnFreeResource(m_osInterface, &resVMEScratchBuffer);

        if (bVMEKernelDump)
        {
            m_osInterface->pfnFreeResource(m_osInterface, &resVmeKernelDumpBuffer);
        }

        // RefPicSelectList
        for (uint32_t i = 0; i < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; i++)
        {
            m_osInterface->pfnFreeResource(
                m_osInterface,
                &RefPicSelectList[i].sBuffer.OsResource);
        }

        MOS_DeleteArray(pMbEncKernelStates);
    }

    //WP output surface
    for (uint32_t i = 0; i < CODEC_AVC_NUM_WP_FRAME; i++)
    {
        m_osInterface->pfnFreeResource(
            m_osInterface,
            &WeightedPredOutputPicSelectList[i].sBuffer.OsResource);
    }

    // SFD surfaces
    {
        // SFD output buffer
        for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
        {
            m_osInterface->pfnFreeResource(
                m_osInterface,
                &resSFDOutputBuffer[i]);
        }

        m_osInterface->pfnFreeResource(
            m_osInterface,
            &resSFDCostTablePFrameBuffer);

        m_osInterface->pfnFreeResource(
            m_osInterface,
            &resSFDCostTableBFrameBuffer);
    }

    if (m_swBrcMode != nullptr)
    {
        m_osInterface->pfnFreeLibrary(m_swBrcMode);
        m_swBrcMode = nullptr;
    }

    // MB specific data buffer
    for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        m_osInterface->pfnFreeResource(
            m_osInterface,
            &resMbSpecificDataBuffer[i]);
    }

    return;

}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(settings);

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::Initialize(settings));

    // for AVC: the Ds+Copy kernel is by default used to do CSC and copy non-aligned surface
    m_cscDsState->EnableCopy();
    m_cscDsState->EnableColor();

    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
#if (_DEBUG || _RELEASE_INTERNAL)
    /*MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_BRC_SOFTWARE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);

    if (userFeatureData.i32Data)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnLoadLibrary(m_osInterface, CODECHAL_DBG_STRING_SWAVCBRCLIBRARY, &m_swBrcMode));
    }*/

    // SW BRC DLL Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_BRC_SOFTWARE_IN_USE_ID, (m_swBrcMode == nullptr) ? false : true, m_osInterface->pOsContext);
#endif // (_DEBUG || _RELEASE_INTERNAL)

    if (!(m_codecFunction == CODECHAL_FUNCTION_PAK || m_codecFunction == CODECHAL_FUNCTION_FEI_PAK))
    {
        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_ME_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        m_hmeSupported = (userFeatureData.u32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_16xME_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);

        if (userFeatureData.i32Data == 0 || userFeatureData.i32Data == 1)
        {
            m_16xMeUserfeatureControl = true;
            m_16xMeSupported = (userFeatureData.i32Data) ? true : false;
        }
        else
        {
            m_16xMeUserfeatureControl = false;
            m_16xMeSupported = true;
        }

        // Flatness check enable
        m_flatnessCheckSupported = 1; // Enabled by default for AVC when supported

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_FLATNESS_CHECK_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        m_flatnessCheckSupported = (userFeatureData.i32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_STATIC_FRAME_DETECTION_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bStaticFrameDetectionEnable = (userFeatureData.i32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_SEARCH_WINDOW_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bApdatvieSearchWindowEnable = (userFeatureData.i32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_FORCE_TO_SKIP_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bForceToSkipEnable = (userFeatureData.u32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_SLIDING_WINDOW_SIZE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        dwSlidingWindowSize = userFeatureData.u32Data;

        // Colorbit support (encoding multiple slices in parallel)
        m_colorbitSupported = 1;  // Enable by default for AVC
#if (_DEBUG || _RELEASE_INTERNAL)
        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_COLOR_BIT_SUPPORT_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        m_colorbitSupported = (userFeatureData.i32Data) ? true : false;
#endif

        m_groupIdSelectSupported = 0; // Disabled by default for AVC for now
#if (_DEBUG || _RELEASE_INTERNAL)
        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_GROUP_ID_SELECT_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        m_groupIdSelectSupported = (userFeatureData.i32Data) ? true : false;
#endif

        m_groupId = 0; // default value for group ID  = 0
#if (_DEBUG || _RELEASE_INTERNAL)
        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_GROUP_ID_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        m_groupId = (uint8_t)userFeatureData.i32Data;
#endif
    }

    // disable BRC and HME for FEI encoder
    if ((m_feiEnable) && (m_codecFunction != CODECHAL_FUNCTION_FEI_PRE_ENC))
    {
        m_hmeSupported = false;
        m_16xMeSupported = false;
        m_32xMeSupported = false;
    }

    // Initialize hardware resources for the current Os/Platform
    CODECHAL_ENCODE_CHK_STATUS_RETURN(InitializeState());
    {
        MotionEstimationDisableCheck();
    }
    CODECHAL_ENCODE_CHK_STATUS_RETURN(Initialize());

    // common function for all codecs needed
    if (CodecHalUsesRenderEngine(m_codecFunction, m_standard))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelState());
    }

    // Picture Level Commands
    m_hwInterface->GetMfxStateCommandsDataSize(
        CODECHAL_ENCODE_MODE_AVC,
        &m_pictureStatesSize,
        &m_picturePatchListSize,
        false);

    // Slice Level Commands
    m_hwInterface->GetMfxPrimitiveCommandsDataSize(
        CODECHAL_ENCODE_MODE_AVC,
        &m_sliceStatesSize,
        &m_slicePatchListSize,
        m_singleTaskPhaseSupported);

    return eStatus;
}

void CodechalEncodeAvcEnc::InitializeDataMember()
{
    CODECHAL_ENCODE_FUNCTION_ENTER;

    // SEI
    MOS_ZeroMemory(&SeiData, sizeof(CodechalEncodeSeiData));
    dwSEIDataOffset = false;
    pSeiParamBuffer = nullptr;

    bMbEncCurbeSetInBrcUpdate = false;
    bMbEncIFrameDistEnabled = false;
    bBrcInit = false;
    bBrcReset = false;
    bBrcEnabled = false;
    bMbBrcEnabled = false;
    bBrcRoiEnabled = false;                 // BRC ROI feature
    bROIValueInDeltaQP = false;
    bROISmoothEnabled = false;
    bMbBrcUserFeatureKeyControl = false;
    dBrcTargetSize = 0.0f;
    dwTrellis = false;
    bAcceleratorHeaderPackingCaps = false; //flag set by driver from driver caps
    dwIntraRefreshQpThreshold = false;
    bSquareRollingIEnabled = false;

    // VME Scratch Buffers
    MOS_ZeroMemory(&resVMEScratchBuffer, sizeof(MOS_RESOURCE));            // HSW+
    bVMEScratchBuffer = false;
    MOS_ZeroMemory(&resVmeKernelDumpBuffer, sizeof(MOS_RESOURCE));
    bVMEKernelDump = false;
    ulVMEKernelDumpBottomFieldOffset = 0;

    // MbEnc
    pMbEncKernelStates = nullptr;
    MOS_ZeroMemory(&MbEncBindingTable, sizeof(CODECHAL_ENCODE_AVC_BINDING_TABLE_MBENC));
    dwNumMbEncEncKrnStates = false;
    MOS_ZeroMemory(RefPicSelectList, CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES * sizeof(CODEC_AVC_REF_PIC_SELECT_LIST));
    ucCurrRefPicSelectIndex = 0;
    ulRefPicSelectBottomFieldOffset = 0;
    dwMbEncBlockBasedSkipEn = false;
    bKernelTrellis = false; // Kernel controlled Trellis Quantization
    bExtendedMvCostRange = false; // Extended MV Cost Range for Gen10+

    // WP
    pWPKernelState = nullptr;
    MOS_ZeroMemory(WeightedPredOutputPicSelectList, CODEC_AVC_NUM_WP_FRAME * sizeof(CODEC_AVC_REF_PIC_SELECT_LIST));

    // BRC Params
    MOS_ZeroMemory(&BrcUpdateBindingTable, sizeof(CODECHAL_ENCODE_AVC_BINDING_TABLE_BRC_UPDATE));

    // PreProc
    MOS_ZeroMemory(&PreProcBindingTable, sizeof(CODECHAL_ENCODE_AVC_BINDING_TABLE_PREPROC));

    MOS_ZeroMemory(&BrcBuffers, sizeof(EncodeBrcBuffers));
    usAVBRAccuracy = 0;
    usAVBRConvergence = 0;
    dBrcInitCurrentTargetBufFullInBits = 0;
    dBrcInitResetInputBitsPerFrame = 0;
    dwBrcInitResetBufSizeInBits = false;
    dwBrcInitPreviousTargetBufFullInBits = false;
    // Below values will be set if qp control params are sent by app
    bMinMaxQPControlEnabled = false;  // Flag to indicate if min/max QP feature is enabled or not.
    ucIMinQP = 0;
    ucIMaxQP = 0;
    ucPMinQP = 0;
    ucPMaxQP = 0;
    ucBMinQP = 0;
    ucBMaxQP = 0;
    bPFrameMinMaxQPControl = false;   // Indicates min/max QP values for P-frames are set separately or not.
    bBFrameMinMaxQPControl = false;   // Indicates min/max QP values for B-frames are set separately or not.

    dwSkipFrameBufferSize = false;     // size of skip frame packed data
    MOS_ZeroMemory(&resSkipFrameBuffer, sizeof(MOS_RESOURCE));        // copy skip frame packed data from DDI
    // Mb Disable Skip Map
    bMbDisableSkipMapEnabled = false;
    psMbDisableSkipMapSurface = nullptr;

    // Mb Qp Data
    bMbQpDataEnabled = false;
    MOS_ZeroMemory(&sMbQpDataSurface, sizeof(MOS_SURFACE));

    // Mb Specific Data
    bMbSpecificDataEnabled = false;
    MOS_ZeroMemory(&resMbSpecificDataBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_RECYCLED_BUFFER_NUM);

    // Static frame detection
    bStaticFrameDetectionEnable = false;    // Static frame detection enable
    bApdatvieSearchWindowEnable = false;    // allow search window size change when SFD enabled
    bPerMbSFD = false;
    MOS_ZeroMemory(&resSFDOutputBuffer, sizeof(MOS_RESOURCE)* CODECHAL_ENCODE_RECYCLED_BUFFER_NUM);

    MOS_ZeroMemory(&resSFDCostTablePFrameBuffer, sizeof(MOS_RESOURCE));
    MOS_ZeroMemory(&resSFDCostTableBFrameBuffer, sizeof(MOS_RESOURCE));
    pSFDKernelState = nullptr;

    // Generation Specific Support Flags & User Feature Key Reads
    bBrcDistortionBufferSupported = false;
    bRefPicSelectListSupported = false;
    ucMbBrcSupportCaps = 0;
    bMultiPredEnable = false;               // MultiPredictor enable, 6 predictors
    bFTQEnable = false;                     // FTQEnable
    bCAFSupported = false;                  // CAFSupported
    bCAFEnable = false;                     // CAFEnable
    bCAFDisableHD = false;                  // Disable CAF for HD
    bSkipBiasAdjustmentSupported = false;   // SkipBiasAdjustment support for P frame
    bAdaptiveIntraScalingEnable = false;    // Enable AdaptiveIntraScaling
    bOldModeCostEnable = false;             // Enable Old Mode Cost (HSW cost table for BDW)
    bMultiRefQpEnabled = false;             // BDW Mutiref Qp
    bAdvancedDshInUse  = false;             // Use MbEnc Adv kernel
    bUseMbEncAdvKernel = false;             // Use MbEnc Adv kernel
    bUseWeightedSurfaceForL0 = false;       //Use WP Surface for L0
    bUseWeightedSurfaceForL1 = false;       //Use WP Surface for L1
    bWeightedPredictionSupported = false;   //Weighted prediction support
    bBrcSplitEnable = false;                // starting GEN9 BRC kernel has split into frame-level and MB-level update.
    bDecoupleMbEncCurbeFromBRC = false;     // starting GEN95 BRC kernel write to extra surface instread of MBEnc curbe.
    bSliceLevelReportSupported = false;     // Slice Level Report support
    bFBRBypassEnable = false;               // FBRBypassEnable
    bBrcRoiSupported = false;
    bMvDataNeededByBRC = false;             // starting from G95,
    bHighTextureModeCostEnable = false;

    bRoundingInterEnable = false;
    bAdaptiveRoundingInterEnable = false;
    dwRoundingInterP = false;
    dwRoundingInterB = false;
    dwRoundingInterBRef = false;
    dwBrcConstantSurfaceWidth = false;
    dwBrcConstantSurfaceHeight = false;

    dwSlidingWindowSize = false;
    bForceToSkipEnable = false;
}

MOS_STATUS CodechalEncodeAvcEnc::Initialize()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::Initialize());
    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::InitializeState()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_SINGLE_TASK_PHASE_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    m_singleTaskPhaseSupported = (userFeatureData.i32Data) ? true : false;

    // Set interleaved scaling output to support PAFF.
    m_fieldScalingOutputInterleaved = true;

    if (m_encEnabled)
    {
        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_MULTIPRED_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bMultiPredEnable = (userFeatureData.i32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_FTQ_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bFTQEnable = (userFeatureData.i32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_CAF_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bCAFSupported = (userFeatureData.i32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_CAF_DISABLE_HD_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bCAFDisableHD = (userFeatureData.i32Data) ? true : false;

        ucMbBrcSupportCaps = 1;
        if (ucMbBrcSupportCaps)
        {
            // If the MBBRC user feature key does not exist, MBBRC will be set in SPS parsing
            MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
            MOS_UserFeature_ReadValue_ID(
                nullptr,
                __MEDIA_USER_FEATURE_VALUE_AVC_MB_BRC_ENABLE_ID,
                &userFeatureData,
                m_osInterface->pOsContext);
            if (userFeatureData.i32Data == 0 || userFeatureData.i32Data == 1)
            {
                bMbBrcUserFeatureKeyControl = true;
                bMbBrcEnabled = userFeatureData.i32Data ? true : false;
            }
        }

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_MULTIREF_QP_ID,
            &userFeatureData,
            m_osInterface->pOsContext);
        bMultiRefQpEnabled = (userFeatureData.i32Data) ? true : false;

        MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
        MOS_UserFeature_ReadValue_ID(
            nullptr,
            __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_32xME_ENABLE_ID,
            &userFeatureData,
            m_osInterface->pOsContext);

        if (userFeatureData.i32Data == 0 || userFeatureData.i32Data == 1)
        {
            m_32xMeUserfeatureControl = true;
            m_32xMeSupported = (userFeatureData.i32Data) ? true : false;
        }
        else
        {
            m_32xMeUserfeatureControl = false;
            m_32xMeSupported = true;
        }
    }

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    bRoundingInterEnable = (userFeatureData.i32Data) ? true : false;

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    userFeatureData.i32Data = CODECHAL_ENCODE_AVC_INVALID_ROUNDING;
    userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_P_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    dwRoundingInterP = userFeatureData.i32Data;

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    userFeatureData.i32Data = CODECHAL_ENCODE_AVC_INVALID_ROUNDING;
    userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_B_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    dwRoundingInterB = userFeatureData.i32Data;

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    userFeatureData.i32Data = CODECHAL_ENCODE_AVC_INVALID_ROUNDING;
    userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_BREF_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    dwRoundingInterBRef = userFeatureData.i32Data;

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    userFeatureData.i32Data = 1;
    userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_ROUNDING_INTER_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    bAdaptiveRoundingInterEnable = (userFeatureData.i32Data) ? true : false;

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_SKIP_BIAS_ADJUSTMENT_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    bSkipBiasAdjustmentSupported = (userFeatureData.i32Data) ? true : false;

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_INTRA_SCALING_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    bAdaptiveIntraScalingEnable = (userFeatureData.i32Data) ? true : false;

    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_OLD_MODE_COST_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    bOldModeCostEnable = (userFeatureData.i32Data) ? true : false;

    //Check if ATD has been disabled by user feature key. The TU check happens in CodecHalAvcEncode_SetPictureStructs()
    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    userFeatureData.i32Data = 1;
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_ADAPTIVE_TRANSFORM_DECISION_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    m_adaptiveTransformDecisionEnabled = (userFeatureData.i32Data) ? true : false;

    // add user feature key to test FBR Bypass on SKL
    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_FBR_BYPASS_ENABLE_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    bFBRBypassEnable = (userFeatureData.i32Data) ? true : false;

    // add user feature key to enable/disable variance computation in BRC kernel
    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_AVC_BRC_VAR_COMPU_BYPASS_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    bBRCVarCompuBypass = (userFeatureData.i32Data) ? true : false;

    // add user feature key to switch on/off ARB WA of CNL AVC MBEnc hang
    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
    MOS_UserFeature_ReadValue_ID(
        nullptr,
        __MEDIA_USER_FEATURE_VALUE_ENABLE_CNL_AVC_ENCODE_ARB_WA_ID,
        &userFeatureData,
        m_osInterface->pOsContext);
    if ((userFeatureData.i32Data) == 0)
    {
        MEDIA_WR_WA(m_waTable, WaArbitraryNumMbsInSlice, 0);
    }

    m_4xMeDistortionBufferSupported = true;
    bBrcDistortionBufferSupported = true;
    bRefPicSelectListSupported = true;

    bPerMbSFD = true;

    bWeightedPredictionSupported = true;

    m_forceBrcMbStatsEnabled = true;

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::ValidateNumReferences(PCODECHAL_ENCODE_AVC_VALIDATE_NUM_REFS_PARAMS params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);

    uint8_t numRefIdx0MinusOne = params->pAvcSliceParams->num_ref_idx_l0_active_minus1;
    uint8_t numRefIdx1MinusOne = params->pAvcSliceParams->num_ref_idx_l1_active_minus1;

    // Nothing to do here if numRefIdx = 0 and frame encoded
    if (numRefIdx0MinusOne == 0 && !CodecHal_PictureIsField(params->pPicParams->CurrOriginalPic))
    {
        if (params->wPictureCodingType == P_TYPE ||
            (params->wPictureCodingType == B_TYPE && numRefIdx1MinusOne == 0))
        {
            return eStatus;
        }
    }

    uint8_t   maxPNumRefIdx0MinusOne;
    if (params->wPictureCodingType == P_TYPE || params->wPictureCodingType == B_TYPE)
    {
        if (params->wPictureCodingType == P_TYPE)
        {
            if ((((params->wPicHeightInMB * CODECHAL_MACROBLOCK_HEIGHT) * (params->wFrameFieldHeightInMB * CODECHAL_MACROBLOCK_WIDTH)) >= 3840 * 2160)
                && CodecHal_PictureIsFrame(params->pPicParams->CurrOriginalPic))
            {
                maxPNumRefIdx0MinusOne = MaxRefIdx0_Progressive_4K[params->pSeqParams->TargetUsage];
            }
            else
            {
                maxPNumRefIdx0MinusOne = MaxRefIdx0[params->pSeqParams->TargetUsage];
            }

            if (numRefIdx0MinusOne > maxPNumRefIdx0MinusOne)
            {
                CODECHAL_ENCODE_NORMALMESSAGE("Invalid active reference list size.");
                numRefIdx0MinusOne = maxPNumRefIdx0MinusOne;
            }

            numRefIdx1MinusOne = 0;
        }
        else // B_TYPE
        {
            if (numRefIdx0MinusOne > MaxBRefIdx0[params->pSeqParams->TargetUsage])
            {
                CODECHAL_ENCODE_NORMALMESSAGE("Invalid active reference list size.");
                numRefIdx0MinusOne = MaxBRefIdx0[params->pSeqParams->TargetUsage];
            }

            if (numRefIdx1MinusOne > MaxRefIdx1[params->pSeqParams->TargetUsage])
            {
                CODECHAL_ENCODE_NORMALMESSAGE("Invalid active reference list size.");
                numRefIdx1MinusOne = MaxRefIdx1[params->pSeqParams->TargetUsage];
            }

            // supports at most 1 L1 ref for frame picture
            if (CodecHal_PictureIsFrame(params->pPicParams->CurrOriginalPic) && numRefIdx1MinusOne > 0)
            {
                numRefIdx1MinusOne = 0;
            }
        }
    }
    // Override number of references used by VME. PAK uses value from DDI (num_ref_idx_l*_active_minus1_from_DDI)
    params->pAvcSliceParams->num_ref_idx_l0_active_minus1 = numRefIdx0MinusOne;
    params->pAvcSliceParams->num_ref_idx_l1_active_minus1 = numRefIdx1MinusOne;

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::InitBrcConstantBuffer(PCODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;
    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pOsInterface);

    MOS_LOCK_PARAMS lockFlags;
    MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
    lockFlags.WriteOnly = 1;
    uint8_t* pbData = (uint8_t*)params->pOsInterface->pfnLockResource(
        params->pOsInterface,
        &params->sBrcConstantDataBuffer.OsResource,
        &lockFlags);
    CODECHAL_ENCODE_CHK_NULL_RETURN(pbData);

    MOS_ZeroMemory(pbData, params->sBrcConstantDataBuffer.dwWidth * params->sBrcConstantDataBuffer.dwHeight);

    // Fill surface with qp Adjustment table, Distortion threshold table, MaxFrame threshold table, Distortion qp Adjustment Table for I frame
    eStatus = MOS_SecureMemcpy(
        pbData,
        sizeof(m_qpDistMaxFrameAdjustmentCm),
        (void*)m_qpDistMaxFrameAdjustmentCm,
        sizeof(m_qpDistMaxFrameAdjustmentCm));
    if (eStatus != MOS_STATUS_SUCCESS)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
        return eStatus;
    }

    pbData += sizeof(m_qpDistMaxFrameAdjustmentCm);

    uint8_t qp = 0;
    if (params->wPictureCodingType == I_TYPE)
    {
        // skip early skip table for I frame
        pbData += m_brcConstantSurfaceEarlySkipTableSize;

        // POCs not used for now, set to zeroes
        pbData += CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_DPB_LIST_SIZE;
        pbData += CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_FINAL_LIST_SIZE;

        // Mode cost and MV cost
        eStatus = MOS_SecureMemcpy(
            pbData,
            m_brcConstantSurfacModeMvCostSize,
            (void*)&ModeMvCost_Common[0][0][0],
            m_brcConstantSurfacModeMvCostSize);
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }

        if (params->pAvcQCParams)
        {
            for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
            {
                if (params->pAvcQCParams->FTQSkipThresholdLUT[qp])
                {
                    *(pbData + (qp * 32) + 24) =
                        *(pbData + (qp * 32) + 25) =
                        *(pbData + (qp * 32) + 27) =
                        *(pbData + (qp * 32) + 28) =
                        *(pbData + (qp * 32) + 29) =
                        *(pbData + (qp * 32) + 30) =
                        *(pbData + (qp * 32) + 31) = params->pAvcQCParams->FTQSkipThresholdLUT[qp];
                }
            }
        }

        pbData += m_brcConstantSurfacModeMvCostSize;

        // Refcost
        eStatus = MOS_SecureMemcpy(
            pbData,
            m_brcConstantSurfaceRefCostSize,
            (void*)&RefCost_Common[0][0],
            m_brcConstantSurfaceRefCostSize);
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }
    }
    else if (params->wPictureCodingType == P_TYPE)
    {
        if (!params->dwMbEncBlockBasedSkipEn)
        {
            if (params->pPicParams->transform_8x8_mode_flag)
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_P_Common[0][1][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
            else
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_P_Common[0][0][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
        }
        else
        {
            if (params->pPicParams->transform_8x8_mode_flag)
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_P_Common[1][1][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
            else
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_P_Common[1][0][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
        }

        if ((params->pAvcQCParams != nullptr) && (params->pAvcQCParams->NonFTQSkipThresholdLUTInput))
        {
            for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
            {
                *(pbData + 1 + (qp * 2)) = (uint8_t)CalcSkipVal((params->dwMbEncBlockBasedSkipEn ? true : false), (params->pPicParams->transform_8x8_mode_flag ? true : false), params->pAvcQCParams->NonFTQSkipThresholdLUT[qp]);
            }
        }

        pbData += m_brcConstantSurfaceEarlySkipTableSize;

        // POCs not used for now, set to zeroes
        pbData += CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_DPB_LIST_SIZE;
        pbData += CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_FINAL_LIST_SIZE;

        // Mode cost and MV cost
        eStatus = MOS_SecureMemcpy(
            pbData,
            m_brcConstantSurfacModeMvCostSize,
            (void*)&ModeMvCost_Common[1][0][0],
            m_brcConstantSurfacModeMvCostSize);
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }

        if (params->pAvcQCParams)
        {
            for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
            {
                if (params->pAvcQCParams->FTQSkipThresholdLUTInput)
                {
                    *(pbData + (qp * 32) + 24) =
                        *(pbData + (qp * 32) + 25) =
                        *(pbData + (qp * 32) + 27) =
                        *(pbData + (qp * 32) + 28) =
                        *(pbData + (qp * 32) + 29) =
                        *(pbData + (qp * 32) + 30) =
                        *(pbData + (qp * 32) + 31) = params->pAvcQCParams->FTQSkipThresholdLUT[qp];
                }
            }
        }

        pbData += m_brcConstantSurfacModeMvCostSize;

        // Refcost
        eStatus = MOS_SecureMemcpy(
            pbData,
            m_brcConstantSurfaceRefCostSize,
            (void*)&RefCost_Common[1][0],
            m_brcConstantSurfaceRefCostSize);
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }
    }
    else // B picture
    {
        if (!params->dwMbEncBlockBasedSkipEn)
        {
            if (params->pPicParams->transform_8x8_mode_flag)
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_B_Common[0][1][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
            else
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_B_Common[0][0][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
        }
        else
        {
            if (params->pPicParams->transform_8x8_mode_flag)
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_B_Common[1][1][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
            else
            {
                eStatus = MOS_SecureMemcpy(
                    pbData,
                    m_brcConstantSurfaceEarlySkipTableSize,
                    (void*)&SkipVal_B_Common[1][0][0],
                    m_brcConstantSurfaceEarlySkipTableSize);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                    return eStatus;
                }
            }
        }

        if (params->pAvcQCParams != nullptr && params->pAvcQCParams->NonFTQSkipThresholdLUTInput)
        {
            for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
            {
                *(pbData + 1 + (qp * 2)) = (uint8_t)CalcSkipVal((params->dwMbEncBlockBasedSkipEn ? true : false), (params->pPicParams->transform_8x8_mode_flag ? true : false), params->pAvcQCParams->NonFTQSkipThresholdLUT[qp]);
            }
        }

        pbData += m_brcConstantSurfaceEarlySkipTableSize;

        // POCs not used for now, set to zeroes
        pbData += CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_DPB_LIST_SIZE;
        pbData += CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_FINAL_LIST_SIZE;

        // Mode cost and MV cost
        eStatus = MOS_SecureMemcpy(
            pbData,
            m_brcConstantSurfacModeMvCostSize,
            (void*)&ModeMvCost_Common[2][0][0],
            m_brcConstantSurfacModeMvCostSize);
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }

        if (params->pAvcQCParams)
        {
            for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
            {
                if (params->pAvcQCParams->FTQSkipThresholdLUTInput)
                {
                    *(pbData + (qp * 32) + 24) =
                        *(pbData + (qp * 32) + 25) =
                        *(pbData + (qp * 32) + 27) =
                        *(pbData + (qp * 32) + 28) =
                        *(pbData + (qp * 32) + 29) =
                        *(pbData + (qp * 32) + 30) =
                        *(pbData + (qp * 32) + 31) = params->pAvcQCParams->FTQSkipThresholdLUT[qp];
                }
            }
        }

        pbData += m_brcConstantSurfacModeMvCostSize;

        // Refcost
        eStatus = MOS_SecureMemcpy(
            pbData,
            m_brcConstantSurfaceRefCostSize,
            (void*)&RefCost_Common[2][0],
            m_brcConstantSurfaceRefCostSize);
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }
    }

    params->pOsInterface->pfnUnlockResource(
        params->pOsInterface,
        &params->sBrcConstantDataBuffer.OsResource);

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::InitMbBrcConstantDataBuffer(PCODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->presBrcConstantDataBuffer);

    // 16 DWs per QP value
    uint32_t size = 16 * CODEC_AVC_NUM_QP;

    MOS_LOCK_PARAMS lockFlags;
    MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
    lockFlags.WriteOnly = 1;
    // using an async lock because the wait has already occured for recycled buffers
    lockFlags.NoOverWrite = 1;
    lockFlags.Uncached = 1;
    uint32_t* pData = (uint32_t*)m_osInterface->pfnLockResource(
        m_osInterface,
        params->presBrcConstantDataBuffer,
        &lockFlags);
    CODECHAL_ENCODE_CHK_NULL_RETURN(pData);

    if (params->bPreProcEnable)
    {
        eStatus = MOS_SecureMemcpy(pData, size * sizeof(uint32_t), (void*)PreProcFtqLut_Cm_Common, size * sizeof(uint32_t));
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            m_osInterface->pfnUnlockResource(
                m_osInterface,
                params->presBrcConstantDataBuffer);
            return eStatus;
        }
    }
    else
    {
        CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams);

        uint8_t tableIdx = params->wPictureCodingType - 1;
        bool blockBasedSkipEn = params->dwMbEncBlockBasedSkipEn ? true : false;
        bool transform_8x8_mode_flag = params->pPicParams->transform_8x8_mode_flag ? true : false;

        if (tableIdx >= 3)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Invalid input parameter.");
            eStatus = MOS_STATUS_INVALID_PARAMETER;
            m_osInterface->pfnUnlockResource(
                m_osInterface,
                params->presBrcConstantDataBuffer);
            return eStatus;
        }

        eStatus = MOS_SecureMemcpy(pData, size * sizeof(uint32_t), (void*)MBBrcConstantData_Cm_Common[tableIdx], size * sizeof(uint32_t));
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            m_osInterface->pfnUnlockResource(
                m_osInterface,
                params->presBrcConstantDataBuffer);
            return eStatus;
        }

        uint32_t* databk = pData;
        uint8_t qp = 0;
        switch (params->wPictureCodingType)
        {
        case I_TYPE:
            for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
            {
                // Writing to DW0 in each sub-array of 16 DWs
                if (params->bOldModeCostEnable)
                {
                    *pData = (uint32_t)OldIntraModeCost_Cm_Common[qp];
                }
                pData += 16;
            }
            break;
        case P_TYPE:
        case B_TYPE:
            for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
            {
                if (params->wPictureCodingType == P_TYPE)
                {
                    // Writing to DW3 in each sub-array of 16 DWs
                    if (params->bSkipBiasAdjustmentEnable)
                    {
                        *(pData + 3) = (uint32_t)MvCost_PSkipAdjustment_Cm_Common[qp];
                    }
                }

                // Writing to DW9 in each sub-array of 16 DWs
                if (params->pAvcQCParams && params->pAvcQCParams->NonFTQSkipThresholdLUTInput)
                {
                    *(pData + 9) = (uint32_t)CalcSkipVal((params->dwMbEncBlockBasedSkipEn ? true : false),
                        (transform_8x8_mode_flag ? true : false),
                        params->pAvcQCParams->NonFTQSkipThresholdLUT[qp]);
                }
                else if (params->wPictureCodingType == P_TYPE)
                {
                    *(pData + 9) = (uint32_t)SkipVal_P_Common[blockBasedSkipEn][transform_8x8_mode_flag][qp];
                }
                else
                {
                    *(pData + 9) = (uint32_t)SkipVal_B_Common[blockBasedSkipEn][transform_8x8_mode_flag][qp];
                }

                // Writing to DW10 in each sub-array of 16 DWs
                if (params->bAdaptiveIntraScalingEnable)
                {
                    *(pData + 10) = (uint32_t)AdaptiveIntraScalingFactor_Cm_Common[qp];
                }
                else
                {
                    *(pData + 10) = (uint32_t)IntraScalingFactor_Cm_Common[qp];
                }
                pData += 16;
            }
            break;
        default:
            break;
        }

        pData = databk;
        for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
        {
            if (params->pAvcQCParams && params->pAvcQCParams->FTQSkipThresholdLUTInput)
            {
                *(pData + 6) = ((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp])
                    | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 16)
                    | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 24);
                *(pData + 7) = ((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp])
                    | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 8)
                    | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 16)
                    | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 24);
            }

            if (params->bEnableKernelTrellis)
            {
                // Writing uint32_t 11 and uint32_t 12 with Lambda values
                *(pData + 11) = (uint32_t)params->Lambda[qp][0];
                *(pData + 12) = (uint32_t)params->Lambda[qp][1];
            }
            pData += 16;
        }
    }

    m_osInterface->pfnUnlockResource(
        m_osInterface,
        params->presBrcConstantDataBuffer);

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::CalcLambdaTable(
        uint16_t slice_type,
        uint32_t* lambda)
{
    MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN( m_avcSeqParam);
    CODECHAL_ENCODE_CHK_NULL_RETURN( m_refList);
    CODECHAL_ENCODE_CHK_NULL_RETURN(lambda);

    // Initialize Lambda Table
    switch (slice_type)
    {
    case I_TYPE:
        eStatus = MOS_SecureMemcpy((void*)lambda, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t), (void*)TQ_LAMBDA_I_FRAME, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t));
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }
        break;

    case B_TYPE:
        eStatus = MOS_SecureMemcpy((void*)lambda, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t), (void*)TQ_LAMBDA_B_FRAME, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t));
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }
        break;

    case P_TYPE:
        eStatus = MOS_SecureMemcpy((void*)lambda, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t), (void*)TQ_LAMBDA_P_FRAME, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t));
        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
            return eStatus;
        }
        break;

    default:
        eStatus = MOS_STATUS_UNKNOWN;
        break;
    }

    uint32_t roundingValue = 0;
    for (uint8_t sliceQP = 0; sliceQP < CODEC_AVC_NUM_QP; sliceQP++)
    {
        for (uint8_t col = 0; col < 2; col++)
        {
            uint32_t value = *(lambda + sliceQP * 2 + col);
            uint32_t intra = value >> 16;

            if (intra > CODECHAL_ENCODE_AVC_MAX_LAMBDA)
            {
                if (intra == 0xfffa)
                {
                    intra = 0xf000 + CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_INTRA_ROUNDING;
                }
            }

            intra = intra << 16;
            uint32_t inter = value & 0xffff;
            if (inter > CODECHAL_ENCODE_AVC_MAX_LAMBDA)
            {
                if (inter == 0xffef)
                {

                    switch (slice_type)
                    {
                    case P_TYPE:
                        if ( dwRoundingInterP == CODECHAL_ENCODE_AVC_INVALID_ROUNDING)
                        {
                            roundingValue = InterRoundingP_TQ[m_avcSeqParam->TargetUsage];
                        }
                        else
                        {
                            roundingValue =  dwRoundingInterP;
                        }
                        break;
                    case B_TYPE:
                        if (m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef)
                        {
                            roundingValue = ( dwRoundingInterBRef == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) ?
                                InterRoundingBRef_TQ[m_avcSeqParam->TargetUsage] :  dwRoundingInterBRef;
                        }
                        else
                        {
                            if ( dwRoundingInterB == CODECHAL_ENCODE_AVC_INVALID_ROUNDING)
                            {
                                roundingValue = InterRoundingB_TQ[m_avcSeqParam->TargetUsage];
                            }
                            else
                            {
                                roundingValue =  dwRoundingInterB;
                            }
                        }
                        break;
                    default:
                        // do nothing
                        break;
                    }

                    inter = 0xf000 + roundingValue;
                }
            }

            *(lambda + sliceQP * 2 + col) = intra + inter;
        }
    }
    return eStatus;
}

static uint8_t CODECHAL_ENCODE_AVC_AdaptiveInterRoundingPWithoutB[CODEC_AVC_NUM_QP] =
{
    //QP =  0   1   2   3   4   5   6   7   8   9   10  11  12
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,  //QP=[0~12]
    3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0,  //QP=[13~25]
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  //QP=[26~38]
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   //QP=[39~51]
};

static uint8_t CODECHAL_ENCODE_AVC_AdaptiveInterRoundingP[CODEC_AVC_NUM_QP] =
{
    //QP =  0   1   2   3   4   5   6   7   8   9   10  11  12
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  //QP=[0~12]
    4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,  //QP=[13~25]
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,  //QP=[26~38]
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3   //QP=[39~51]
};

static const uint32_t CODECHAL_ENCODE_AVC_InterRoundingP[NUM_TARGET_USAGE_MODES] =
{
    0, 3, 3, 3, 3, 3, 3, 3
};

static const uint32_t CODECHAL_ENCODE_AVC_InterRoundingBRef[NUM_TARGET_USAGE_MODES] =
{
    0, 2, 2, 2, 2, 2, 2, 2
};

static uint8_t CODECHAL_ENCODE_AVC_AdaptiveInterRoundingB[CODEC_AVC_NUM_QP] =
{
    //QP =  0   1   2   3   4   5   6   7   8   9   10  11  12
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  //QP=[0~12]
    4, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,  //QP=[13~25]
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  //QP=[26~38]
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   //QP=[39~51]
};

static const uint32_t CODECHAL_ENCODE_AVC_InterRoundingB[NUM_TARGET_USAGE_MODES] =
{
    0, 0, 0, 0, 0, 0, 0, 0
};

MOS_STATUS CodechalEncodeAvcEnc::GetInterRounding(PMHW_VDBOX_AVC_SLICE_STATE sliceState)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState);
    CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcSeqParams);
    CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcPicParams);
    CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcSliceParams);

    auto avcSeqParams = sliceState->pEncodeAvcSeqParams;
    auto avcPicParams = sliceState->pEncodeAvcPicParams;
    auto avcSliceParams = sliceState->pEncodeAvcSliceParams;
    uint8_t sliceQP = avcPicParams->pic_init_qp_minus26 + 26 + avcSliceParams->slice_qp_delta;

    switch (Slice_Type[avcSliceParams->slice_type])
    {
    case SLICE_P:
        if (dwRoundingInterP == CODECHAL_ENCODE_AVC_INVALID_ROUNDING)
        {
            // Adaptive Rounding is only used in CQP case
            if (bAdaptiveRoundingInterEnable && !bBrcEnabled)
            {
                // If IPPP scenario
                if (avcSeqParams->GopRefDist == 1)
                {
                    sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_AdaptiveInterRoundingPWithoutB[sliceQP];
                }
                else
                {
                    sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_AdaptiveInterRoundingP[sliceQP];
                }
            }
            else
            {
                sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_InterRoundingP[avcSeqParams->TargetUsage];
            }
        }
        else
        {
            sliceState->dwRoundingValue = dwRoundingInterP;
        }
        break;
    case SLICE_B:
        if (m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef)
        {
            sliceState->dwRoundingValue = (dwRoundingInterBRef == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) ?
                CODECHAL_ENCODE_AVC_InterRoundingBRef[avcSeqParams->TargetUsage] : dwRoundingInterBRef;
        }
        else
        {
            if (dwRoundingInterB == CODECHAL_ENCODE_AVC_INVALID_ROUNDING)
            {
                if (bAdaptiveRoundingInterEnable && !bBrcEnabled)
                {
                    sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_AdaptiveInterRoundingB[sliceQP];
                }
                else
                {
                    sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_InterRoundingB[avcSeqParams->TargetUsage];
                }
            }
            else
            {
                sliceState->dwRoundingValue = dwRoundingInterB;
            }
        }
        break;
    default:
        // do nothing
        break;
    }

    return eStatus;
}

// This applies only for progressive pictures. For interlaced, CAF is currently not disabled.
const uint32_t CodechalEncodeAvcEnc::CODECHAL_ENCODE_AVC_DisableAllFractionalCheckForHighRes_Common[NUM_TARGET_USAGE_MODES] =
{
    0, 0, 0, 1, 1, 1, 1, 1
};

MOS_STATUS CodechalEncodeAvcEnc::GetSkipBiasAdjustment(uint8_t sliceQP, uint16_t gopRefDist, bool* skipBiasAdjustmentEnable)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(skipBiasAdjustmentEnable);

    // Determine if SkipBiasAdjustment should be enabled for P picture
    // 1. No B frame 2. Qp >= 22 3. CQP mode
    *skipBiasAdjustmentEnable = bSkipBiasAdjustmentSupported && (m_pictureCodingType == P_TYPE)
        && (gopRefDist == 1) && (sliceQP >= CODECHAL_ENCODE_AVC_SKIP_BIAS_ADJUSTMENT_QP_THRESHOLD) && !bBrcEnabled;

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::GetHmeSupportedBasedOnTU(HmeLevel hmeLevel, bool *supported)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(supported);

    switch (hmeLevel)
    {
    case HME_LEVEL_4x:
        //HME always supported
        *supported = true;
        break;
    case HME_LEVEL_16x:
        *supported = SuperHME[m_targetUsage & 0x7] ? true : false;
        break;
    case HME_LEVEL_32x:
        *supported = UltraHME[m_targetUsage & 0x7] ? true : false;
        break;
    default:
        CODECHAL_ENCODE_ASSERTMESSAGE("Invalid hme Level");
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        break;
    }

    return eStatus;
}

static const bool CODECHAL_ENCODE_AVC_MBBRCEnabled_Common[NUM_TARGET_USAGE_MODES] =
{
    false, true, true, false, false, false, false, false
};

MOS_STATUS CodechalEncodeAvcEnc::GetMbBrcEnabled(uint32_t targetUsage, bool *mbBrcEnabled)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
    CODECHAL_ENCODE_CHK_NULL_RETURN(mbBrcEnabled);

    *mbBrcEnabled = CODECHAL_ENCODE_AVC_MBBRCEnabled_Common[targetUsage & 0x7];

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::GetCAFEnabled(bool *cafenable)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(cafenable);

    auto picParams = m_avcPicParam;
    auto targetUsage = m_targetUsage & 0x7;
    auto framePicture = CodecHal_PictureIsFrame(picParams->CurrOriginalPic);

    if (bCAFSupported)
    {
        switch (m_pictureCodingType)
        {
        case I_TYPE:
            *cafenable = false;
            break;
        case P_TYPE:
            *cafenable = (CODECHAL_ENCODE_AVC_AllFractional_Common[targetUsage] & 0x01) ? true : false;
            break;
        case B_TYPE:
            *cafenable = ((CODECHAL_ENCODE_AVC_AllFractional_Common[targetUsage] >> 1) & 0x01) ? true : false;
            break;
        default:
            CODECHAL_ENCODE_ASSERTMESSAGE("Invalid picture coding type");
            eStatus = MOS_STATUS_INVALID_PARAMETER;
            break;
        }

        // For performance reason, disable CAF for picture resolution >= 720P
        // a. Based on Target Usage.
        // b. For progressive pictures only.
        if (*cafenable)
        {
            if ((bCAFDisableHD && CODECHAL_ENCODE_AVC_DisableAllFractionalCheckForHighRes_Common[targetUsage] && framePicture)
                && (m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH >= 1280) && (m_frameFieldHeightInMb * CODECHAL_MACROBLOCK_HEIGHT >= 720))
            {
                *cafenable = false;
            }
        }
    }
    else
    {
        *cafenable = false;
    }

    return eStatus;
}

static const uint8_t CODECHAL_ENCODE_AVC_EnableAdaptiveTxDecision_Common[NUM_TARGET_USAGE_MODES] =
{
    0, 1, 1, 1, 1, 1, 1, 0
};

MOS_STATUS CodechalEncodeAvcEnc::GetATDEnabled()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    // If ATD has been disabled by user feature key, don't turn it on because it is supported by the TU.
    if (CODECHAL_ENCODE_AVC_EnableAdaptiveTxDecision_Common[m_targetUsage & 0x7] == 0)
        m_adaptiveTransformDecisionEnabled = false;

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::BrcInitResetKernel()
{
    MOS_STATUS                                          eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    uint32_t kernelIdx =
        (bBrcInit) ? CODECHAL_ENCODE_BRC_IDX_INIT : CODECHAL_ENCODE_BRC_IDX_RESET;
    auto kernelState = &BrcKernelStates[kernelIdx];

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL :
        CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

    CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_INIT_RESET;

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    // Setup AVC Curbe
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
        m_stateHeapInterface,
        kernelState,
        false,
        0,
        false,
        m_storeData));

    MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
    MOS_ZeroMemory(&idParams, sizeof(idParams));
    idParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
        m_stateHeapInterface,
        1,
        &idParams));

    CODECHAL_ENCODE_AVC_BRC_INIT_RESET_CURBE_PARAMS brcInitResetCurbeParams;
    brcInitResetCurbeParams.pdBrcInitCurrentTargetBufFullInBits =
        &dBrcInitCurrentTargetBufFullInBits;
    brcInitResetCurbeParams.pdwBrcInitResetBufSizeInBits =
        &dwBrcInitResetBufSizeInBits;
    brcInitResetCurbeParams.pdBrcInitResetInputBitsPerFrame =
        &dBrcInitResetInputBitsPerFrame;
    brcInitResetCurbeParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcBrcInitReset(
        &brcInitResetCurbeParams));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_DSH_TYPE,
            kernelState));
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            encFunctionType,
            kernelState));
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_ISH_TYPE,
            kernelState));
    )

//#if (_DEBUG || _RELEASE_INTERNAL)
//    if (m_swBrcMode != nullptr)
//    {
//        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgCallAvcSwBrcImpl(
//            m_debugInterface,
//            encFunctionType,
//            this,
//            &BrcBuffers,
//            bBrcReset,
//            kernelState,
//            kernelState));
//        return eStatus;
//    }
//#endif

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

    SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
    sendKernelCmdsParams.EncFunctionType = encFunctionType;
    sendKernelCmdsParams.bBrcResetRequested = bBrcInit ? false : bBrcReset; // Set BrcResetRequested to false if init is also set
    sendKernelCmdsParams.pKernelState = kernelState;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));

    // Add binding table
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
        m_stateHeapInterface,
        kernelState));

    //Add surface states
    CODECHAL_ENCODE_AVC_BRC_INIT_RESET_SURFACE_PARAMS brcInitResetSurfaceParams;
    brcInitResetSurfaceParams.presBrcHistoryBuffer =
        &BrcBuffers.resBrcHistoryBuffer;
    brcInitResetSurfaceParams.psMeBrcDistortionBuffer =
        &BrcBuffers.sMeBrcDistortionBuffer;
    brcInitResetSurfaceParams.dwMeBrcDistortionBottomFieldOffset =
        BrcBuffers.dwMeBrcDistortionBottomFieldOffset;
    brcInitResetSurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x;
    brcInitResetSurfaceParams.dwDownscaledFrameFieldHeightInMb4x =
        m_downscaledFrameFieldHeightInMb4x;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendBrcInitResetSurfaces(
        &cmdBuffer,
        &brcInitResetSurfaceParams));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_SSH_TYPE,
            kernelState));
    )

    HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
    HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

    MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
    MediaObjectInlineData mediaObjectInlineData;
    MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
    MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData));
    mediaObjectParams.pInlineData = &mediaObjectInlineData;
    mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject(
        &cmdBuffer,
        nullptr,
        &mediaObjectParams));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
        m_stateHeapInterface,
        kernelState));
    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
            m_stateHeapInterface));
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
    }

    CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
        &cmdBuffer,
        encFunctionType,
        nullptr)));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));

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

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
        m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
        m_lastTaskInPhase = false;
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::InitKernelStateSFD()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    pSFDKernelState = MOS_New(MHW_KERNEL_STATE);
    CODECHAL_ENCODE_CHK_NULL_RETURN(pSFDKernelState);

    uint8_t* kernelBinary;
    uint32_t kernelSize;

    uint32_t kuid = m_useCommonKernel ? m_kuidCommon : m_kuid;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, kuid, &kernelBinary, &kernelSize));

    CODECHAL_KERNEL_HEADER currKrnHeader;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnGetKernelHeaderAndSize(
        kernelBinary,
        ENC_SFD,
        0,
        &currKrnHeader,
        (uint32_t*)&kernelSize));

    auto kernelStatePtr = pSFDKernelState;
    kernelStatePtr->KernelParams.iBTCount = CODECHAL_ENCODE_AVC_SFD_NUM_SURFACES;
    kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads;
    kernelStatePtr->KernelParams.iCurbeLength = sizeof(CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON);
    kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
    kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
    kernelStatePtr->KernelParams.iIdCount = 1;
    kernelStatePtr->KernelParams.iInlineDataLength = 0;

    kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
    kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
    kernelStatePtr->KernelParams.iSize = kernelSize;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
        m_stateHeapInterface,
        kernelStatePtr->KernelParams.iBTCount,
        &kernelStatePtr->dwSshSize,
        &kernelStatePtr->dwBindingTableSize));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr));

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::InitKernelState()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateMe());
    CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateMbEnc());
    if(!CodecHalIsFeiEncode(m_codecFunction))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateMfeMbEnc());
        CODECHAL_ENCODE_CHK_NULL_RETURN(pMbEncKernelStates);
    }

    if (CodecHalIsFeiEncode(m_codecFunction))
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStatePreProc());
    }
    else
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateBrc());
    }
    if (bWeightedPredictionSupported)
    {
        if(m_feiEnable == false)
        {
            if (m_wpUseCommonKernel)
            {
                CODECHAL_ENCODE_CHK_STATUS_RETURN(m_wpState->InitKernelState());
            }
            else
            {
                CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateWP());
            }
        }
        else
        {
            if((m_codecFunction == CODECHAL_FUNCTION_FEI_ENC_PAK)||(m_codecFunction == CODECHAL_FUNCTION_FEI_ENC))
            {
                if (m_wpUseCommonKernel)
                {
                    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_wpState->InitKernelState());
                }
                else
                {
                    CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateWP());
                }
            }
        }
    }

    if ((bStaticFrameDetectionEnable) && (!bPerMbSFD) && (!m_feiEnable))
    {
        // init Static frame detection kernel
        CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateSFD());
    }

    if (m_singleTaskPhaseSupported)
    {
        if (m_codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC)
        {
            uint32_t dwScalingBtCount = MOS_ALIGN_CEIL(
                    m_scaling4xKernelStates[0].KernelParams.iBTCount,
                    m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
            uint32_t dwMeBtCount = MOS_ALIGN_CEIL(
                    m_meKernelStates[0].KernelParams.iBTCount,
                    m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
            uint32_t dwPreProcBtCount = MOS_ALIGN_CEIL(
                    PreProcKernelState.KernelParams.iBTCount,
                    m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
            // in preenc stateless case, the maximum scaling pass number is 1(for current frame/field)
            // + 4 (4 forward ref frames/fields) + 2(2 backward ref frames/fields)
            m_maxBtCount = dwScalingBtCount*(1 + 4 + 2) + dwMeBtCount + dwPreProcBtCount;
        }
        else
        {
            uint32_t dwScalingBtCount = MOS_ALIGN_CEIL(
                    m_scaling4xKernelStates[0].KernelParams.iBTCount,
                    m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
            uint32_t dwMeBtCount = MOS_ALIGN_CEIL(
                    m_hmeKernel ? m_hmeKernel->GetBTCount() : m_meKernelStates[0].KernelParams.iBTCount,
                    m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());

            uint32_t wpbtCount = 0;
            if(bWeightedPredictionSupported)
            {
                if (m_wpUseCommonKernel)
                {
                    wpbtCount += MOS_ALIGN_CEIL(
                            m_wpState->GetBTCount(),
                            m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
                }
                else
                {
                    wpbtCount += MOS_ALIGN_CEIL(
                            pWPKernelState->KernelParams.iBTCount,
                            m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
                }
            }

            uint32_t mbEncBtCount = 0;
            if (nullptr != pMbEncKernelStates)
            {
                mbEncBtCount = MOS_ALIGN_CEIL(
                        pMbEncKernelStates->KernelParams.iBTCount,
                        m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
            }

            uint32_t brcBtCount = 0;
            for (uint32_t i = 0; i < CODECHAL_ENCODE_BRC_IDX_NUM; i++)
            {
                brcBtCount += MOS_ALIGN_CEIL(
                        BrcKernelStates[i].KernelParams.iBTCount,
                        m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
            }

            uint32_t encOneBtCount = dwScalingBtCount + dwMeBtCount;
            encOneBtCount += (m_16xMeSupported) ? encOneBtCount : 0;
            encOneBtCount += (m_32xMeSupported) ? encOneBtCount : 0;
            uint32_t encTwoBtCount = mbEncBtCount + brcBtCount + wpbtCount;
            m_maxBtCount = MOS_MAX(encOneBtCount, encTwoBtCount);
        }
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::InsertInRefPicSelectList()
{
    MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    auto refPicSelectList = &RefPicSelectList[0];
    auto picParams = m_avcPicParam;
    auto currEncodeRefList = m_refList[picParams->CurrReconstructedPic.FrameIdx];

    uint8_t index = 0;
    uint8_t refFrameListIndex = 0;
    bool inserted = false;
    // Check if current PicIdx is already present in the list
    for (index = 0; index < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; index++)
    {
        if (refPicSelectList[index].FrameIdx == picParams->CurrReconstructedPic.FrameIdx)
        {
            ucCurrRefPicSelectIndex = index;
            return eStatus;
        }
    }

    // Save this picture in the list for future use
    // Use the first available index to save it
    for (index = 0; index < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; index++)
    {
        if (refPicSelectList[index].FrameIdx == CODECHAL_ENCODE_AVC_INVALID_PIC_ID) // Index not used
        {
            refPicSelectList[index].FrameIdx = picParams->CurrReconstructedPic.FrameIdx;
            ucCurrRefPicSelectIndex = index;
            inserted = true;
            break;
        }
    }

    if (!inserted)
    {
        // No unused index available, need to bump off an existing entry
        // Compare with RefFrameList sent through PicParams
        for (index = 0; index < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; index++)
        {
            bool foundMatch = false;

            for (refFrameListIndex = 0; refFrameListIndex < CODEC_AVC_MAX_NUM_REF_FRAME; refFrameListIndex++)
            {
                if (currEncodeRefList->RefList[refFrameListIndex].FrameIdx == refPicSelectList[index].FrameIdx)
                {
                    // reference still present in ref frame list, cannot be replaced
                    foundMatch = true;
                }
            }

            // Found an entry thats not in ref frame list anymore, safe to reuse
            if (foundMatch == false)
            {
                refPicSelectList[index].FrameIdx = picParams->CurrReconstructedPic.FrameIdx;
                ucCurrRefPicSelectIndex = index;
                inserted = true;
                break;
            }
        }

        if (!inserted)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Could not find an unused entry, this should never happen.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::MbEncKernel(bool mbEncIFrameDistInUse)
{
    MOS_STATUS                                  eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    uint8_t ppsidx = m_avcSliceParams->pic_parameter_set_id;
    uint8_t spsidx = m_avcPicParams[ppsidx]->seq_parameter_set_id;
    auto refList = &m_refList[0];
    auto currRefList = m_refList[m_currReconstructedPic.FrameIdx];
    bool use45DegreePattern = false;
    bool roiEnabled = (m_avcPicParams[ppsidx]->NumROI > 0) ? true : false;
    uint8_t refPicListIdx = m_avcSliceParams[ppsidx].RefPicList[0][0].FrameIdx;
    uint8_t refFrameListIdx = m_avcPicParam[ppsidx].RefFrameList[refPicListIdx].FrameIdx;
    bool bDirtyRoiEnabled = (m_pictureCodingType == P_TYPE
        && m_avcPicParams[ppsidx]->NumDirtyROI > 0
        && m_prevReconFrameIdx == refFrameListIdx);

    //  Two flags(bMbConstDataBufferNeeded, bMbQpBufferNeeded)
    //  would be used as there are two buffers and not all cases need both the buffers
    //  Constant Data buffer  needed for MBBRC, MBQP, ROI, RollingIntraRefresh
    //  Please note that this surface needs to be programmed for
    //  all usage cases(including CQP cases) because DWord13 includes mode cost for high texture MB?s cost.
    bool bMbConstDataBufferInUse = bMbBrcEnabled || bMbQpDataEnabled || roiEnabled || bDirtyRoiEnabled ||
        m_avcPicParam->EnableRollingIntraRefresh || bHighTextureModeCostEnable;

    bool mbQpBufferInUse = bMbBrcEnabled || bBrcRoiEnabled || bMbQpDataEnabled;

    if (m_feiEnable)
    {
        CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcFeiPicParams);
        bMbConstDataBufferInUse |= m_avcFeiPicParams->bMBQp;
        mbQpBufferInUse |= m_avcFeiPicParams->bMBQp;
    }

    // MFE MBEnc kernel handles several frames from different streams in one submission.
    // All the streams use the same HW/OS/StateHeap interfaces during this submssion.
    // All the streams use the kernel state from the first stream.
    // The first stream allocates the DSH and SSH, send the binding table.
    // The last stream sets mfe curbe, prepare and submit the command buffer.
    // All the streams set their own curbe surfaces and surface states.
    CODECHAL_ENCODE_AVC_BINDING_TABLE_MBENC     origMbEncBindingTable;
    if (IsMfeMbEncEnabled(mbEncIFrameDistInUse))
    {
        auto mfeEncodeSharedState = m_mfeEncodeSharedState;
        if (m_mfeFirstStream)
        {
            mfeEncodeSharedState->pHwInterface = m_hwInterface;
            mfeEncodeSharedState->pOsInterface = m_osInterface;
            m_hwInterface->GetRenderInterface()->m_stateHeapInterface = m_stateHeapInterface;
            m_osInterface->pfnResetOsStates(m_osInterface);
        }
        else
        {
            m_hwInterface           = mfeEncodeSharedState->pHwInterface;
            m_osInterface           = mfeEncodeSharedState->pOsInterface;
            m_stateHeapInterface    = m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
            m_renderEngineInterface->SetOsInterface(m_osInterface);
        }
        // Set maximum width/height, it is used for initializing media walker parameters
        // during submitting the command buffer at the last stream.
        if (m_picWidthInMb > mfeEncodeSharedState->dwPicWidthInMB)
        {
            mfeEncodeSharedState->dwPicWidthInMB = m_picWidthInMb;
        }
        if (m_frameFieldHeightInMb > mfeEncodeSharedState->dwPicHeightInMB)
        {
            mfeEncodeSharedState->dwPicHeightInMB = m_frameFieldHeightInMb;
        }

        uint16_t sliceHeight = m_arbitraryNumMbsInSlice ? m_frameFieldHeightInMb : m_sliceHeight;

        if (sliceHeight > mfeEncodeSharedState->sliceHeight)
        {
            mfeEncodeSharedState->sliceHeight = sliceHeight;
        }

        m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext);
        CODECHAL_DEBUG_TOOL(
            m_debugInterface->m_osInterface = m_osInterface;)
        // bookkeeping the original binding table
        origMbEncBindingTable = MbEncBindingTable;
    }

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = (mbEncIFrameDistInUse && !m_singleTaskPhaseSupported) ?
        CODECHAL_ENCODE_PERFTAG_CALL_INTRA_DIST : CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

    CODECHAL_MEDIA_STATE_TYPE encFunctionType;
    if (mbEncIFrameDistInUse)
    {
        encFunctionType = CODECHAL_MEDIA_STATE_ENC_I_FRAME_DIST;
    }
    else if (bUseMbEncAdvKernel)
    {
        encFunctionType = CODECHAL_MEDIA_STATE_ENC_ADV;
    }
    else if (m_kernelMode == encodeNormalMode)
    {
        encFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL;
    }
    else if (m_kernelMode == encodePerformanceMode)
    {
        encFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE;
    }
    else
    {
        encFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY;
    }

    // Initialize DSH kernel region
    PMHW_KERNEL_STATE kernelState;
    if (mbEncIFrameDistInUse)
    {
        kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST];
    }
    else if (IsMfeMbEncEnabled(mbEncIFrameDistInUse))
    {
        kernelState = &mfeMbEncKernelState;
    }
    else
    {
        CodechalEncodeIdOffsetParams idOffsetParams;
        MOS_ZeroMemory(&idOffsetParams, sizeof(idOffsetParams));
        idOffsetParams.Standard = m_standard;
        idOffsetParams.EncFunctionType = encFunctionType;
        idOffsetParams.wPictureCodingType = m_pictureCodingType;
        idOffsetParams.ucDmvPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag;
        idOffsetParams.interlacedField = CodecHal_PictureIsField(m_currOriginalPic);

        uint32_t krnStateIdx;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbEncKernelStateIdx(
            &idOffsetParams,
            &krnStateIdx));
        kernelState = &pMbEncKernelStates[krnStateIdx];
    }

    // All the streams use the kernel state from the first stream.
    if (IsMfeMbEncEnabled(mbEncIFrameDistInUse))
    {
        if (m_mfeFirstStream)
        {
            m_mfeEncodeSharedState->pMfeMbEncKernelState = kernelState;
        }
        else
        {
            kernelState = m_mfeEncodeSharedState->pMfeMbEncKernelState;
        }
    }

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported ||
            (IsMfeMbEncEnabled(mbEncIFrameDistInUse) && m_mfeFirstStream))
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    // Allocate DSH and SSH for the first stream, which will be passed to other streams through the shared kernel state.
     if ((IsMfeMbEncEnabled(mbEncIFrameDistInUse) && m_mfeFirstStream) ||
         (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) && !bMbEncCurbeSetInBrcUpdate))
    {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
                m_stateHeapInterface,
                kernelState,
                false,
                0,
                false,
                m_storeData));

            MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
            MOS_ZeroMemory(&idParams, sizeof(idParams));
            idParams.pKernelState = kernelState;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
                m_stateHeapInterface,
                1,
                &idParams));
    }

    if (bMbEncCurbeSetInBrcUpdate)
    {
        if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse))
        {
            // If BRC update was used to set up the DSH & SSH, SSH only needs to
            // be obtained if single task phase is enabled because the same SSH
            // could not be shared between BRC update and MbEnc
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
                m_stateHeapInterface,
                kernelState,
                true,
                0,
                m_singleTaskPhaseSupported,
                m_storeData));
        }
    }
    else
    {
        // Setup AVC Curbe
        CODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS mbEncCurbeParams;
        MOS_ZeroMemory(&mbEncCurbeParams, sizeof(mbEncCurbeParams));
        mbEncCurbeParams.pPicParams = m_avcPicParams[ppsidx];
        mbEncCurbeParams.pSeqParams = m_avcSeqParams[spsidx];
        mbEncCurbeParams.pSlcParams = m_avcSliceParams;
        mbEncCurbeParams.ppRefList = &(m_refList[0]);
        mbEncCurbeParams.pPicIdx = &(m_picIdx[0]);
        mbEncCurbeParams.bRoiEnabled = roiEnabled;
        mbEncCurbeParams.bDirtyRoiEnabled = bDirtyRoiEnabled;
        mbEncCurbeParams.bMbEncIFrameDistEnabled = mbEncIFrameDistInUse;
        mbEncCurbeParams.pdwBlockBasedSkipEn = &dwMbEncBlockBasedSkipEn;
        if (mbEncIFrameDistInUse)
        {
            mbEncCurbeParams.bBrcEnabled = false;
            mbEncCurbeParams.wPicWidthInMb = (uint16_t)m_downscaledWidthInMb4x;
            mbEncCurbeParams.wFieldFrameHeightInMb = (uint16_t)m_downscaledFrameFieldHeightInMb4x;
            mbEncCurbeParams.usSliceHeight = (m_sliceHeight + SCALE_FACTOR_4x - 1) / SCALE_FACTOR_4x;
        }
        else
        {
            mbEncCurbeParams.bBrcEnabled = bBrcEnabled;
            mbEncCurbeParams.wPicWidthInMb = m_picWidthInMb;
            mbEncCurbeParams.wFieldFrameHeightInMb = m_frameFieldHeightInMb;
            mbEncCurbeParams.usSliceHeight = (m_arbitraryNumMbsInSlice) ?
                m_frameFieldHeightInMb : m_sliceHeight;
            mbEncCurbeParams.bUseMbEncAdvKernel = bUseMbEncAdvKernel;
        }
        mbEncCurbeParams.pKernelState = kernelState;
        mbEncCurbeParams.pAvcQCParams = m_avcQCParams ;
        mbEncCurbeParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled;
        mbEncCurbeParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled;
        mbEncCurbeParams.bApdatvieSearchWindowSizeEnabled = bApdatvieSearchWindowEnable;
        mbEncCurbeParams.bSquareRollingIEnabled = bSquareRollingIEnabled;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbEnc(
            &mbEncCurbeParams));
    }

    if (IsMfeMbEncEnabled(mbEncIFrameDistInUse))
    {
        // Set MFE specific curbe in the last stream
        // MFE MBEnc specific curbe is different from the normal MBEnc curbe which is passed
        // to MFE MBEnc kernel as a surface.
        if (m_mfeLastStream)
        {
            CODECHAL_ENCODE_AVC_MFE_MBENC_CURBE_PARAMS mfeMbEncCurbeParams;
            MOS_ZeroMemory(&mfeMbEncCurbeParams, sizeof(mfeMbEncCurbeParams));
            mfeMbEncCurbeParams.submitNumber = m_mfeEncodeParams.submitNumber;
            mfeMbEncCurbeParams.pKernelState = kernelState;
            mfeMbEncCurbeParams.pBindingTable = &MbEncBindingTable;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMfeMbEnc(&mfeMbEncCurbeParams));
        }
        // Change the binding table according to the index during this submission
        UpdateMfeMbEncBindingTable(m_mfeEncodeParams.submitIndex);
    }

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_DSH_TYPE,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            encFunctionType,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_ISH_TYPE,
            kernelState));
    )

    for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
    {
        if (m_picIdx[i].bValid)
        {
            uint8_t index = m_picIdx[i].ucPicIdx;
            refList[index]->sRefBuffer = m_userFlags.bUseRawPicForRef ?
                refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer;

            CodecHalGetResourceInfo(m_osInterface, &refList[index]->sRefBuffer);
        }
    }

    MOS_COMMAND_BUFFER cmdBuffer;
    MOS_ZeroMemory(&cmdBuffer,sizeof(cmdBuffer));
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));

    // For MFE, All the commands are sent in the last stream and can not be sent in different streams
    // since cmdBuffer is zeroed for each stream and cmd buffer pointer is reset.
    if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeLastStream)
    {
        SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
        sendKernelCmdsParams.EncFunctionType = encFunctionType;
        sendKernelCmdsParams.ucDmvPredFlag =
            m_avcSliceParams->direct_spatial_mv_pred_flag;
        sendKernelCmdsParams.pKernelState = kernelState;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
    }

    // Set up MB BRC Constant Data Buffer if there is QP change within a frame
    if (bMbConstDataBufferInUse)
    {
        CODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS initMbBrcConstantDataBufferParams;

        MOS_ZeroMemory(&initMbBrcConstantDataBufferParams, sizeof(initMbBrcConstantDataBufferParams));
        initMbBrcConstantDataBufferParams.pOsInterface = m_osInterface;
        initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer =
            &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx];
        initMbBrcConstantDataBufferParams.dwMbEncBlockBasedSkipEn = dwMbEncBlockBasedSkipEn;
        initMbBrcConstantDataBufferParams.pPicParams = m_avcPicParams[ppsidx];
        initMbBrcConstantDataBufferParams.wPictureCodingType = m_pictureCodingType;
        initMbBrcConstantDataBufferParams.bSkipBiasAdjustmentEnable = m_skipBiasAdjustmentEnable;
        initMbBrcConstantDataBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable;
        initMbBrcConstantDataBufferParams.bOldModeCostEnable = bOldModeCostEnable;
        initMbBrcConstantDataBufferParams.pAvcQCParams = m_avcQCParams ;
        initMbBrcConstantDataBufferParams.bEnableKernelTrellis = bKernelTrellis && m_trellisQuantParams.dwTqEnabled;

        // Kernel controlled Trellis Quantization
        if (bKernelTrellis && m_trellisQuantParams.dwTqEnabled)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(CalcLambdaTable(
                m_pictureCodingType,
                &initMbBrcConstantDataBufferParams.Lambda[0][0]));
        }

        CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMbBrcConstantDataBuffer(&initMbBrcConstantDataBufferParams));

        // dump MbBrcLut
        CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer,
            CodechalDbgAttr::attrInput,
            "MbBrcLut",
            16 * (CODEC_AVC_NUM_QP) * sizeof(uint32_t),
            0,
            CODECHAL_MEDIA_STATE_ENC_QUALITY)));

    }

    // Add binding table
    // For MFE first stream sends binding table since the function zeros the whole SSH.
    // If last stream sends binding table it will clean the surface states from other streams.
    if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeFirstStream)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
            m_stateHeapInterface,
            kernelState));
    }

    //Add surface states
    CODECHAL_ENCODE_AVC_MBENC_SURFACE_PARAMS mbEncSurfaceParams;
    MOS_ZeroMemory(&mbEncSurfaceParams, sizeof(mbEncSurfaceParams));
    mbEncSurfaceParams.MediaStateType = encFunctionType;
    mbEncSurfaceParams.pAvcSlcParams = m_avcSliceParams;
    mbEncSurfaceParams.ppRefList = &m_refList[0];
    mbEncSurfaceParams.pAvcPicIdx = &m_picIdx[0];
    mbEncSurfaceParams.pCurrOriginalPic = &m_currOriginalPic;
    mbEncSurfaceParams.pCurrReconstructedPic = &m_currReconstructedPic;
    mbEncSurfaceParams.wPictureCodingType = m_pictureCodingType;
    mbEncSurfaceParams.psCurrPicSurface = mbEncIFrameDistInUse ? m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER) : m_rawSurfaceToEnc;
    if (mbEncIFrameDistInUse && CodecHal_PictureIsBottomField(m_currOriginalPic))
    {
        mbEncSurfaceParams.dwCurrPicSurfaceOffset = m_scaledBottomFieldOffset;
    }
    mbEncSurfaceParams.dwMbCodeBottomFieldOffset = (uint32_t)m_mbcodeBottomFieldOffset;
    mbEncSurfaceParams.dwMvBottomFieldOffset = (uint32_t)m_mvBottomFieldOffset;
    mbEncSurfaceParams.ps4xMeMvDataBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer;
    mbEncSurfaceParams.ps4xMeDistortionBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer;
    mbEncSurfaceParams.dwMeMvBottomFieldOffset = m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset(): (uint32_t)m_meMvBottomFieldOffset;
    mbEncSurfaceParams.psMeBrcDistortionBuffer = &BrcBuffers.sMeBrcDistortionBuffer;
    mbEncSurfaceParams.dwMeBrcDistortionBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset;
    mbEncSurfaceParams.dwMeDistortionBottomFieldOffset = m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset;
    mbEncSurfaceParams.dwRefPicSelectBottomFieldOffset = (uint32_t)ulRefPicSelectBottomFieldOffset;
    mbEncSurfaceParams.dwFrameWidthInMb = (uint32_t)m_picWidthInMb;
    mbEncSurfaceParams.dwFrameFieldHeightInMb = (uint32_t)m_frameFieldHeightInMb;
    mbEncSurfaceParams.dwFrameHeightInMb = (uint32_t)m_picHeightInMb;
    // Interleaved input surfaces
    mbEncSurfaceParams.dwVerticalLineStride = m_verticalLineStride;
    mbEncSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset;
    // Vertical line stride is not used for the case of scaled surfaces saved as separate fields
    if (!m_fieldScalingOutputInterleaved && mbEncIFrameDistInUse)
    {
        mbEncSurfaceParams.dwVerticalLineStride = 0;
        mbEncSurfaceParams.dwVerticalLineStrideOffset = 0;
    }
    mbEncSurfaceParams.bHmeEnabled = m_hmeSupported;
    mbEncSurfaceParams.bMbEncIFrameDistInUse = mbEncIFrameDistInUse;
    mbEncSurfaceParams.presMbBrcConstDataBuffer = &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx];
    mbEncSurfaceParams.psMbQpBuffer =
        bMbQpDataEnabled ? &sMbQpDataSurface : &BrcBuffers.sBrcMbQpBuffer;
    mbEncSurfaceParams.dwMbQpBottomFieldOffset = bMbQpDataEnabled ? 0 : BrcBuffers.dwBrcMbQpBottomFieldOffset;
    mbEncSurfaceParams.bUsedAsRef =
        m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef;
    mbEncSurfaceParams.presMADDataBuffer = &m_resMadDataBuffer[m_currMadBufferIdx];
    mbEncSurfaceParams.bMbQpBufferInUse = mbQpBufferInUse;
    mbEncSurfaceParams.bMbSpecificDataEnabled = bMbSpecificDataEnabled;
    mbEncSurfaceParams.presMbSpecificDataBuffer = &resMbSpecificDataBuffer[m_currRecycledBufIdx];
    mbEncSurfaceParams.bMbConstDataBufferInUse = bMbConstDataBufferInUse;
    mbEncSurfaceParams.bMADEnabled              = mbEncIFrameDistInUse ? false : m_madEnabled;
    mbEncSurfaceParams.bUseMbEncAdvKernel = mbEncIFrameDistInUse ? false : bUseMbEncAdvKernel;
    mbEncSurfaceParams.presMbEncCurbeBuffer =
        (mbEncIFrameDistInUse && bUseMbEncAdvKernel) ? nullptr : &BrcBuffers.resMbEncAdvancedDsh;
    mbEncSurfaceParams.presMbEncBRCBuffer = &BrcBuffers.resMbEncBrcBuffer;

    if (IsMfeMbEncEnabled(mbEncIFrameDistInUse) || bDecoupleMbEncCurbeFromBRC)
    {
        mbEncSurfaceParams.dwMbEncBRCBufferSize = m_mbencBrcBufferSize;
    }

    mbEncSurfaceParams.bUseAdvancedDsh = bAdvancedDshInUse;
    mbEncSurfaceParams.bBrcEnabled = bBrcEnabled;
    mbEncSurfaceParams.bArbitraryNumMbsInSlice = m_arbitraryNumMbsInSlice;
    mbEncSurfaceParams.psSliceMapSurface = &m_sliceMapSurface[m_currRecycledBufIdx];
    mbEncSurfaceParams.dwSliceMapBottomFieldOffset = (uint32_t)m_sliceMapBottomFieldOffset;
    mbEncSurfaceParams.pMbEncBindingTable = &MbEncBindingTable;
    mbEncSurfaceParams.pKernelState = kernelState;

    if (m_mbStatsSupported)
    {
        mbEncSurfaceParams.bMBVProcStatsEnabled = m_flatnessCheckEnabled ||
                                                  m_adaptiveTransformDecisionEnabled ||
                                                  bMbBrcEnabled ||
                                                  bMbQpDataEnabled;
        mbEncSurfaceParams.presMBVProcStatsBuffer = &m_resMbStatsBuffer;
        mbEncSurfaceParams.dwMBVProcStatsBottomFieldOffset = m_mbStatsBottomFieldOffset;
    }
    else
    {
        mbEncSurfaceParams.bFlatnessCheckEnabled = m_flatnessCheckEnabled;
        mbEncSurfaceParams.psFlatnessCheckSurface = &m_flatnessCheckSurface;
        mbEncSurfaceParams.dwFlatnessCheckBottomFieldOffset = (uint32_t)m_flatnessCheckBottomFieldOffset;
    }

    // Set up pFeiPicParams
    mbEncSurfaceParams.pFeiPicParams = m_avcFeiPicParams;

    mbEncSurfaceParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled;
    mbEncSurfaceParams.psMbDisableSkipMapSurface = psMbDisableSkipMapSurface;

    if (bUseWeightedSurfaceForL0 || bUseWeightedSurfaceForL1)
    {
        if (!m_wpUseCommonKernel)
        {
            mbEncSurfaceParams.pWeightedPredOutputPicSelectList = &WeightedPredOutputPicSelectList[0];
        }
        mbEncSurfaceParams.bUseWeightedSurfaceForL0 = bUseWeightedSurfaceForL0;
        mbEncSurfaceParams.bUseWeightedSurfaceForL1 = bUseWeightedSurfaceForL1;
    }

    // Clear the MAD buffer -- the kernel requires it to be 0 as it accumulates the result
    if (mbEncSurfaceParams.bMADEnabled)
    {
        // set lock flag to WRITE_ONLY
        MOS_LOCK_PARAMS lockFlags;
        MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
        lockFlags.WriteOnly = 1;

        uint8_t* pbData = (uint8_t*)m_osInterface->pfnLockResource(
            m_osInterface,
            mbEncSurfaceParams.presMADDataBuffer,
            &lockFlags);

        CODECHAL_ENCODE_CHK_NULL_RETURN(pbData);

        MOS_ZeroMemory(pbData, CODECHAL_MAD_BUFFER_SIZE);

        m_osInterface->pfnUnlockResource(
            m_osInterface,
            mbEncSurfaceParams.presMADDataBuffer);

        CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &m_resMadDataBuffer[m_currMadBufferIdx],
            CodechalDbgAttr::attrOutput,
            "MADRead",
            CODECHAL_MAD_BUFFER_SIZE,
            0,
            encFunctionType)));
    }

    // static frame detection buffer
    mbEncSurfaceParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled;
    mbEncSurfaceParams.presSFDOutputBuffer = &resSFDOutputBuffer[0];
    if (m_pictureCodingType == P_TYPE)
    {
        mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTablePFrameBuffer;
    }
    else if (m_pictureCodingType == B_TYPE)
    {
        mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTableBFrameBuffer;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcMbEncSurfaces(&cmdBuffer, &mbEncSurfaceParams));

    // For MFE, only one walker processes frame in parallel through color bits.
    if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeLastStream)
    {
        uint32_t dwResolutionX = mbEncIFrameDistInUse ?
            m_downscaledWidthInMb4x : (uint32_t)m_picWidthInMb;
        uint32_t dwResolutionY = mbEncIFrameDistInUse ?
            m_downscaledFrameFieldHeightInMb4x : (uint32_t)m_frameFieldHeightInMb;

        CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
        MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
        walkerCodecParams.WalkerMode = m_walkerMode;
        walkerCodecParams.bUseScoreboard = m_useHwScoreboard;
        walkerCodecParams.wPictureCodingType = m_pictureCodingType;
        walkerCodecParams.bMbEncIFrameDistInUse = mbEncIFrameDistInUse;
        walkerCodecParams.bMbaff = m_mbaffEnabled;
        walkerCodecParams.bDirectSpatialMVPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag;

        if (IsMfeMbEncEnabled(mbEncIFrameDistInUse))
        {
            walkerCodecParams.bColorbitSupported = true;
            walkerCodecParams.dwNumSlices = m_mfeEncodeParams.submitNumber;  // MFE use color bit to handle frames in parallel
            walkerCodecParams.WalkerDegree = CODECHAL_26_DEGREE;                        // MFE use 26 degree dependency
            walkerCodecParams.dwResolutionX = m_mfeEncodeSharedState->dwPicWidthInMB;
            walkerCodecParams.dwResolutionY = m_mfeEncodeSharedState->dwPicHeightInMB;
            walkerCodecParams.usSliceHeight = m_mfeEncodeSharedState->sliceHeight;
        }
        else
        {
            walkerCodecParams.bColorbitSupported = (m_colorbitSupported && !m_arbitraryNumMbsInSlice) ? m_cmKernelEnable : false;
            walkerCodecParams.dwResolutionX = dwResolutionX;
            walkerCodecParams.dwResolutionY = dwResolutionY;
            walkerCodecParams.dwNumSlices = m_numSlices;
            walkerCodecParams.usSliceHeight = m_sliceHeight;
        }
        walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported;
        walkerCodecParams.ucGroupId = m_groupId;

        MHW_WALKER_PARAMS walkerParams;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
            m_hwInterface,
            &walkerParams,
            &walkerCodecParams));

        HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
        HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
            &cmdBuffer,
            &walkerParams));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));

        // Add dump for MBEnc surface state heap here
        CODECHAL_DEBUG_TOOL(
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
                encFunctionType,
                MHW_SSH_TYPE,
                kernelState));
        )

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

        CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
            &cmdBuffer,
            encFunctionType,
            nullptr)));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));

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

        if ((!m_singleTaskPhaseSupported || m_lastTaskInPhase))
        {
            HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
            m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
            m_lastTaskInPhase = false;
        }
    }

    CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
        &BrcBuffers.sBrcMbQpBuffer.OsResource,
        CodechalDbgAttr::attrInput,
        "MbQp",
        BrcBuffers.sBrcMbQpBuffer.dwPitch*BrcBuffers.sBrcMbQpBuffer.dwHeight,
        BrcBuffers.dwBrcMbQpBottomFieldOffset,
        CODECHAL_MEDIA_STATE_ENC_NORMAL)));

    currRefList->ucMADBufferIdx = m_currMadBufferIdx;
    currRefList->bMADEnabled    = m_madEnabled;

    if (IsMfeMbEncEnabled(mbEncIFrameDistInUse))
    {
        m_stateHeapInterface    = m_origStateHeapInterface;
        m_hwInterface           = m_origHwInterface;
        m_osInterface           = m_origOsInterface;
        m_renderEngineInterface->SetOsInterface(m_origOsInterface);

        MbEncBindingTable       = origMbEncBindingTable;

        CODECHAL_DEBUG_TOOL(
            m_debugInterface->m_osInterface = m_osInterface;)
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::BrcFrameUpdateKernel()
{
    MOS_STATUS                                          eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    if (m_lastTaskInPhase)
    {
        perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE;
    }
    else
    {
        perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE;
    }
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

    auto kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_FrameBRC_UPDATE];

    uint8_t ppsidx = m_avcSliceParams->pic_parameter_set_id;
    uint8_t refPicListIdx = m_avcSliceParams[ppsidx].RefPicList[0][0].FrameIdx;
    uint8_t refFrameListIdx = m_avcPicParam[ppsidx].RefFrameList[refPicListIdx].FrameIdx;

    bool bDirtyRoiEnabled = (m_pictureCodingType == P_TYPE
        && m_avcPicParams[ppsidx]->NumDirtyROI > 0
        && m_prevReconFrameIdx == refFrameListIdx);

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_UPDATE;
    CODECHAL_MEDIA_STATE_TYPE mbEncFunctionType;
    if (bUseMbEncAdvKernel)
    {
        mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_ADV;
    }
    else if (m_kernelMode == encodeNormalMode)
    {
        mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL;
    }
    else if (m_kernelMode == encodePerformanceMode)
    {
        mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE;
    }
    else
    {
        mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY;
    }

    uint32_t krnStateIdx;
    CodechalEncodeIdOffsetParams idOffsetParams;
    MOS_ZeroMemory(&idOffsetParams, sizeof(idOffsetParams));
    idOffsetParams.Standard = m_standard;
    idOffsetParams.EncFunctionType = mbEncFunctionType;
    idOffsetParams.wPictureCodingType = m_pictureCodingType;
    idOffsetParams.ucDmvPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag;
    idOffsetParams.interlacedField = CodecHal_PictureIsField(m_currOriginalPic);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbEncKernelStateIdx(
        &idOffsetParams,
        &krnStateIdx));
    auto mbEncKernelState = &pMbEncKernelStates[krnStateIdx];

    auto brcImageStatesReadBuffer =
        &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx];

    // No need to setup MBEnc Curbe for Gen95+ platforms.
    if (!bDecoupleMbEncCurbeFromBRC)
    {
        // Mfe use MBEnc Curbe buffer instead of DSH
        if (IsMfeMbEncEnabled(false))
        {
            BrcBuffers.pMbEncKernelStateInUse = nullptr;
        }
        else
        {
            BrcBuffers.pMbEncKernelStateInUse = mbEncKernelState;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
                m_stateHeapInterface,
                mbEncKernelState,
                false,
                0,
                !m_singleTaskPhaseSupported,
                m_storeData));

            MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
            MOS_ZeroMemory(&idParams, sizeof(idParams));
            idParams.pKernelState = mbEncKernelState;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
                m_stateHeapInterface,
                1,
                &idParams));
        }

        CODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS mbEncCurbeParams;
        MOS_ZeroMemory(&mbEncCurbeParams, sizeof(mbEncCurbeParams));
        mbEncCurbeParams.pPicParams = m_avcPicParam;
        mbEncCurbeParams.pSeqParams = m_avcSeqParam;
        mbEncCurbeParams.pSlcParams = m_avcSliceParams;
        mbEncCurbeParams.ppRefList = &(m_refList[0]);
        mbEncCurbeParams.pPicIdx = &(m_picIdx[0]);
        mbEncCurbeParams.pdwBlockBasedSkipEn = &dwMbEncBlockBasedSkipEn;
        mbEncCurbeParams.wPicWidthInMb = m_picWidthInMb;
        mbEncCurbeParams.wFieldFrameHeightInMb = m_frameFieldHeightInMb;
        mbEncCurbeParams.usSliceHeight = (m_arbitraryNumMbsInSlice) ?
            m_frameFieldHeightInMb : m_sliceHeight;
        mbEncCurbeParams.bRoiEnabled = (m_avcPicParams[m_avcSliceParams->pic_parameter_set_id]->NumROI > 0) ? true : false;
        mbEncCurbeParams.bDirtyRoiEnabled = bDirtyRoiEnabled;
        mbEncCurbeParams.bBrcEnabled = true;
        mbEncCurbeParams.pKernelState = mbEncKernelState;
        mbEncCurbeParams.pAvcQCParams = m_avcQCParams ;
        mbEncCurbeParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled;
        mbEncCurbeParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled;
        mbEncCurbeParams.bApdatvieSearchWindowSizeEnabled = bApdatvieSearchWindowEnable;
        mbEncCurbeParams.bSquareRollingIEnabled = bSquareRollingIEnabled;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbEnc(&mbEncCurbeParams));

        // BrcCopy is not needed if MbEnc Adv kenrel is used.
        if (!bUseMbEncAdvKernel && bAdvancedDshInUse)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcCopyKernel());
        }
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
        m_stateHeapInterface,
        kernelState,
        false,
        0,
        (m_swBrcMode != nullptr),
        m_storeData));

    MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
    MOS_ZeroMemory(&idParams, sizeof(idParams));
    idParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
        m_stateHeapInterface,
        1,
        &idParams));

    // Setup BRC Update Curbe
    CODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS brcUpdateCurbeParams;
    MOS_ZeroMemory(&brcUpdateCurbeParams, sizeof(brcUpdateCurbeParams));
    // set skipped frame params to be used in pfnSetCurbeAvcFrameBrcUpdate()
    if (m_numSkipFrames > 0)
    {
        // CP case: one or more frames with skip flag = 2 received and copied
        brcUpdateCurbeParams.dwNumSkipFrames = m_numSkipFrames;
        brcUpdateCurbeParams.dwSizeSkipFrames = m_sizeSkipFrames;

        // this should not happen since skip flag == 1 means non-CP user case
        // but we accumulate the num/size of skipped frame per BRC
        if (FRAME_SKIP_NORMAL == m_skipFrameFlag)
        {
            brcUpdateCurbeParams.dwNumSkipFrames += m_avcPicParam->NumSkipFrames;
            brcUpdateCurbeParams.dwSizeSkipFrames += m_avcPicParam->SizeSkipFrames;
        }
    }
    else if (FRAME_SKIP_NORMAL == m_skipFrameFlag)
    {
        // non-CP case: use the num/size of skipped frames passed in by MSDK
        brcUpdateCurbeParams.dwNumSkipFrames = m_avcPicParam->NumSkipFrames;
        brcUpdateCurbeParams.dwSizeSkipFrames = m_avcPicParam->SizeSkipFrames;
    }
    else
        brcUpdateCurbeParams.dwNumSkipFrames = 0;

    // Setting min/max QP to zero indicates to the kernel that no QP control is desired
    if (m_pictureCodingType == I_TYPE)
    {
        brcUpdateCurbeParams.ucMinQP = ucIMinQP;
        brcUpdateCurbeParams.ucMaxQP = ucIMaxQP;
    }
    else if (m_pictureCodingType == P_TYPE)
    {
        brcUpdateCurbeParams.ucMinQP = ucPMinQP;
        brcUpdateCurbeParams.ucMaxQP = ucPMaxQP;
    }
    else
    {
        brcUpdateCurbeParams.ucMinQP = ucBMinQP;
        brcUpdateCurbeParams.ucMaxQP = ucBMaxQP;
    }
    // reset skip frame statistics
    m_numSkipFrames = 0;
    m_sizeSkipFrames = 0;

    bMbEncCurbeSetInBrcUpdate = !bDecoupleMbEncCurbeFromBRC;

    brcUpdateCurbeParams.pdBrcInitCurrentTargetBufFullInBits = &dBrcInitCurrentTargetBufFullInBits;
    brcUpdateCurbeParams.pKernelState = kernelState;
    brcUpdateCurbeParams.ucEnableROI = (uint8_t)bBrcRoiEnabled;
    brcUpdateCurbeParams.dwIntraRefreshQpThreshold = dwIntraRefreshQpThreshold;
    brcUpdateCurbeParams.bSquareRollingIEnabled = bSquareRollingIEnabled;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcFrameBrcUpdate(
        &brcUpdateCurbeParams));

    CODECHAL_DEBUG_TOOL(
        if (!bDecoupleMbEncCurbeFromBRC && !IsMfeMbEncEnabled(false))
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
                mbEncFunctionType,
                MHW_DSH_TYPE,
                mbEncKernelState));
        }

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_DSH_TYPE,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            encFunctionType,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_ISH_TYPE,
            kernelState));
    )

    auto trellisQuantParams = &m_trellisQuantParams;

#if (_DEBUG || _RELEASE_INTERNAL)

    if (m_swBrcMode != nullptr)
    {
        CODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS initBrcConstantBufferParams;
        // Check if the constant data surface is present
        initBrcConstantBufferParams.pOsInterface = m_osInterface;
        initBrcConstantBufferParams.pAvcSlcParams = m_avcSliceParams;
        initBrcConstantBufferParams.pAvcPicIdx = &m_picIdx[0];
        initBrcConstantBufferParams.sBrcConstantDataBuffer =
            BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx];
        initBrcConstantBufferParams.dwMbEncBlockBasedSkipEn = dwMbEncBlockBasedSkipEn;
        initBrcConstantBufferParams.pPicParams = m_avcPicParam;
        initBrcConstantBufferParams.wPictureCodingType = m_pictureCodingType;
        initBrcConstantBufferParams.bSkipBiasAdjustmentEnable = m_skipBiasAdjustmentEnable;
        initBrcConstantBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable;
        initBrcConstantBufferParams.bOldModeCostEnable = bOldModeCostEnable;
        initBrcConstantBufferParams.pAvcQCParams = m_avcQCParams ;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&initBrcConstantBufferParams));

        MHW_VDBOX_AVC_IMG_PARAMS imageStateParams;
        imageStateParams.pEncodeAvcPicParams = m_avcPicParam;
        imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam;
        imageStateParams.wPicWidthInMb = m_picWidthInMb;
        imageStateParams.wPicHeightInMb = m_picHeightInMb;
        imageStateParams.ppRefList = &(m_refList[0]);
        imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled;
        imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding;
        imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level);
        imageStateParams.ucKernelMode = m_kernelMode;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgBrcBuffer(
            brcImageStatesReadBuffer,
            &imageStateParams));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx],
            CodechalDbgAttr::attrInput,
            "ImgStateRead",
            BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(),
            0,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].OsResource,
            CodechalDbgAttr::attrInput,
            "ConstData",
            BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwPitch * BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwHeight,
            0,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));

        // PAK statistics buffer is only dumped for BrcUpdate kernel input
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.resBrcPakStatisticBuffer[0],
            CodechalDbgAttr::attrInput,
            "PakStats",
            m_brcPakStatisticsSize,
            0,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.sMeBrcDistortionBuffer.OsResource,
            CodechalDbgAttr::attrInput,
            "BrcDist",
            BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight,
            BrcBuffers.dwMeBrcDistortionBottomFieldOffset,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.resBrcHistoryBuffer,
            CodechalDbgAttr::attrInput,
            "HistoryRead",
            m_brcHistoryBufferSize,
            0,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));
        if (BrcBuffers.pMbEncKernelStateInUse)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
                CODECHAL_MEDIA_STATE_BRC_UPDATE,
                BrcBuffers.pMbEncKernelStateInUse));
        }
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &m_resMbStatsBuffer,
            CodechalDbgAttr::attrInput,
            "MBStatsSurf",
            m_hwInterface->m_avcMbStatBufferSize,
            0,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));

        // CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgCallAvcSwBrcImpl(
        //     m_debugInterface,
        //     encFunctionType,
        //     this,
        //     &BrcBuffers,
        //     false,
        //     kernelState,
        //     mbEncKernelState));

        return eStatus;
    }

#endif
    MOS_COMMAND_BUFFER cmdBuffer;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));

    SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
    sendKernelCmdsParams.EncFunctionType = encFunctionType;
    sendKernelCmdsParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));

    CODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS initBrcConstantBufferParams;
    // Check if the constant data surface is present
    initBrcConstantBufferParams.pOsInterface = m_osInterface;
    initBrcConstantBufferParams.pAvcSlcParams = m_avcSliceParams;
    initBrcConstantBufferParams.pAvcPicIdx = &m_picIdx[0];
    initBrcConstantBufferParams.sBrcConstantDataBuffer =
        BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx];
    initBrcConstantBufferParams.dwMbEncBlockBasedSkipEn = dwMbEncBlockBasedSkipEn;
    initBrcConstantBufferParams.pPicParams = m_avcPicParam;
    initBrcConstantBufferParams.wPictureCodingType = m_pictureCodingType;
    initBrcConstantBufferParams.bSkipBiasAdjustmentEnable = m_skipBiasAdjustmentEnable;
    initBrcConstantBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable;
    initBrcConstantBufferParams.bOldModeCostEnable = bOldModeCostEnable;
    initBrcConstantBufferParams.pAvcQCParams = m_avcQCParams ;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&initBrcConstantBufferParams));

    MHW_VDBOX_AVC_IMG_PARAMS imageStateParams;
    imageStateParams.pEncodeAvcPicParams = m_avcPicParam;
    imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam;
    imageStateParams.wPicWidthInMb = m_picWidthInMb;
    imageStateParams.wPicHeightInMb = m_picHeightInMb;
    imageStateParams.ppRefList = &(m_refList[0]);
    imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled;
    imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding;
    imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level);
    imageStateParams.ucKernelMode = m_kernelMode;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgBrcBuffer(
        brcImageStatesReadBuffer,
        &imageStateParams));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam(
            nullptr,
            nullptr));
    )

    // Add binding table
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
        m_stateHeapInterface,
        kernelState));

    //Add surface state
    CODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS brcUpdateSurfaceParams;
    MOS_ZeroMemory(&brcUpdateSurfaceParams, sizeof(brcUpdateSurfaceParams));
    brcUpdateSurfaceParams.MbEncMediaStateType = mbEncFunctionType;
    brcUpdateSurfaceParams.pBrcBuffers = &BrcBuffers;
    brcUpdateSurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x;
    brcUpdateSurfaceParams.dwDownscaledFrameFieldHeightInMb4x = m_downscaledFrameFieldHeightInMb4x;
    brcUpdateSurfaceParams.bMbBrcEnabled = bMbBrcEnabled;
    brcUpdateSurfaceParams.bUseAdvancedDsh = bAdvancedDshInUse;
    brcUpdateSurfaceParams.dwBrcPakStatisticsSize = m_brcPakStatisticsSize;
    brcUpdateSurfaceParams.dwBrcHistoryBufferSize = m_brcHistoryBufferSize;
    brcUpdateSurfaceParams.presMbEncCurbeBuffer = &BrcBuffers.resMbEncAdvancedDsh;
    brcUpdateSurfaceParams.ucCurrRecycledBufIdx = m_currRecycledBufIdx;
    brcUpdateSurfaceParams.pBrcUpdateBindingTable = &BrcUpdateBindingTable;
    brcUpdateSurfaceParams.pKernelState = kernelState;
    brcUpdateSurfaceParams.presMbEncBRCBuffer = &BrcBuffers.resMbEncBrcBuffer;

    if (bDecoupleMbEncCurbeFromBRC || IsMfeMbEncEnabled(false))
    {
        brcUpdateSurfaceParams.dwMbEncBRCBufferSize = m_mbencBrcBufferSize;
    }
    brcUpdateSurfaceParams.presMbStatBuffer = &m_resMbStatsBuffer;  //Starting from GEN9

    PMOS_SURFACE buffer4xMeMvData = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer;
    CODECHAL_ENCODE_CHK_NULL_RETURN(buffer4xMeMvData);
    uint32_t dwMvBufferHeightBack = buffer4xMeMvData->dwHeight; // save 4x ME output MV buffer height
    if (bMvDataNeededByBRC) //starting from G95
    {
        brcUpdateSurfaceParams.psMvDataBuffer = buffer4xMeMvData;
        brcUpdateSurfaceParams.dwMvBottomFieldOffset = (uint32_t)m_mvBottomFieldOffset;

        // BRC kernel only needs the MV data for reference 0
        brcUpdateSurfaceParams.psMvDataBuffer->dwHeight = m_downscaledFrameFieldHeightInMb4x * 4;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcBrcFrameUpdateSurfaces(
        &cmdBuffer,
        &brcUpdateSurfaceParams));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_SSH_TYPE,
            kernelState));
    )

    if (bMvDataNeededByBRC) //starting from G95
    {
        // restore back 4x ME mv buffer height
        buffer4xMeMvData->dwHeight = dwMvBufferHeightBack;
    }

    HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
    HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

    MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
    MediaObjectInlineData mediaObjectInlineData;
    MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
    MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData));
    mediaObjectParams.pInlineData = &mediaObjectInlineData;
    mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject(
        &cmdBuffer,
        nullptr,
        &mediaObjectParams));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));

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

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
            &cmdBuffer,
            encFunctionType,
            nullptr));

        if (m_swBrcMode == nullptr)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx],
                CodechalDbgAttr::attrInput,
                "ImgStateRead",
                BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(),
                0,
                CODECHAL_MEDIA_STATE_BRC_UPDATE));

            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].OsResource,
                CodechalDbgAttr::attrInput,
                "ConstData",
                BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwPitch * BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwHeight,
                0,
                CODECHAL_MEDIA_STATE_BRC_UPDATE));

            // PAK statistics buffer is only dumped for BrcUpdate kernel input
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.resBrcPakStatisticBuffer[0],
                CodechalDbgAttr::attrInput,
                "PakStats",
                m_brcPakStatisticsSize,
                0,
                CODECHAL_MEDIA_STATE_BRC_UPDATE));

            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.sMeBrcDistortionBuffer.OsResource,
                CodechalDbgAttr::attrInput,
                "BrcDist",
                BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight,
                BrcBuffers.dwMeBrcDistortionBottomFieldOffset,
                CODECHAL_MEDIA_STATE_BRC_UPDATE));

            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.resBrcHistoryBuffer,
                CodechalDbgAttr::attrInput,
                "HistoryRead",
                m_brcHistoryBufferSize,
                0,
                CODECHAL_MEDIA_STATE_BRC_UPDATE));
            if (BrcBuffers.pMbEncKernelStateInUse)
            {
                CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
                    CODECHAL_MEDIA_STATE_BRC_UPDATE,
                    BrcBuffers.pMbEncKernelStateInUse));
            }
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &m_resMbStatsBuffer,
                CodechalDbgAttr::attrInput,
                "MBStatsSurf",
                m_hwInterface->m_avcMbStatBufferSize,
                0,
                CODECHAL_MEDIA_STATE_BRC_UPDATE));
        }
    )

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));

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

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
        m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
        m_lastTaskInPhase = false;
    }

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.resBrcHistoryBuffer,
            CodechalDbgAttr::attrOutput,
            "HistoryWrite",
            m_brcHistoryBufferSize,
            0,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));)

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::BrcCopyKernel()
{
    MOS_STATUS                                          eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(BrcBuffers.pMbEncKernelStateInUse);

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL :
        CODECHAL_ENCODE_PERFTAG_CALL_BRC_COPY;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

    CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_BLOCK_COPY;
    auto kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_BLOCKCOPY];
    auto mbEncKernelState = BrcBuffers.pMbEncKernelStateInUse;
    uint32_t blockCopyHeight =
        mbEncKernelState->m_dshRegion.GetSize() / CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH;

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
        m_stateHeapInterface,
        kernelState,
        false,
        0,
        false,
        m_storeData));

    MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
    MOS_ZeroMemory(&idParams, sizeof(idParams));
    idParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
        m_stateHeapInterface,
        1,
        &idParams));

    if (kernelState->KernelParams.iCurbeLength > 0)
    {
        CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_CURBE_PARAMS brcBlockCopyCurbeParams;
        brcBlockCopyCurbeParams.pKernelState = kernelState;
        brcBlockCopyCurbeParams.dwBufferOffset = 0x00;
        brcBlockCopyCurbeParams.dwBlockHeight = blockCopyHeight;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcBrcBlockCopy(
            &brcBlockCopyCurbeParams));
    }

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_DSH_TYPE,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            encFunctionType,
            kernelState));
    )

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

    SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
    sendKernelCmdsParams.EncFunctionType = encFunctionType;
    sendKernelCmdsParams.pKernelState = kernelState;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));

    // Add binding table
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
        m_stateHeapInterface,
        kernelState));

    //Add surface states for Brc Copy
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendBrcBlockCopySurfaces(
        m_hwInterface,
        &cmdBuffer,
        mbEncKernelState,
        kernelState,
        &BrcBuffers.resMbEncAdvancedDsh));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_SSH_TYPE,
            kernelState));
    )

    MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
    MediaObjectInlineData mediaObjectInlineData;
    MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
    MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData));
    mediaObjectParams.pInlineData = &mediaObjectInlineData;
    mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData);

    uint32_t blockHeight =
        CODECHAL_ENCODE_AVC_BRC_COPY_NUM_ROWS_PER_VME_SEND_MSG * CODECHAL_ENCODE_AVC_BRC_COPY_NUM_SEND_MSGS_PER_KERNEL;
    uint32_t remainingRows = blockCopyHeight;
    for (uint32_t i = 0; i < blockCopyHeight; i++)
    {
        if (remainingRows < blockHeight)
        {
            blockHeight = remainingRows;
        }
        mediaObjectInlineData.DW0.blockHeight = blockHeight;
        mediaObjectInlineData.DW0.bufferOffset = i;

        HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
        HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject(
            &cmdBuffer,
            nullptr,
            &mediaObjectParams));

        remainingRows -= blockHeight;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
        m_stateHeapInterface,
        kernelState));
    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
            m_stateHeapInterface));
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));

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

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
        m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
        m_lastTaskInPhase = false;
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::BrcMbUpdateKernel()
{
    MOS_STATUS                                      eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

    auto kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_MbBRC_UPDATE];

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_MB_BRC_UPDATE;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
        m_stateHeapInterface,
        kernelState,
        false,
        0,
        false,
        m_storeData));

    MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
    MOS_ZeroMemory(&idParams, sizeof(idParams));
    idParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
        m_stateHeapInterface,
        1,
        &idParams));

    // Setup MbBRC Curbe
    CODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS brcUpdateCurbeParams;
    MOS_ZeroMemory(&brcUpdateCurbeParams, sizeof(brcUpdateCurbeParams));
    brcUpdateCurbeParams.ucEnableROI = (uint8_t)bBrcRoiEnabled;
    brcUpdateCurbeParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbBrcUpdate(
        &brcUpdateCurbeParams));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_DSH_TYPE,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            encFunctionType,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_ISH_TYPE,
            kernelState));
    )

    // Setup ROI Surface
    if (bBrcRoiSupported && bBrcRoiEnabled)
    {
        SetupROISurface();
    }

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.resBrcHistoryBuffer,
            CodechalDbgAttr::attrInput,
            "HistoryRead",
            m_brcHistoryBufferSize,
            0,
            CODECHAL_MEDIA_STATE_MB_BRC_UPDATE));)

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

    SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
    sendKernelCmdsParams.EncFunctionType = encFunctionType;
    sendKernelCmdsParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));

    // Add binding table
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
        m_stateHeapInterface,
        kernelState));

    //Add surface state
    CODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS brcUpdateSurfaceParams;
    MOS_ZeroMemory(&brcUpdateSurfaceParams, sizeof(brcUpdateSurfaceParams));
    brcUpdateSurfaceParams.pBrcBuffers = &BrcBuffers;
    brcUpdateSurfaceParams.bMbBrcEnabled = bMbBrcEnabled;
    brcUpdateSurfaceParams.bBrcRoiEnabled = bBrcRoiEnabled;
    brcUpdateSurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x;
    brcUpdateSurfaceParams.dwDownscaledFrameFieldHeightInMb4x = m_downscaledFrameFieldHeightInMb4x;
    brcUpdateSurfaceParams.psRoiSurface = &BrcBuffers.sBrcRoiSurface;
    brcUpdateSurfaceParams.presMbStatBuffer = &m_resMbStatsBuffer;
    brcUpdateSurfaceParams.dwBrcPakStatisticsSize = m_brcPakStatisticsSize;
    brcUpdateSurfaceParams.dwBrcHistoryBufferSize = m_brcHistoryBufferSize;
    brcUpdateSurfaceParams.ucCurrRecycledBufIdx = m_currRecycledBufIdx;
    brcUpdateSurfaceParams.pBrcUpdateBindingTable = &BrcUpdateBindingTable;
    brcUpdateSurfaceParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcBrcMbUpdateSurfaces(
        &cmdBuffer,
        &brcUpdateSurfaceParams));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_SSH_TYPE,
            kernelState));
    )

    // set-up media walker
    CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
    MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
    walkerCodecParams.WalkerMode = m_walkerMode;
    walkerCodecParams.dwResolutionX = MOS_ROUNDUP_SHIFT(m_picWidthInMb, 2);
    walkerCodecParams.dwResolutionY = MOS_ROUNDUP_SHIFT(m_picHeightInMb, 2);
    walkerCodecParams.bNoDependency = true;
    walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported;

    MHW_WALKER_PARAMS walkerParams;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
        m_hwInterface,
        &walkerParams,
        &walkerCodecParams));

    HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
    HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
        &cmdBuffer,
        &walkerParams));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));

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

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
            &cmdBuffer,
            encFunctionType,
            nullptr));
    )

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));

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

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
        m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
        m_lastTaskInPhase = false;
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::WPKernel(bool useRefPicList1, uint32_t index)
{
    MOS_STATUS                              eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    if (Mos_ResourceIsNull(&WeightedPredOutputPicSelectList[0].sBuffer.OsResource))
    {
        // initiate allocation parameters
        MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferNV12;
        MOS_ZeroMemory(&allocParamsForBufferNV12, sizeof(MOS_ALLOC_GFXRES_PARAMS));
        allocParamsForBufferNV12.Type = MOS_GFXRES_2D;
        allocParamsForBufferNV12.TileType = MOS_TILE_Y;
        allocParamsForBufferNV12.Format = Format_NV12;

        // WP allocation
        auto refPicSelect = WeightedPredOutputPicSelectList;
        for (uint32_t i = 0; i < CODEC_AVC_NUM_WP_FRAME; i++)
        {
            MOS_ZeroMemory(&refPicSelect[i].sBuffer, sizeof(MOS_SURFACE));
            refPicSelect[i].FrameIdx = CODECHAL_ENCODE_AVC_INVALID_PIC_ID;
            refPicSelect[i].sBuffer.dwWidth = m_frameWidth;
            refPicSelect[i].sBuffer.dwHeight = m_frameHeight;

            allocParamsForBufferNV12.dwWidth = refPicSelect[i].sBuffer.dwWidth;
            allocParamsForBufferNV12.dwHeight = refPicSelect[i].sBuffer.dwHeight;
            allocParamsForBufferNV12.pBufName = "WP Scaled output Buffer";

            CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
                m_osInterface,
                &allocParamsForBufferNV12,
                &refPicSelect[i].sBuffer.OsResource),
                "Failed to allocate WP Scaled output Buffer.");

            CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
                m_osInterface,
                &refPicSelect[i].sBuffer));
        }
    }

    auto refList = &m_refList[0];
    auto currRefList = m_refList[m_currReconstructedPic.FrameIdx];

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_WP_KERNEL;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

    CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_ENC_WP;

    auto kernelState = pWPKernelState;

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    // Set up the DSH/SSH as normal
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
        m_stateHeapInterface,
        kernelState,
        false,
        0,
        false,
        m_storeData));

    MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
    MOS_ZeroMemory(&idParams, sizeof(idParams));
    idParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
        m_stateHeapInterface,
        1,
        &idParams));

    // Setup AVC Curbe
    CODECHAL_ENCODE_AVC_WP_CURBE_PARAMS wpcurbeParams;
    MOS_ZeroMemory(&wpcurbeParams, sizeof(wpcurbeParams));
    wpcurbeParams.RefPicListIdx = (useRefPicList1) ? LIST_1 : LIST_0;
    wpcurbeParams.WPIdx = index;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcWP(
        &wpcurbeParams));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_DSH_TYPE,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            encFunctionType,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_ISH_TYPE,
            kernelState));
    )

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

    SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
    sendKernelCmdsParams.EncFunctionType = encFunctionType;
    sendKernelCmdsParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));

    // Add binding table
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
        m_stateHeapInterface,
        kernelState));

    uint8_t picIndex = 0;
    uint8_t wpindex;
    uint8_t refVDirection;
    uint32_t refVerticalLineStride;
    uint32_t refVerticalLineStrideOffset;
    auto refPic = m_avcSliceParams->RefPicList[useRefPicList1][index];
    if (!CodecHal_PictureIsInvalid(refPic) && m_picIdx[refPic.FrameIdx].bValid)
    {
        picIndex = m_picIdx[refPic.FrameIdx].ucPicIdx;
        refList[picIndex]->sRefBuffer = m_userFlags.bUseRawPicForRef ?
            refList[picIndex]->sRefRawBuffer : refList[picIndex]->sRefReconBuffer;

        bool currFieldPicture = CodecHal_PictureIsField(m_currOriginalPic);
        bool refBottomField = (CodecHal_PictureIsBottomField(refPic));

        // Program the surface based on current picture's field/frame mode
        if (currFieldPicture) // if current picture is field
        {
            if (refBottomField)
            {
                refVDirection = CODECHAL_VDIRECTION_BOT_FIELD;
                refVerticalLineStride = CODECHAL_VLINESTRIDE_FIELD;
                refVerticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_BOT_FIELD;
            }
            else
            {
                refVDirection = CODECHAL_VDIRECTION_TOP_FIELD;
                refVerticalLineStride = CODECHAL_VLINESTRIDE_FIELD;
                refVerticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
            }
        }
        else // if current picture is frame
        {
            refVDirection = CODECHAL_VDIRECTION_FRAME;
            refVerticalLineStride = CODECHAL_VLINESTRIDE_FRAME;
            refVerticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
        }

        (useRefPicList1) ? bUseWeightedSurfaceForL1 = true : bUseWeightedSurfaceForL0 = true;
    }
    else
    {
        (useRefPicList1) ? bUseWeightedSurfaceForL1 = false : bUseWeightedSurfaceForL0 = false;
        return eStatus;
    }

    CodecHalGetResourceInfo(m_osInterface, &refList[picIndex]->sRefBuffer);

    //Add surface states
    CODECHAL_ENCODE_AVC_WP_SURFACE_PARAMS wpsurfaceParams;
    MOS_ZeroMemory(&wpsurfaceParams, sizeof(wpsurfaceParams));

    wpsurfaceParams.psInputRefBuffer = &refList[picIndex]->sRefBuffer;
    if (useRefPicList1) {
        wpindex = CODEC_AVC_WP_OUTPUT_L1_START + index;
    }
    else {
        wpindex = CODEC_AVC_WP_OUTPUT_L0_START + index;
    }
    wpsurfaceParams.psOutputScaledBuffer = &(WeightedPredOutputPicSelectList[wpindex].sBuffer);
    wpsurfaceParams.ucVDirection = refVDirection;
    wpsurfaceParams.dwVerticalLineStride = refVerticalLineStride;
    wpsurfaceParams.dwVerticalLineStrideOffset = refVerticalLineStrideOffset;
    wpsurfaceParams.pKernelState = kernelState;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcWPSurfaces(&cmdBuffer, &wpsurfaceParams));

    if (m_hwWalker)
    {
        uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth);
        uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight);

        CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
        MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
        walkerCodecParams.WalkerMode = m_walkerMode;
        walkerCodecParams.bUseScoreboard = m_useHwScoreboard;
        walkerCodecParams.dwResolutionX = resolutionX;
        walkerCodecParams.dwResolutionY = resolutionY;
        walkerCodecParams.wPictureCodingType = m_pictureCodingType;
        walkerCodecParams.bMbaff = m_mbaffEnabled;
        walkerCodecParams.dwNumSlices = m_numSlices;
        walkerCodecParams.usSliceHeight = m_sliceHeight;
        walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported;
        walkerCodecParams.ucGroupId = m_groupId;
        walkerCodecParams.bNoDependency = true;     /* Enforce no dependency dispatch order for Scaling kernel,  */

        MHW_WALKER_PARAMS walkerParams;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
            m_hwInterface,
            &walkerParams,
            &walkerCodecParams));

        HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
        HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
            &cmdBuffer,
            &walkerParams));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));

    // Add dump for WP surface state heap here
    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_SSH_TYPE,
            kernelState));
    )

    CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
        &cmdBuffer,
        encFunctionType,
        nullptr)));

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

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));

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

    if ((!m_singleTaskPhaseSupported || m_lastTaskInPhase))
    {
        HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
        m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
        m_lastTaskInPhase = false;
    }

    currRefList->ucMADBufferIdx = m_currMadBufferIdx;
    currRefList->bMADEnabled    = m_madEnabled;

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::SFDKernel()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

    // set function type and kernel state pointer
    auto encFunctionType = CODECHAL_MEDIA_STATE_STATIC_FRAME_DETECTION;
    auto kernelState = pSFDKernelState;

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
        m_stateHeapInterface,
        kernelState,
        false,
        0,
        false,
        m_storeData));

    MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
    MOS_ZeroMemory(&idParams, sizeof(idParams));
    idParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
        m_stateHeapInterface,
        1,
        &idParams));

    // set-up SFD Curbe
    CODECHAL_ENCODE_AVC_SFD_CURBE_PARAMS sfdcurbeParams;
    MOS_ZeroMemory(&sfdcurbeParams, sizeof(sfdcurbeParams));
    sfdcurbeParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcSFD(
        &sfdcurbeParams));

    // dump DSH/Curbe/ISH
    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_DSH_TYPE,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            encFunctionType,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_ISH_TYPE,
            kernelState));
    )

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

    SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
    sendKernelCmdsParams.EncFunctionType = encFunctionType;
    sendKernelCmdsParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));

    // Add binding table
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
        m_stateHeapInterface,
        kernelState));

    // Add surface states
    CODECHAL_ENCODE_AVC_SFD_SURFACE_PARAMS sfdsurfaceParams;
    MOS_ZeroMemory(&sfdsurfaceParams, sizeof(sfdsurfaceParams));
    sfdsurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x;
    sfdsurfaceParams.dwDownscaledHeightInMb4x = m_downscaledFrameFieldHeightInMb4x;
    sfdsurfaceParams.psMeMvDataSurface = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer;
    sfdsurfaceParams.dwMeMvBottomFieldOffset = m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset() : (uint32_t)m_meMvBottomFieldOffset;
    sfdsurfaceParams.psMeDistortionSurface = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer;
    sfdsurfaceParams.dwMeDistortionBottomFieldOffset = m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset;
    sfdsurfaceParams.presOutputBuffer = &resSFDOutputBuffer[0];
    sfdsurfaceParams.pKernelState = kernelState;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcSFDSurfaces(
        &cmdBuffer,
        &sfdsurfaceParams));

    // dump SSH
    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            encFunctionType,
            MHW_SSH_TYPE,
            kernelState));
    )

    HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
    HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

    MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
    MediaObjectInlineData mediaObjectInlineData;
    MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
    MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData));
    mediaObjectParams.pInlineData = &mediaObjectInlineData;
    mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject(
        &cmdBuffer,
        nullptr,
        &mediaObjectParams));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));

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

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
            &cmdBuffer,
            encFunctionType,
            nullptr));
    )

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));

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

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
        m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
        m_lastTaskInPhase = false;
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::SetCurbeAvcSFD(PCODECHAL_ENCODE_AVC_SFD_CURBE_PARAMS params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);

    CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON                curbe;
    MOS_ZeroMemory(&curbe, sizeof(curbe));
    curbe.DW0.EnableIntraCostScalingForStaticFrame = 1;
    curbe.DW0.EnableAdaptiveMvStreamIn = 0;
    curbe.DW0.StreamInType = 7;
    curbe.DW0.SliceType = (m_pictureCodingType + 1) % 3;
    curbe.DW0.BRCModeEnable = (bBrcEnabled != 0);
    curbe.DW0.VDEncModeDisable = true;

    curbe.DW1.HMEStreamInRefCost = 5;
    curbe.DW1.NumOfRefs = m_avcSliceParams->num_ref_idx_l0_active_minus1;
    curbe.DW1.QPValue = m_avcPicParam->QpY + m_avcSliceParams->slice_qp_delta;

    // SFD kernel requires to round-down to 4-MB aligned
    curbe.DW2.FrameHeightInMBs = (m_oriFrameHeight / CODECHAL_MACROBLOCK_HEIGHT >> 2) << 2;
    curbe.DW2.FrameWidthInMBs = (m_oriFrameWidth / CODECHAL_MACROBLOCK_WIDTH >> 2) << 2;
    curbe.DW3.LargeMvThresh = 128;
    uint32_t totalMb = curbe.DW2.FrameWidthInMBs * curbe.DW2.FrameHeightInMBs;
    curbe.DW4.TotalLargeMvThreshold = totalMb / 100;
    curbe.DW5.ZMVThreshold = 4;
    curbe.DW6.TotalZMVThreshold = totalMb * m_avcPicParam->dwZMvThreshold / 100;
    curbe.DW7.MinDistThreshold = 10;

    if (P_TYPE == m_pictureCodingType)
    {
        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(curbe.CostTable, CODEC_AVC_NUM_QP * sizeof(uint8_t), m_codechalEncodeAvcSfdCostTablePFrame, CODEC_AVC_NUM_QP * sizeof(uint8_t)),
            "Failed to copy P-frame SFD cost table");
    }
    else if (B_TYPE == m_pictureCodingType)
    {
        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(curbe.CostTable, CODEC_AVC_NUM_QP * sizeof(uint8_t), m_codechalEncodeAvcSfdCostTableBFrame, CODEC_AVC_NUM_QP * sizeof(uint8_t)),
            "Failed to copy B-frame SFD cost table");
    }

    curbe.DW21.ActualHeightInMB = curbe.DW2.FrameHeightInMBs;
    curbe.DW21.ActualWidthInMB = curbe.DW2.FrameWidthInMBs;
    curbe.DW26.MVDataSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON;
    curbe.DW27.InterDistortionSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON;
    curbe.DW28.OutputDataSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
        &curbe,
        params->pKernelState->dwCurbeOffset,
        sizeof(curbe)));

    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    auto seqParams = m_avcSeqParam;

    if (m_targetUsageOverride)
    {
        seqParams->TargetUsage = m_targetUsageOverride;
    }

    if (m_feiEnable)
    {
        // FEI kernel is based on normal mode TU = TARGETUSAGE_RT_SPEED(4)
        seqParams->TargetUsage = TARGETUSAGE_RT_SPEED;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetSequenceStructs());

    // If 16xMe is supported then check if it is supported in the TU settings
    if (!m_16xMeUserfeatureControl && m_16xMeSupported)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(GetHmeSupportedBasedOnTU(HME_LEVEL_16x, &m_16xMeSupported));
    }

    // If 32xMe is supported then check if it is supported in the TU settings
    if (!m_32xMeUserfeatureControl && m_32xMeSupported)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(GetHmeSupportedBasedOnTU(HME_LEVEL_32x, &m_32xMeSupported));
    }

    if (m_firstFrame)
    {
        m_oriFrameHeight = seqParams->FrameHeight;
        m_oriFrameWidth = seqParams->FrameWidth;
    }

    // check if there is a dynamic resolution change
    if ((m_oriFrameHeight && (m_oriFrameHeight != seqParams->FrameHeight)) ||
        (m_oriFrameWidth && (m_oriFrameWidth != seqParams->FrameWidth)))
    {
        m_resolutionChanged = true;
        m_oriFrameHeight = seqParams->FrameHeight;
        m_oriFrameWidth = seqParams->FrameWidth;
        // Need to call BRCInit instead of BRCReset for dynamic resolution change
        bBrcInit = true;
    }
    else
    {
        m_resolutionChanged = false;
    }

    usAVBRAccuracy = CODECHAL_ENCODE_AVC_DEFAULT_AVBR_ACCURACY;
    usAVBRConvergence = CODECHAL_ENCODE_AVC_DEFAULT_AVBR_CONVERGENCE;

    bBrcEnabled =
        CodecHalIsRateControlBrc(seqParams->RateControlMethod, CODECHAL_AVC);

    if (m_osInterface->osCpInterface->IsHMEnabled())
    {
        // use MbEnc Adv kernel when DSH protection is disabled and Brc is enabled
        if (bBrcEnabled)
        {
            bAdvancedDshInUse = true;
            bUseMbEncAdvKernel = true;
        }
    }

    if (ucMbBrcSupportCaps && bBrcEnabled)
    {
        // control MBBRC if the user feature key does not exist
        if (!bMbBrcUserFeatureKeyControl)
        {
            if (seqParams->RateControlMethod == RATECONTROL_ICQ || seqParams->RateControlMethod == RATECONTROL_QVBR)
            {
                // If the rate control method is ICQ or QVBR then enable MBBRC by default for all TUs and ignore the app input
                bMbBrcEnabled = true;
                CODECHAL_ENCODE_NORMALMESSAGE("MBBRC enabled with rate control = %d", seqParams->RateControlMethod);
            }
            else if (seqParams->RateControlMethod == RATECONTROL_VCM)
            {
                // If the rate control method is VCM then disable MBBRC by default for all TUs and ignore the app input
                bMbBrcEnabled = false;
            }
            else
            {
                switch (seqParams->MBBRC)
                {
                case mbBrcInternal:
                    // Enable or disable MBBRC based on TU
                    CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbBrcEnabled(seqParams->TargetUsage, &bMbBrcEnabled));
                    break;
                case mbBrcDisabled:
                    bMbBrcEnabled = false;
                    break;
                case mbBrcEnabled:
                    bMbBrcEnabled = true;
                    break;
                }
            }
        }
    }

    dwTrellis = seqParams->Trellis;
    bROIValueInDeltaQP = seqParams->ROIValueInDeltaQP;

    // Simple check for BRC parameters; if error, disable BRC and continue encoding
    if (bBrcEnabled &&
        ((((!seqParams->InitVBVBufferFullnessInBit ||
            !seqParams->VBVBufferSizeInBit ||
            !seqParams->MaxBitRate) &&
            (seqParams->RateControlMethod != RATECONTROL_AVBR)) ||
            !seqParams->TargetBitRate ||
            !seqParams->FramesPer100Sec) &&
            seqParams->RateControlMethod != RATECONTROL_ICQ))
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Fatal error in AVC Encoding BRC parameters.");
        CODECHAL_ENCODE_ASSERTMESSAGE("RateControlMethod = %d, InitVBVBufferFullnessInBit = %d, VBVBufferSizeInBit = %d, MaxBitRate = %d, TargetBitRate = %d, FramesPer100Sec = %d",
            seqParams->RateControlMethod, seqParams->InitVBVBufferFullnessInBit, seqParams->VBVBufferSizeInBit, seqParams->MaxBitRate, seqParams->TargetBitRate, seqParams->FramesPer100Sec);
        bBrcEnabled = false;
    }

    // Mb Qp data is only enabled for CQP
    if (bBrcEnabled)
    {
        bMbQpDataEnabled = false;
    }

    // BRC Init or Reset
    if (seqParams->bInitBRC)
    {
        bBrcInit = seqParams->bInitBRC;
    }
    else
    {
        bBrcReset = seqParams->bResetBRC;
    }

    if (bBrcReset &&
        (!bBrcEnabled ||
            seqParams->RateControlMethod == RATECONTROL_ICQ ||
            !bBrcDistortionBufferSupported))
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("BRC Reset cannot be trigerred on SNB or in CQP/CBR/ICQ modes - invalid BRC parameters.");
        bBrcReset = 0;
    }

    if (seqParams->RateControlMethod == RATECONTROL_ICQ)
    {
        if (seqParams->ICQQualityFactor < CODECHAL_ENCODE_AVC_MIN_ICQ_QUALITYFACTOR ||
            seqParams->ICQQualityFactor > CODECHAL_ENCODE_AVC_MAX_ICQ_QUALITYFACTOR)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Invalid ICQ Quality Factor input\n");
            eStatus = MOS_STATUS_INVALID_PARAMETER;
            return eStatus;
        }
    }

    if (bBrcEnabled && !bPerMbSFD)
    {
        bStaticFrameDetectionEnable = false;
    }

    // if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer
    m_gopIsIdrFrameOnly = (seqParams->GopPicSize == 1 && seqParams->GopRefDist == 0);

    // Set sliding window size to one second by default, up to 60
    if (dwSlidingWindowSize == 0)
    {
        dwSlidingWindowSize = MOS_MIN((uint32_t)(seqParams->FramesPer100Sec / 100), 60);
    }

    if (seqParams->FramesPer100Sec == 0)
    {
        return MOS_STATUS_INVALID_PARAMETER;
    }
    m_maxNumSlicesAllowed = CodecHalAvcEncode_GetMaxNumSlicesAllowed(
        (CODEC_AVC_PROFILE_IDC)(seqParams->Profile),
        (CODEC_AVC_LEVEL_IDC)(seqParams->Level),
        seqParams->FramesPer100Sec);

    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    auto picParams = m_avcPicParam;
    auto seqParams = m_avcSeqParam;
    auto avcRefList = &m_refList[0];
    auto avcPicIdx = &m_picIdx[0];

    uint8_t prevRefIdx = m_currReconstructedPic.FrameIdx;
    CODECHAL_ENCODE_CHK_NULL_RETURN(picParams);
    uint8_t currRefIdx = picParams->CurrReconstructedPic.FrameIdx;

    int16_t prevFrameNum = m_frameNum;
    int16_t currFrameNum = picParams->frame_num;

    if (m_firstFrame)
    {
        m_oriFieldCodingFlag = picParams->FieldCodingFlag;
    }

    if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
        (!picParams->UserFlags.bUseRawPicForRef || !(m_codecFunction == CODECHAL_FUNCTION_ENC || m_codecFunction == CODECHAL_FUNCTION_FEI_ENC)))
    {
        return MOS_STATUS_INVALID_PARAMETER;
    }

    // Sync initialize
    if ((m_firstFrame) ||
        (!bBrcEnabled && picParams->UserFlags.bUseRawPicForRef) ||  // No need to wait for previous PAK if reconstructed pic is not used as reference (but RAW pic is used for ref)
        (!bBrcEnabled && (picParams->CodingType == I_TYPE)) ||      // No need to wait for I-Frames
        (!bBrcEnabled && (currFrameNum == prevFrameNum) &&
            CodecHal_PictureIsFrame(picParams->CurrOriginalPic)) ||          // No need to wait if current and previous pics have same frame numbers (Same reference list is used for two pictures with same frame numbers)
            (!bBrcEnabled && !avcRefList[prevRefIdx]->bUsedAsRef &&
                CodecHal_PictureIsField(picParams->CurrOriginalPic)))
    {
        m_waitForPak = false;
    }
    else
    {
        m_waitForPak = true;
    }

    if ((bBrcEnabled || picParams->RefPicFlag))
    {
        m_signalEnc = true;
    }
    else
    {
        m_signalEnc = false;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetPictureStructs());

    // use MbEnc Adv kenrel if rolling I or DirtyROI is enabled
    if (picParams->EnableRollingIntraRefresh || (picParams->NumDirtyROI > 0))
    {
        bAdvancedDshInUse = bBrcEnabled;
        bUseMbEncAdvKernel = true;
    }

    bMbEncIFrameDistEnabled =
        bBrcDistortionBufferSupported &&
        bBrcEnabled &&
        (m_pictureCodingType == I_TYPE);

    m_mfxInterface->SetBrcNumPakPasses(GetNumBrcPakPasses(picParams->BRCPrecision));
    if (bBrcEnabled)
    {
        // For ICQ mode, ignore BRCPrecision sent by the app and set the number of passes internally
        if (seqParams->RateControlMethod == RATECONTROL_ICQ)
        {
            m_numPasses = CODECHAL_ENCODE_AVC_ICQ_NUM_OF_PASSES - 1;  // 1 original plus extra to handle IPCM MBs
        }
        // If min/max QP control is on, set single PAK pass.
        else if (bMinMaxQPControlEnabled)
        {
            m_numPasses = CODECHAL_ENCODE_BRC_SINGLE_PASS - 1;  // single PAK pass, no IPCM (-1 because of the loop condition)
        }
        else
        {
            m_numPasses = (uint8_t)(m_mfxInterface->GetBrcNumPakPasses() - 1);  // 1 original plus extra to handle BRC
        }
        // Call BrcInitReset kernel for field/frame mode change
        if ((m_oriFieldCodingFlag != picParams->FieldCodingFlag) && (!m_firstFrame))
        {
            bBrcReset = true;
            m_oriFieldCodingFlag = picParams->FieldCodingFlag;
        }

        // check if BRC ROI feature enabled
        bBrcRoiEnabled = (seqParams->RateControlMethod != RATECONTROL_CQP) && picParams->NumROI;

        // allocated resource for MB-level BRC
        if ((bMbBrcEnabled = (bMbBrcEnabled || bBrcRoiEnabled)))
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesMbBrc());
        }
    }
    else
    {
        // legacy AVC : 1 original plus extra to handle IPCM MBs
        m_numPasses = (CODECHAL_ENCODE_AVC_CQP_NUM_OF_PASSES - 1);

        if (picParams->bEnableQpAdjustment)
        {
            bMbBrcEnabled = true;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesMbBrc());
        }
    }

    //add for multiple Pass Pak
    if (CodecHalIsFeiEncode(m_codecFunction))
    {
        CodecEncodeAvcFeiPicParams *feiPicParams;

        feiPicParams = (CodecEncodeAvcFeiPicParams *)m_encodeParams.pFeiPicParams;
        CODECHAL_ENCODE_CHK_NULL_RETURN(feiPicParams);
        if (feiPicParams->dwMaxFrameSize != 0)
        {
            m_numPasses = (uint8_t)feiPicParams->dwNumPasses; //-1+1 for additional one IPCM pass
        }
    }
    else if (CodecHalUsesPakEngine(m_codecFunction) && picParams->dwMaxFrameSize != 0)
    {
        m_numPasses = (uint8_t)picParams->dwNumPasses; //-1+1 for additional one IPCM pass
    }

    if (seqParams->RateControlMethod == RATECONTROL_VCM && m_pictureCodingType == B_TYPE)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("VCM BRC mode does not support B-frames\n");
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        return eStatus;
    }

    if (seqParams->RateControlMethod == RATECONTROL_VCM && (picParams->FieldCodingFlag || picParams->FieldFrameCodingFlag))
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("VCM BRC mode does not support interlaced\n");
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        return eStatus;
    }

    if (bRefPicSelectListSupported && m_encEnabled && m_refList[currRefIdx]->bUsedAsRef)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(InsertInRefPicSelectList());
        avcRefList[currRefIdx]->pRefPicSelectListEntry = &RefPicSelectList[ucCurrRefPicSelectIndex];
    }
    else
    {
        avcRefList[currRefIdx]->pRefPicSelectListEntry = nullptr;
    }

    // Force RepartitionCheck
    CODECHAL_ENCODE_AVC_RPC forceRepartitionCheck = (CODECHAL_ENCODE_AVC_RPC)picParams->ForceRepartitionCheck;

    switch (forceRepartitionCheck)
    {
    case CODECHAL_ENCODE_RPC_FOLLOW_DRIVER:
        CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCAFEnabled(&bCAFEnable));
        break;

    case CODECHAL_ENCODE_RPC_FORCE_ENABLE:
        bCAFEnable = 1;
        break;

    case CODECHAL_ENCODE_RPC_FORCE_DISABLE:
        bCAFEnable = 0;
        break;

    default:
        CODECHAL_ENCODE_ASSERTMESSAGE("Invalid ForceRepartitionCheck Flag");
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        break;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(GetATDEnabled());

    // Flatness check is enabled only if scaling will be performed and CAF is enabled. Always enable Flatness for I_type to improve quality.
    m_flatnessCheckEnabled = m_flatnessCheckSupported ?
        ((bCAFEnable || ((m_pictureCodingType == I_TYPE))) && (m_hmeSupported || bBrcEnabled)) : 0;

    //ATD enabled or BRC enabled for dual pipe AVC on KBL
    if (m_adaptiveTransformDecisionEnabled || (bBrcEnabled && m_forceBrcMbStatsEnabled))
    {
        m_mbStatsEnabled = true;
    }
    else
    {
        m_mbStatsEnabled = false;
    }

    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    auto slcParams = m_avcSliceParams;
    auto seqParams = m_avcSeqParam;
    auto picParams = m_avcPicParam;
    if (m_pictureCodingType != I_TYPE)
    {
        CODECHAL_ENCODE_AVC_VALIDATE_NUM_REFS_PARAMS validateNumRefsParams;
        validateNumRefsParams.pSeqParams = seqParams;
        validateNumRefsParams.pPicParams = picParams;
        validateNumRefsParams.pAvcSliceParams = slcParams;
        validateNumRefsParams.wPictureCodingType = m_pictureCodingType;
        validateNumRefsParams.wPicHeightInMB = m_picHeightInMb;
        validateNumRefsParams.wFrameFieldHeightInMB = m_frameFieldHeightInMb;
        validateNumRefsParams.bFirstFieldIPic = m_firstFieldIdrPic;
        validateNumRefsParams.bVDEncEnabled = false;
        validateNumRefsParams.bPAKonly = (m_codecFunction == CODECHAL_FUNCTION_FEI_PAK) ? true : false;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(ValidateNumReferences(&validateNumRefsParams));
    }
    else
    {
        slcParams->num_ref_idx_l0_active_minus1 = 0;
        slcParams->num_ref_idx_l1_active_minus1 = 0;
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetSliceStructs());

    if (eStatus == MOS_STATUS_INVALID_PARAMETER)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Invalid slice parameters.");
    }
    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::SendBrcInitResetSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_BRC_INIT_RESET_SURFACE_PARAMS params)
{
    MOS_STATUS                                  eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->presBrcHistoryBuffer);

    uint32_t kernelIdx =
        (bBrcInit) ? CODECHAL_ENCODE_BRC_IDX_INIT : CODECHAL_ENCODE_BRC_IDX_RESET;
    auto kernelState = &BrcKernelStates[kernelIdx];

    // BRC history buffer
    CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
    uint32_t size = MOS_BYTES_TO_DWORDS(m_brcHistoryBufferSize);
    MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
    surfaceCodecParams.bIsWritable = true;
    surfaceCodecParams.presBuffer = params->presBrcHistoryBuffer;
    surfaceCodecParams.dwSize = size;
    surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE].Value;
    surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_HISTORY;
    surfaceCodecParams.bIsWritable = true;
    surfaceCodecParams.bRenderTarget = true;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        m_hwInterface,
        cmdBuffer,
        &surfaceCodecParams,
        kernelState));

    // AVC_ME BRC Distortion data buffer - output
    params->psMeBrcDistortionBuffer->dwWidth = MOS_ALIGN_CEIL((params->dwDownscaledWidthInMb4x * 8), 64);
    params->psMeBrcDistortionBuffer->dwHeight =
        MOS_ALIGN_CEIL((params->dwDownscaledFrameFieldHeightInMb4x * 4), 8);

    MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
    surfaceCodecParams.bIs2DSurface = true;
    surfaceCodecParams.bMediaBlockRW = true;
    surfaceCodecParams.bIsWritable = true;
    surfaceCodecParams.psSurface = params->psMeBrcDistortionBuffer;
    surfaceCodecParams.dwOffset = params->dwMeBrcDistortionBottomFieldOffset;
    surfaceCodecParams.dwSize = size;
    surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value;
    surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_DISTORTION;
    surfaceCodecParams.bIsWritable = true;
    surfaceCodecParams.bRenderTarget = true;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        m_hwInterface,
        cmdBuffer,
        &surfaceCodecParams,
        kernelState));

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::SendAvcSFDSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_SFD_SURFACE_PARAMS params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params);

    auto kernelState = params->pKernelState;
    CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
    // HME MV Data surface
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeMvDataSurface);
    MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
    surfaceCodecParams.bIs2DSurface = true;
    surfaceCodecParams.bMediaBlockRW = true;
    surfaceCodecParams.psSurface = params->psMeMvDataSurface;
    surfaceCodecParams.dwOffset = params->dwMeMvBottomFieldOffset;
    surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
    surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        m_hwInterface,
        cmdBuffer,
        &surfaceCodecParams,
        kernelState));

    // HME distortion surface
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeDistortionSurface);
    MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
    surfaceCodecParams.bIs2DSurface = true;
    surfaceCodecParams.bMediaBlockRW = true;
    surfaceCodecParams.psSurface = params->psMeDistortionSurface;
    surfaceCodecParams.dwOffset = params->dwMeDistortionBottomFieldOffset;
    surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
    surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        m_hwInterface,
        cmdBuffer,
        &surfaceCodecParams,
        kernelState));

    // output buffer
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->presOutputBuffer);
    MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
    surfaceCodecParams.presBuffer = params->presOutputBuffer;
    surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE_COMMON);
    surfaceCodecParams.dwOffset = 0;
    surfaceCodecParams.bRenderTarget = true;
    surfaceCodecParams.bIsWritable = true;
    surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
    surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        m_hwInterface,
        cmdBuffer,
        &surfaceCodecParams,
        kernelState));

    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    auto ppsidx = ((PCODEC_AVC_ENCODE_SLICE_PARAMS)(params.pSliceParams))->pic_parameter_set_id;
    auto spsidx = ((PCODEC_AVC_ENCODE_PIC_PARAMS)(params.pPicParams))->seq_parameter_set_id;

    m_madEnabled = params.bMADEnabled;

    m_avcSeqParams[spsidx] = (PCODEC_AVC_ENCODE_SEQUENCE_PARAMS)(params.pSeqParams);
    if (ppsidx >= CODEC_AVC_MAX_PPS_NUM)
    {
        return MOS_STATUS_INVALID_PARAMETER;
    }
    m_avcPicParams[ppsidx] = (PCODEC_AVC_ENCODE_PIC_PARAMS)(params.pPicParams);
    m_avcQCParams  = (PCODECHAL_ENCODE_AVC_QUALITY_CTRL_PARAMS)params.pAVCQCParams;
    m_avcRoundingParams      = (PCODECHAL_ENCODE_AVC_ROUNDING_PARAMS)params.pAVCRoundingParams;

    m_avcSeqParam = m_avcSeqParams[spsidx];
    m_avcPicParam = m_avcPicParams[ppsidx];
    m_avcVuiParams = (PCODECHAL_ENCODE_AVC_VUI_PARAMS)params.pVuiParams;
    m_avcSliceParams = (PCODEC_AVC_ENCODE_SLICE_PARAMS)params.pSliceParams;
    m_avcFeiPicParams = (CodecEncodeAvcFeiPicParams *)params.pFeiPicParams;
    m_avcIQMatrixParams = (PCODEC_AVC_IQ_MATRIX_PARAMS)params.pIQMatrixBuffer;
    m_avcIQWeightScaleLists = (PCODEC_AVC_ENCODE_IQ_WEIGTHSCALE_LISTS)params.pIQWeightScaleLists;
    m_nalUnitParams = params.ppNALUnitParams;
    m_sliceStructCaps = params.uiSlcStructCaps;

    m_skipFrameFlag = m_avcPicParam->SkipFrameFlag;

    // Picture and slice header packing flag from DDI caps
    bAcceleratorHeaderPackingCaps = params.bAcceleratorHeaderPackingCaps;

    CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcIQMatrixParams);

    // so far this only applies to AVC
    // can move to MotionEstimationDisableCheck() if the logic applies to other codecs later
    if ((!m_feiEnable) && (m_avcQCParams ))
    {
        // disable 4x/16x/32 HME if DDI wants to do so, enabling logic is not affected
        if (m_avcQCParams ->HMEDisable)
        {
            m_hmeSupported = false;
            m_16xMeSupported = false;
            m_32xMeSupported = false;
        }
        else if (m_avcQCParams ->SuperHMEDisable)
        {
            m_16xMeSupported = false;
            m_32xMeSupported = false;
        }
        else if (m_avcQCParams ->UltraHMEDisable)
        {
            m_32xMeSupported = false;
        }
    }

    // Mb Qp data
    bMbQpDataEnabled = params.bMbQpDataEnabled;
    if (bMbQpDataEnabled)
    {
        sMbQpDataSurface = *(params.psMbQpDataSurface);
    }

    // Mb Disable Skip Map
    bMbDisableSkipMapEnabled = params.bMbDisableSkipMapEnabled;
    if (bMbDisableSkipMapEnabled)
    {
        psMbDisableSkipMapSurface = params.psMbDisableSkipMapSurface;
    }

    // Sei for AVC
    if (params.pSeiData != nullptr)
    {
        if (params.pSeiData->dwSEIBufSize > 0) // sei is present
        {
            if (params.pSeiData->dwSEIBufSize > SeiData.dwSEIBufSize)
            {
                // Destroy and re-allocate
                if (SeiData.pSEIBuffer)
                {
                    MOS_FreeMemory(SeiData.pSEIBuffer);
                    SeiData.pSEIBuffer = nullptr;
                }
                SeiData.dwSEIBufSize = params.pSeiData->dwSEIBufSize;
                SeiData.pSEIBuffer = (uint8_t *)MOS_AllocAndZeroMemory(SeiData.dwSEIBufSize);
                CODECHAL_ENCODE_CHK_NULL_RETURN(SeiData.pSEIBuffer);
            }

            pSeiParamBuffer = params.pSeiParamBuffer;
            dwSEIDataOffset = params.dwSEIDataOffset;
            SeiData.newSEIData = params.pSeiData->newSEIData;
            SeiData.dwSEIDataSize = params.pSeiData->dwSEIDataSize;

            eStatus = MOS_SecureMemcpy(SeiData.pSEIBuffer,
                SeiData.dwSEIDataSize,
                (pSeiParamBuffer + dwSEIDataOffset),
                SeiData.dwSEIDataSize);
            if (eStatus != MOS_STATUS_SUCCESS)
            {
                CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
                return eStatus;
            }
        }

        m_extraPictureStatesSize = SeiData.dwSEIDataSize;
    }

    m_deblockingEnabled = 0;
    for (uint32_t i = 0; i < m_numSlices; i++)
    {
        if (m_avcSliceParams[i].disable_deblocking_filter_idc != 1)
        {
            m_deblockingEnabled = 1;
            break;
        }
    }

    if (m_newSeq)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceStructs());

    // MB control data
    bMbSpecificDataEnabled = false; // Reset this flag at start of each frame encode.
    if (params.pMbCtrlBuffer)
    {
        bMbSpecificDataEnabled = true;

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

        PCODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS mbSpecificData = nullptr;
        CODECHAL_ENCODE_CHK_NULL_RETURN(mbSpecificData = \
            (PCODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS)m_osInterface->pfnLockResource(
                m_osInterface,
                &resMbSpecificDataBuffer[m_currRecycledBufIdx],
                &lockFlagsWriteOnly));

        uint32_t frameFieldMbNum = m_picWidthInMb * m_frameFieldHeightInMb;
        for (unsigned idx = 0; idx < frameFieldMbNum; ++idx)
        {
            mbSpecificData[idx].DW0.ForceToIntra = params.pMbCtrlBuffer[idx].MBParams.bForceIntra;
        }

        m_osInterface->pfnUnlockResource(m_osInterface, &resMbSpecificDataBuffer[m_currRecycledBufIdx]);
    }

    // Scaling occurs when either HME or BRC is enabled, and for Interlaced only called on first field
    m_scalingEnabled = (m_hmeSupported || bBrcEnabled) && m_firstField;
    m_useRawForRef = m_userFlags.bUseRawPicForRef;

    //Allocate and Generate the slice map surface
    if (m_arbitraryNumMbsInSlice)
    {
        /********** Allocate slice map surface **********/

        if (Mos_ResourceIsNull(&m_sliceMapSurface[m_currRecycledBufIdx].OsResource))     // Allocate only if not allocated before
        {
            for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
            {
                MOS_ZeroMemory(&m_sliceMapSurface[i], sizeof(MOS_SURFACE));
                m_sliceMapSurface[i].TileType = MOS_TILE_LINEAR;
                m_sliceMapSurface[i].bArraySpacing = true;
                m_sliceMapSurface[i].Format = Format_Buffer_2D;
                m_sliceMapSurface[i].dwWidth = (m_picWidthInMb + 1) * sizeof(uint32_t);
                m_sliceMapSurface[i].dwHeight = 2 * m_frameFieldHeightInMb;
                m_sliceMapSurface[i].dwPitch = MOS_ALIGN_CEIL(m_sliceMapSurface[i].dwWidth, 64);

                MOS_ALLOC_GFXRES_PARAMS                     allocParamsForBuffer2D;
                MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
                allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
                allocParamsForBuffer2D.TileType = (MOS_TILE_TYPE)m_sliceMapSurface[i].TileType;
                allocParamsForBuffer2D.Format = m_sliceMapSurface[i].Format;
                allocParamsForBuffer2D.dwWidth = m_sliceMapSurface[i].dwPitch;
                allocParamsForBuffer2D.dwHeight = m_sliceMapSurface[i].dwHeight;
                allocParamsForBuffer2D.pBufName = "Slice Map Surface";

                eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
                    m_osInterface,
                    &allocParamsForBuffer2D,
                    &m_sliceMapSurface[i].OsResource);
                if (eStatus != MOS_STATUS_SUCCESS)
                {
                    CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate slice map Surface.");
                    return eStatus;
                }
            }
        }
        else    // If sSliceMapSurface was already allocated, reassign width and height, in case there was a dynamic resolution change. Pitch doesn't need to be udpated.
        {
            m_sliceMapSurface[m_currRecycledBufIdx].dwWidth = (m_picWidthInMb + 1) * sizeof(uint32_t);
            m_sliceMapSurface[m_currRecycledBufIdx].dwHeight = 2 * m_frameFieldHeightInMb;
        }

        /********** Generate slice map surface **********/
        uint8_t*           data = nullptr;
        MOS_LOCK_PARAMS lockFlagsWriteOnly;
        MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(lockFlagsWriteOnly));
        lockFlagsWriteOnly.WriteOnly = true;

        // lock the internal lockable buffer.
        CODECHAL_ENCODE_CHK_NULL_RETURN(data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface,
            &m_sliceMapSurface[m_currRecycledBufIdx].OsResource, &lockFlagsWriteOnly));
        CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeGenerateSliceMap(data, m_avcSliceParams));

        // Unlock the internal lockable buffer
        m_osInterface->pfnUnlockResource(m_osInterface, &m_sliceMapSurface[m_currRecycledBufIdx].OsResource);
    }

    CODECHAL_DEBUG_TOOL(
        m_debugInterface->m_currPic            = m_avcPicParam->CurrOriginalPic;
        m_debugInterface->m_bufferDumpFrameNum = m_storeData;
        m_debugInterface->m_frameType          = m_pictureCodingType;

        if (m_newSeq) {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams(
                m_avcSeqParam,
                m_avcIQMatrixParams));

            CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateConstParam());
        }

        if (m_newVuiData) {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpVuiParams(
                m_avcVuiParams));
        }

        CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams(
            m_avcPicParam,
            m_avcIQMatrixParams));

        if (m_feiEnable) {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpFeiPicParams(
                m_avcFeiPicParams));
        }

        for (uint32_t i = 0; i < m_numSlices; i++) {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSliceParams(
                &m_avcSliceParams[i],
                m_avcPicParam));

            CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateDdiParam(
                 m_avcSeqParam,
                 m_avcPicParam,
                 &m_avcSliceParams[i]));
        })

    ulRefPicSelectBottomFieldOffset = 0;
    BrcBuffers.dwMeBrcDistortionBottomFieldOffset = 0;
    BrcBuffers.dwBrcMbQpBottomFieldOffset = 0;

    if (CodecHal_PictureIsField(m_currOriginalPic))
    {
        if (CodecHal_PictureIsBottomField(m_currOriginalPic))
        {
            if (bVMEKernelDump)
            {
                ulVMEKernelDumpBottomFieldOffset =
                    m_frameFieldHeightInMb * m_picWidthInMb * 64;
            }

            ulRefPicSelectBottomFieldOffset =
                MOS_ALIGN_CEIL((m_picWidthInMb * 8), 64) *
                m_frameFieldHeightInMb;
            BrcBuffers.dwMeBrcDistortionBottomFieldOffset =
                BrcBuffers.sMeBrcDistortionBuffer.dwPitch *
                MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4), 8);
            BrcBuffers.dwBrcMbQpBottomFieldOffset =
                MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 4), 64) *
                MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4), 8);
        }
    }

    // Set min/max QP values in AVC State based on frame type if atleast one of them is non-zero
    if (m_avcPicParam->ucMinimumQP || m_avcPicParam->ucMaximumQP)
    {
        bMinMaxQPControlEnabled = true;
        if (m_avcPicParam->CodingType == I_TYPE)
        {
            ucIMaxQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51);   // Clamp to the max QP to [1, 51] . Zero is not used by our Kernel.
            ucIMinQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), ucIMaxQP);    // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
            if (!bPFrameMinMaxQPControl)
            {
                ucPMinQP = ucIMinQP;
                ucPMaxQP = ucIMaxQP;
            }
            if (!bBFrameMinMaxQPControl)
            {
                ucBMinQP = ucIMinQP;
                ucBMaxQP = ucIMaxQP;
            }
        }
        else if (m_avcPicParam->CodingType == P_TYPE)
        {
            bPFrameMinMaxQPControl = true;
            ucPMaxQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51);   // Clamp to the max QP to [1, 51]. Zero is not used by our Kernel.
            ucPMinQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), ucPMaxQP);    // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
            if (!bBFrameMinMaxQPControl)
            {
                ucBMinQP = ucPMinQP;
                ucBMaxQP = ucPMaxQP;
            }
        }
        else    // B_TYPE
        {
            bBFrameMinMaxQPControl = true;
            ucBMaxQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51);   // Clamp to the max QP to [1, 51] . Zero is not used by our Kernel.
            ucBMinQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), ucBMaxQP);    // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
        }
        // Zero out the QP values, so we don't update the AVCState settings until new values are sent in MiscParamsRC
        m_avcPicParam->ucMinimumQP = 0;
        m_avcPicParam->ucMaximumQP = 0;
    }

    if (!(m_codecFunction == CODECHAL_FUNCTION_ENC || m_codecFunction == CODECHAL_FUNCTION_FEI_ENC)
        && !m_userFlags.bDisableAcceleratorHeaderPacking
        && bAcceleratorHeaderPackingCaps)
    {
        CODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS  packPicHeaderParams;
        packPicHeaderParams.pBsBuffer = &m_bsBuffer;
        packPicHeaderParams.pPicParams = m_avcPicParam;
        packPicHeaderParams.pSeqParams = m_avcSeqParam;
        packPicHeaderParams.pAvcVuiParams = m_avcVuiParams;
        packPicHeaderParams.pAvcIQMatrixParams = m_avcIQMatrixParams;
        packPicHeaderParams.ppNALUnitParams = m_nalUnitParams;
        packPicHeaderParams.pSeiData = &SeiData;
        packPicHeaderParams.dwFrameHeight = m_frameHeight;
        packPicHeaderParams.dwOriFrameHeight = m_oriFrameHeight;
        packPicHeaderParams.wPictureCodingType = m_avcPicParam->CodingType;
        packPicHeaderParams.bNewSeq = m_newSeq;
        packPicHeaderParams.pbNewPPSHeader = &m_newPpsHeader;
        packPicHeaderParams.pbNewSeqHeader = &m_newSeqHeader;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_PackPictureHeader(&packPicHeaderParams));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SetStatusReportParams(m_refList[m_currReconstructedPic.FrameIdx]));

    m_bitstreamUpperBound = m_encodeParams.dwBitstreamSize;
    uint8_t sliceQP = m_avcPicParam->pic_init_qp_minus26 + 26 + m_avcSliceParams->slice_qp_delta;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(GetSkipBiasAdjustment(sliceQP, m_avcSeqParam->GopRefDist,
        &m_skipBiasAdjustmentEnable));

    // Determine if Trellis Quantization should be enabled
    MOS_ZeroMemory(&m_trellisQuantParams, sizeof(m_trellisQuantParams));
    // Trellis must remain switched off if it is explicitly disabled or picture is encoded with CAVLC
    if (!(dwTrellis & trellisDisabled) && m_avcPicParam->entropy_coding_mode_flag)
    {
        if (dwTrellis == trellisInternal)
        {
            CODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS         tqInputParams;
            tqInputParams.ucQP = sliceQP;
            tqInputParams.ucTargetUsage = m_avcSeqParam->TargetUsage;
            tqInputParams.wPictureCodingType = m_pictureCodingType;
            tqInputParams.bBrcEnabled = bBrcEnabled;
            tqInputParams.bVdEncEnabled = false;

            CODECHAL_ENCODE_CHK_STATUS_RETURN(GetTrellisQuantization(
                &tqInputParams,
                &m_trellisQuantParams));
        }
        else if ((m_pictureCodingType == I_TYPE && (dwTrellis & trellisEnabledI)) ||
            (m_pictureCodingType == P_TYPE && (dwTrellis & trellisEnabledP)) ||
            (m_pictureCodingType == B_TYPE && (dwTrellis & trellisEnabledB)))
        {
            m_trellisQuantParams.dwTqEnabled = true;
            m_trellisQuantParams.dwTqRounding = CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_ROUNDING;
        }
    }

    InitMfe();

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::ExecuteKernelFunctions()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;
    auto slcParams = m_avcSliceParams;
    auto sliceType = Slice_Type[slcParams->slice_type];

    CODECHAL_DEBUG_TOOL(
        //CodecHal_DbgMapSurfaceFormatToDumpFormat(m_rawSurfaceToEnc->Format, &u32DumpType);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
            m_rawSurfaceToEnc,
            CodechalDbgAttr::attrEncodeRawInputSurface,
            "SrcSurf"));
    )
    CODECHAL_ENCODE_CHK_NULL_RETURN(m_cscDsState);
    // Scaling, BRC Init/Reset and HME are included in the same task phase
    m_lastEncPhase = false;
    m_firstTaskInPhase = true;

    // BRC init/reset needs to be called before HME since it will reset the Brc Distortion surface
    if (bBrcEnabled && (bBrcInit || bBrcReset))
    {
        bool cscEnabled = m_cscDsState->RequireCsc() && m_firstField;
        m_lastTaskInPhase = !(cscEnabled || m_scalingEnabled || m_16xMeSupported || m_hmeEnabled);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcInitResetKernel());
    }

    UpdateSSDSliceCount();

    if (m_firstField)
    {
        // Csc, Downscaling, and/or 10-bit to 8-bit conversion
        CodechalEncodeCscDs::KernelParams cscScalingKernelParams;
        MOS_ZeroMemory(&cscScalingKernelParams, sizeof(cscScalingKernelParams));
        cscScalingKernelParams.bLastTaskInPhaseCSC =
            cscScalingKernelParams.bLastTaskInPhase4xDS = !(m_16xMeSupported || m_hmeEnabled);
        cscScalingKernelParams.bLastTaskInPhase16xDS = !(m_32xMeSupported || m_hmeEnabled);
        cscScalingKernelParams.bLastTaskInPhase32xDS = !m_hmeEnabled;
        cscScalingKernelParams.inputColorSpace = m_avcSeqParam->InputColorSpace;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->KernelFunctions(&cscScalingKernelParams));
    }

    // SFD should be called only when HME enabled
    auto staticFrameDetectionInUse = bStaticFrameDetectionEnable && m_hmeEnabled;

    staticFrameDetectionInUse = !bPerMbSFD && staticFrameDetectionInUse;

    if (m_hmeEnabled)
    {
        if (m_16xMeEnabled)
        {
            m_lastTaskInPhase = false;
            if (m_32xMeEnabled)
            {
                CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodeMeKernel(&BrcBuffers, HME_LEVEL_32x));
            }
            CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodeMeKernel(&BrcBuffers, HME_LEVEL_16x));
        }
        m_lastTaskInPhase = !staticFrameDetectionInUse;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodeMeKernel(&BrcBuffers, HME_LEVEL_4x));
    }

    // call SFD kernel after HME in same command buffer
    if (staticFrameDetectionInUse)
    {
        m_lastTaskInPhase = true;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SFDKernel());
    }

    // Scaling and HME are not dependent on the output from PAK
    if (m_waitForPak && m_semaphoreObjCount && !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
    {
        // Wait on PAK
        auto syncParams = g_cInitSyncParams;
        syncParams.GpuContext = m_renderContext;
        syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
        syncParams.uiSemaphoreCount = m_semaphoreObjCount;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
        m_semaphoreObjCount = 0; //reset
    }

    // Dump BrcDist 4X_ME buffer here because it will be overwritten in BrcFrameUpdateKernel
    CODECHAL_DEBUG_TOOL(
        if (m_hmeEnabled && bBrcDistortionBufferSupported)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.sMeBrcDistortionBuffer.OsResource,
                CodechalDbgAttr::attrOutput,
                "BrcDist",
                BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight,
                BrcBuffers.dwMeBrcDistortionBottomFieldOffset,
                CODECHAL_MEDIA_STATE_4X_ME));
        })

    // BRC and MbEnc are included in the same task phase
    m_lastEncPhase = true;
    m_firstTaskInPhase = true;

    if (bBrcEnabled)
    {
        if (bMbEncIFrameDistEnabled)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(MbEncKernel(true));
        }

        // Separate the MBEnc kernel and BrcUpdate Kernel
        if (IsMfeMbEncEnabled(false))
        {
            m_lastTaskInPhase = true;
        }
        CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcFrameUpdateKernel());
        if (bBrcSplitEnable && bMbBrcEnabled)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcMbUpdateKernel());
        }

        // Reset buffer ID used for BRC kernel performance reports
        m_osInterface->pfnResetPerfBufferID(m_osInterface);
    }

    bUseWeightedSurfaceForL0 = false;
    bUseWeightedSurfaceForL1 = false;

    if (bWeightedPredictionSupported &&
        ((((sliceType == SLICE_P) || (sliceType == SLICE_SP)) && (m_avcPicParam->weighted_pred_flag)) ||
        (((sliceType == SLICE_B)) && (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE)))
        )
    {
        uint8_t i;
        // Weighted Prediction to be applied for L0
        for (i=0; i<(slcParams->num_ref_idx_l0_active_minus1+1); i++)
        {
            if((slcParams->luma_weight_flag[LIST_0] & (1 << i)) && (i < CODEC_AVC_MAX_FORWARD_WP_FRAME))
            {
                //Weighted Prediction for ith forward reference frame
                CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(false, i));
            }
        }

        if (((sliceType == SLICE_B)) &&
            (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE))
        {
            for (i=0; i<(slcParams->num_ref_idx_l1_active_minus1+1); i++)
            {
                // Weighted Pred to be applied for L1
                if((slcParams->luma_weight_flag[LIST_1] & 1 << i) && (i < CODEC_AVC_MAX_BACKWARD_WP_FRAME))
                {
                    //Weighted Prediction for ith backward reference frame
                    CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(true, i));
                }
            }
        }
    }

#if (_DEBUG || _RELEASE_INTERNAL)

    MOS_USER_FEATURE_VALUE_WRITE_DATA   userFeatureWriteData;

    // Weighted prediction for L0 Reporting
    userFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__;
    userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL0;
    userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L0_IN_USE_ID;
    MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);

    // Weighted prediction for L1 Reporting
    userFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__;
    userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL1;
    userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L1_IN_USE_ID;
    MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);

#endif // _DEBUG || _RELEASE_INTERNAL

    m_lastTaskInPhase = true;

    if (IsMfeMbEncEnabled(false))
    {
        // Submit MBEnc kernel in the last stream
        if (m_mfeLastStream)
        {
            m_lastEncPhase = true;
            m_firstTaskInPhase = true;
            m_lastTaskInPhase = true;
        }
        else
        {
            m_firstTaskInPhase = false;
            m_lastTaskInPhase = false;
        }
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(MbEncKernel(false));

    // Reset buffer ID used for MbEnc kernel performance reports
    m_osInterface->pfnResetPerfBufferID(m_osInterface);

    if (!Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
    {
        auto syncParams = g_cInitSyncParams;
        syncParams.GpuContext = m_renderContext;
        syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;

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

    if (m_madEnabled)
    {
        m_currMadBufferIdx = (m_currMadBufferIdx + 1) % CODECHAL_ENCODE_MAX_NUM_MAD_BUFFERS;
    }

    // Reset after BRC Init has been processed
    bBrcInit = false;

    m_setRequestedEUSlices = false;

    CODECHAL_DEBUG_TOOL(DumpEncodeKernelOutput());

    if (bBrcEnabled)
    {
        bMbEncCurbeSetInBrcUpdate = false;
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::DumpEncodeKernelOutput()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    auto staticFrameDetectionInUse = bStaticFrameDetectionEnable && m_hmeEnabled;
    staticFrameDetectionInUse = !bPerMbSFD && staticFrameDetectionInUse;
    CODECHAL_DEBUG_TOOL(
        if (m_hmeEnabled)
        {
            CODECHAL_ME_OUTPUT_PARAMS meOutputParams;
            MOS_ZeroMemory(&meOutputParams, sizeof(meOutputParams));
            meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer;
            meOutputParams.psMeDistortionBuffer =
                m_4xMeDistortionBufferSupported ?
                (m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer) : nullptr;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &meOutputParams.psMeMvBuffer->OsResource,
                CodechalDbgAttr::attrOutput,
                "MvData",
                meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch,
                m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset() : (uint32_t)m_meMvBottomFieldOffset,
                CODECHAL_MEDIA_STATE_4X_ME));

            if (meOutputParams.psMeDistortionBuffer)
            {
                CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                    &meOutputParams.psMeDistortionBuffer->OsResource,
                    CodechalDbgAttr::attrOutput,
                    "MeDist",
                    meOutputParams.psMeDistortionBuffer->dwHeight *meOutputParams.psMeDistortionBuffer->dwPitch,
                    m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset,
                    CODECHAL_MEDIA_STATE_4X_ME));
            }

            if (m_16xMeEnabled)
            {
                meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me16xMvDataBuffer) : &m_16xMeMvDataBuffer;
                CODECHAL_ENCODE_CHK_STATUS_RETURN(
                    m_debugInterface->DumpBuffer(
                        &meOutputParams.psMeMvBuffer->OsResource,
                        CodechalDbgAttr::attrOutput,
                        "MvData",
                        meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch,
                        m_hmeKernel ? m_hmeKernel->Get16xMeMvBottomFieldOffset() : (uint32_t)m_meMv16xBottomFieldOffset,
                        CODECHAL_MEDIA_STATE_16X_ME));

                if (m_32xMeEnabled)
                {
                    meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me32xMvDataBuffer) : &m_32xMeMvDataBuffer;
                    CODECHAL_ENCODE_CHK_STATUS_RETURN(
                        m_debugInterface->DumpBuffer(
                            &meOutputParams.psMeMvBuffer->OsResource,
                            CodechalDbgAttr::attrOutput,
                            "MvData",
                            meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch,
                            m_hmeKernel ? m_hmeKernel->Get32xMeMvBottomFieldOffset() : (uint32_t)m_meMv32xBottomFieldOffset,
                            CODECHAL_MEDIA_STATE_32X_ME));
                }
            }
        }
    if (staticFrameDetectionInUse)
    {
         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
              &resSFDOutputBuffer[0],
              CodechalDbgAttr::attrOutput,
              "Out",
              CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE_COMMON,
              0,
              CODECHAL_MEDIA_STATE_STATIC_FRAME_DETECTION));
    }

    if (bBrcEnabled)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &BrcBuffers.resBrcImageStatesWriteBuffer,
            CodechalDbgAttr::attrOutput,
            "ImgStateWrite",
            BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(),
            0,
            CODECHAL_MEDIA_STATE_BRC_UPDATE));

        if (!Mos_ResourceIsNull(&BrcBuffers.sBrcMbQpBuffer.OsResource))
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.sBrcMbQpBuffer.OsResource,
                CodechalDbgAttr::attrOutput,
                "MbQp",
                BrcBuffers.sBrcMbQpBuffer.dwPitch*BrcBuffers.sBrcMbQpBuffer.dwHeight,
                BrcBuffers.dwBrcMbQpBottomFieldOffset,
                CODECHAL_MEDIA_STATE_MB_BRC_UPDATE));
        }
        if (bMbBrcEnabled)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.resBrcHistoryBuffer,
                CodechalDbgAttr::attrOutput,
                "HistoryWrite",
                m_brcHistoryBufferSize,
                0,
                CODECHAL_MEDIA_STATE_MB_BRC_UPDATE));
        }
        if (BrcBuffers.pMbEncKernelStateInUse)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
                CODECHAL_MEDIA_STATE_BRC_UPDATE,
                BrcBuffers.pMbEncKernelStateInUse));
        }
        if (m_mbencBrcBufferSize > 0)
        {
            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &BrcBuffers.resMbEncBrcBuffer,
                CodechalDbgAttr::attrOutput,
                "MbEncBRCWrite",
                m_mbencBrcBufferSize,
                0,
                CODECHAL_MEDIA_STATE_BRC_UPDATE));
        }
    }

    if (m_mbStatsSupported)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &m_resMbStatsBuffer,
            CodechalDbgAttr::attrOutput,
            "MBStatsSurf",
            m_picWidthInMb * m_frameFieldHeightInMb * 16 * sizeof(uint32_t),
            CodecHal_PictureIsBottomField(m_currOriginalPic) ? m_mbStatsBottomFieldOffset : 0,
            CODECHAL_MEDIA_STATE_4X_SCALING));
    }

     else if (m_flatnessCheckEnabled)
     {
         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
             &m_flatnessCheckSurface.OsResource,
             CodechalDbgAttr::attrOutput,
             "FlatnessChkSurf",
             ((CodecHal_PictureIsField(m_currOriginalPic)) ? m_flatnessCheckSurface.dwHeight/2 : m_flatnessCheckSurface.dwHeight) * m_flatnessCheckSurface.dwPitch,
             CodecHal_PictureIsBottomField(m_currOriginalPic)?(m_flatnessCheckSurface.dwPitch * m_flatnessCheckSurface.dwHeight >> 1):0,
             CODECHAL_MEDIA_STATE_4X_SCALING));
     }

    if (bMbQpDataEnabled)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &resMbSpecificDataBuffer[m_currRecycledBufIdx],
            CodechalDbgAttr::attrInput,
            "MbSpecificData",
            m_picWidthInMb*m_frameFieldHeightInMb*16,
            0,
            CODECHAL_MEDIA_STATE_ENC_QUALITY));
    }

    uint8_t           index;
    CODEC_PICTURE   refPic;
    if (bUseWeightedSurfaceForL0)
    {
        refPic = m_avcSliceParams->RefPicList[LIST_0][0];
        index = m_picIdx[refPic.FrameIdx].ucPicIdx;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
            &m_refList[index]->sRefBuffer,
            CodechalDbgAttr::attrReferenceSurfaces,
            "WP_In_L0"));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
            &WeightedPredOutputPicSelectList[CODEC_WP_OUTPUT_L0_START + 0].sBuffer,
            CodechalDbgAttr::attrReferenceSurfaces,
            "WP_Out_L0"));
    }
    if (bUseWeightedSurfaceForL1)
    {

        refPic = m_avcSliceParams->RefPicList[LIST_1][0];
        index = m_picIdx[refPic.FrameIdx].ucPicIdx;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
            &m_refList[index]->sRefBuffer,
            CodechalDbgAttr::attrReferenceSurfaces,
            "WP_In_L1"));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
            &WeightedPredOutputPicSelectList[CODEC_WP_OUTPUT_L1_START + 0].sBuffer,
            CodechalDbgAttr::attrReferenceSurfaces,
            "WP_In_L1"));
    }

    if (m_feiEnable)
     {
         if(m_avcFeiPicParams->bMBQp){
             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                 &m_avcFeiPicParams->resMBQp,
                 CodechalDbgAttr::attrInput,
                 "MbQp",
                 m_picWidthInMb * m_frameFieldHeightInMb + 3,
                 0,
                 CODECHAL_MEDIA_STATE_ENC_QUALITY));

         }
         if (m_avcFeiPicParams->MVPredictorEnable){
             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                 &m_avcFeiPicParams->resMVPredictor,
                 CodechalDbgAttr::attrInput,
                 "MvPredictor",
                 m_picWidthInMb * m_frameFieldHeightInMb *40,
                 0,
                 CODECHAL_MEDIA_STATE_ENC_QUALITY));
         }
     }

    if (m_arbitraryNumMbsInSlice)
     {
         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &m_sliceMapSurface[m_currRecycledBufIdx].OsResource,
            CodechalDbgAttr::attrInput,
            "SliceMapSurf",
            m_sliceMapSurface[m_currRecycledBufIdx].dwPitch * m_frameFieldHeightInMb,
            0,
            CODECHAL_MEDIA_STATE_ENC_QUALITY));
     }

    auto refList = &m_refList[0];
    auto currRefList = m_refList[m_currReconstructedPic.FrameIdx];
    // Dump MBEnc output buffer "MbCodebuffer"
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
        &currRefList->resRefMbCodeBuffer,
        CodechalDbgAttr::attrOutput,
        "EncMbCode",
        m_picWidthInMb * m_frameFieldHeightInMb * 64,
        CodecHal_PictureIsBottomField(currRefList->RefPic) ? m_frameFieldHeightInMb * m_picWidthInMb * 64 : 0,
        CODECHAL_MEDIA_STATE_ENC_NORMAL));

    // Dump MBEnc output buffer "MVdatabuffer"
    if (m_mvDataSize)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
            &currRefList->resRefMvDataBuffer,
            CodechalDbgAttr::attrOutput,
            "MbData",
            m_picWidthInMb * m_frameFieldHeightInMb * (32 * 4),
            CodecHal_PictureIsBottomField(currRefList->RefPic) ? MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), 0x1000) : 0,
            CODECHAL_MEDIA_STATE_ENC_NORMAL));
    }
     )
    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcPicParam);
    CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcSliceParams);

    MHW_BATCH_BUFFER batchBuffer;
    MOS_ZeroMemory(&batchBuffer, sizeof(batchBuffer));
    batchBuffer.OsResource = BrcBuffers.resBrcImageStatesWriteBuffer;
    batchBuffer.dwOffset = m_currPass * BRC_IMG_STATE_SIZE_PER_PASS;
    batchBuffer.bSecondLevel = true;

    CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS    encodePictureLevelParams;
    MOS_ZeroMemory(&encodePictureLevelParams, sizeof(encodePictureLevelParams));
    encodePictureLevelParams.psPreDeblockSurface = &m_reconSurface;
    encodePictureLevelParams.psPostDeblockSurface = &m_reconSurface;
    encodePictureLevelParams.bBrcEnabled = bBrcEnabled;
    encodePictureLevelParams.pImgStateBatchBuffer = &batchBuffer;
    encodePictureLevelParams.presBrcHistoryBuffer = &BrcBuffers.resBrcHistoryBuffer;

    bool deblockingEnabled = m_deblockingEnabled;
    bool suppressReconPic =
        ((!m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) && m_suppressReconPicSupported);
    encodePictureLevelParams.bDeblockerStreamOutEnable = 0;
    encodePictureLevelParams.bPreDeblockOutEnable = !deblockingEnabled && !suppressReconPic;
    encodePictureLevelParams.bPostDeblockOutEnable = deblockingEnabled && !suppressReconPic;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodePictureLevel(&encodePictureLevelParams));

    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface->osCpInterface);

    auto cpInterface = m_hwInterface->GetCpInterface();
    auto avcSlcParams = m_avcSliceParams;
    auto avcPicParams = m_avcPicParams[avcSlcParams->pic_parameter_set_id];
    auto avcSeqParams = m_avcSeqParams[avcPicParams->seq_parameter_set_id];
    auto slcData = m_slcData;

    // For use with the single task phase implementation
    if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE)
    {
        uint32_t numSlc = (m_frameFieldHeightInMb + m_sliceHeight - 1) / m_sliceHeight;

        if (numSlc != m_numSlices)
        {
            return MOS_STATUS_INVALID_PARAMETER;
        }
    }

    bool useBatchBufferForPakSlices = false;
    if (m_singleTaskPhaseSupported  && m_singleTaskPhaseSupportedInPak)
    {
        if (m_currPass == 0)
        {
            // The same buffer is used for all slices for all passes.
            uint32_t batchBufferForPakSlicesSize =
                (m_numPasses + 1) * m_numSlices * m_pakSliceSize;
            if (batchBufferForPakSlicesSize >
                (uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iSize)
            {
                if (m_batchBufferForPakSlices[m_currRecycledBufIdx].iSize)
                {
                    CODECHAL_ENCODE_CHK_STATUS_RETURN(ReleaseBatchBufferForPakSlices(m_currRecycledBufIdx));
                }

                CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBatchBufferForPakSlices(
                    m_numSlices,
                    m_numPasses,
                    m_currRecycledBufIdx));
            }
        }
        CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_LockBb(
            m_osInterface,
            &m_batchBufferForPakSlices[m_currRecycledBufIdx]));
        useBatchBufferForPakSlices = true;
    }

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

    if (m_osInterface->osCpInterface->IsCpEnabled())
    {
        MHW_CP_SLICE_INFO_PARAMS sliceInfoParam;
        sliceInfoParam.bLastPass = (m_currPass == m_numPasses) ? true : false;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->SetMfxProtectionState(false, &cmdBuffer, nullptr, &sliceInfoParam));
        CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->UpdateParams(false));
    }

    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 = false;

    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 = bBrcEnabled;
    // Disable Panic mode when min/max QP control is on. kernel may disable it, but disable in driver also.
    if (avcSeqParams->bForcePanicModeControl == 1) {
       sliceState.bRCPanicEnable = (!avcSeqParams->bPanicModeDisable) && (!bMinMaxQPControlEnabled);
    } else {
        sliceState.bRCPanicEnable = m_panicEnable && (!bMinMaxQPControlEnabled);
    }
    sliceState.bAcceleratorHeaderPackingCaps = m_encodeParams.bAcceleratorHeaderPackingCaps;
    sliceState.wFrameFieldHeightInMB = m_frameFieldHeightInMb;

    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 (bAcceleratorHeaderPackingCaps)
            {
                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 = false;
        // App handles tail insertion for VDEnc dynamic slice in non-cp case
        sliceState.bVdencNoTailInsertion = false;

        uint32_t batchBufferForPakSlicesStartOffset =
            (uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iCurrent;

        if (useBatchBufferForPakSlices)
        {
            sliceState.pBatchBufferForPakSlices =
                &m_batchBufferForPakSlices[m_currRecycledBufIdx];
            sliceState.bSingleTaskPhaseSupported = true;
            sliceState.dwBatchBufferForPakSlicesStartOffset = batchBufferForPakSlicesStartOffset;
        }

        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         = bRoundingInterEnable;
            CODECHAL_ENCODE_CHK_STATUS_RETURN(GetInterRounding(&sliceState));
        }

        CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSlice(&cmdBuffer, &sliceState));

        // Add dumps for 2nd level batch buffer
        if (sliceState.bSingleTaskPhaseSupported)
        {
            CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState.pBatchBufferForPakSlices);

            CODECHAL_DEBUG_TOOL(
                CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
                    sliceState.pBatchBufferForPakSlices,
                    CODECHAL_MEDIA_STATE_ENC_NORMAL,
                    nullptr));
            )
        }
    }

    if (useBatchBufferForPakSlices)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_UnlockBb(
            m_osInterface,
            &m_batchBufferForPakSlices[m_currRecycledBufIdx],
            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;
        pakInsertObjectParams.dwBitSize = 32;   // use dwBitSize for SrcDataEndingBitInclusion
        if (m_lastPicInSeq)
        {
            pakInsertObjectParams.dwLastPicInSeqData = (uint32_t)((1 << 16) | CODECHAL_ENCODE_AVC_NAL_UT_EOSEQ << 24);
        }
        if (m_lastPicInStream)
        {
            pakInsertObjectParams.dwLastPicInStreamData = (uint32_t)((1 << 16) | CODECHAL_ENCODE_AVC_NAL_UT_EOSTREAM << 24);
        }
        pakInsertObjectParams.bHeaderLengthExcludeFrmSize = true;
        if (pakInsertObjectParams.bEmulationByteBitsInsert)
        {
            //Does not matter here, but keeping for consistency
            CODECHAL_ENCODE_ASSERTMESSAGE("The emulation prevention bytes are not inserted by the app and are requested to be inserted by HW.");
        }
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr, &pakInsertObjectParams));
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(&cmdBuffer));

    // BRC PAK statistics different for each pass
    if (bBrcEnabled)
    {
        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 = &BrcBuffers.resBrcPakStatisticBuffer[0];
        readBrcPakStatsParams.presStatusBuffer = &m_encodeStatusBuf.resStatusBuffer;
        readBrcPakStatsParams.dwStatusBufNumPassesOffset = offset;
        readBrcPakStatsParams.ucPass = m_currPass;
        readBrcPakStatsParams.VideoContext = m_videoContext;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadBrcPakStatistics(&cmdBuffer, &readBrcPakStatsParams));
    }

    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(CodecHal_DbgReplaceAllCommands(
        //    m_debugInterface,
        //    &cmdBuffer));
    )

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

    // For VDEnc SHME and CSC need to wait workload finish on render engine
    if ((m_currPass == 0) && !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
    {
        auto 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(SubmitCommandBuffer(&cmdBuffer, renderingFlags));

        CODECHAL_DEBUG_TOOL(
            if (!m_mmcUserFeatureUpdated) {
                CODECHAL_UPDATE_ENCODE_MMC_USER_FEATURE(m_reconSurface, m_osInterface->pOsContext);
                m_mmcUserFeatureUpdated = true;
            })

        if (m_sliceSizeStreamoutSupported)
        {
            CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
                &m_pakSliceSizeStreamoutBuffer,
                CodechalDbgAttr::attrOutput,
                "SliceSizeStreamout",
                CODECHAL_ENCODE_SLICESIZE_BUF_SIZE,
                0,
                CODECHAL_NUM_MEDIA_STATES)));
        }

        if ((m_currPass == m_numPasses) &&
            m_signalEnc &&
            !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
        {
            // Check if the signal obj count exceeds max value
            if (m_semaphoreObjCount == MOS_MIN(m_semaphoreMaxCount, MOS_MAX_OBJECT_SIGNALED))
            {
                auto syncParams = g_cInitSyncParams;
                syncParams.GpuContext = m_renderContext;
                syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;

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

            // signal semaphore
            auto syncParams = g_cInitSyncParams;
            syncParams.GpuContext = m_videoContext;
            syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;

            CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
            m_semaphoreObjCount++;
        }
    }

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

        m_newPpsHeader = 0;
        m_newSeqHeader = 0;
    }

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateSliceStateParam(
            bAdaptiveRoundingInterEnable,
            &sliceState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpFrameParFile());
    )

    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::UserFeatureKeyReport());

    CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcSeqParam);

    // AVC Encode BRC Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_BRC_ENABLE_ID, bBrcEnabled, m_osInterface->pOsContext);

    // AVC HME Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_ME_IN_USE_ID, m_hmeSupported, m_osInterface->pOsContext);

    // AVC SuperHME Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_16xME_IN_USE_ID, m_16xMeSupported, m_osInterface->pOsContext);

    // AVC UltraHME Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_32xME_IN_USE_ID, m_32xMeSupported, m_osInterface->pOsContext);

    // AVC RateControl Method Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_RATECONTROL_METHOD_ID, m_avcSeqParam->RateControlMethod, m_osInterface->pOsContext);

    // AVC Adaptive Transform Decision Enable Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ADAPTIVE_TRANSFORM_DECISION_ENABLE_ID, m_adaptiveTransformDecisionEnabled, m_osInterface->pOsContext);

    // FBR Bypass Enable Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_FBR_BYPASS_ENABLE_ID, bFBRBypassEnable, m_osInterface->pOsContext);

    // Static frame detection Enable Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_STATIC_FRAME_DETECTION_ENABLE_ID, bStaticFrameDetectionEnable, m_osInterface->pOsContext);

    // Adaptive Search Windows Enable Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_SEARCH_WINDOW_ENABLE_ID, bApdatvieSearchWindowEnable, m_osInterface->pOsContext);

    // AVC FTQ Reporting
#if (_DEBUG || _RELEASE_INTERNAL)
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_FTQ_IN_USE_ID, bFTQEnable, m_osInterface->pOsContext);

    // AVC CAF Reporting
    CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_CAF_IN_USE_ID, bCAFEnable, m_osInterface->pOsContext);

#endif // _DEBUG || _RELEASE_INTERNAL

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::EncodeGenerateSliceMap(uint8_t* data, PCODEC_AVC_ENCODE_SLICE_PARAMS avcSliceParams)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(data);
    CODECHAL_ENCODE_CHK_NULL_RETURN(avcSliceParams);

    auto sliceMapRow = (uint32_t*)(data + m_sliceMapBottomFieldOffset);
    auto sliceMap = sliceMapRow;
    uint32_t sliceMapPitch = m_sliceMapSurface[m_currRecycledBufIdx].dwPitch / sizeof(uint32_t);
    uint32_t count = 0;

    for (uint32_t j = 0; j < m_numSlices; j++)
    {
        for (uint32_t i = 0; i < avcSliceParams->NumMbsForSlice; i++)
        {
            *sliceMap++ = j;
            if ((count > 0) && ((count % m_picWidthInMb == 0)))
            {
                sliceMapRow += sliceMapPitch;
                sliceMap = sliceMapRow;
                *sliceMap++ = j;
            }
            count++;
        }
        avcSliceParams++;
    }
    *sliceMap++ = 0xFFFFFFFF;        // Set last uint32_t to -1.

    return eStatus;
}

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

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CodechalEncodeAvcBase::AllocateResources();

    uint32_t fieldNumMBs = m_picWidthInMb * ((m_picHeightInMb + 1) >> 1);
    // Field/frame info not ready here, need to round up to even Height for field mode
    uint32_t picWidthHeightInMB = fieldNumMBs * 2;
    uint32_t fieldHeightInMB =
        CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(((m_frameHeight + 1) >> 1));

    // initiate allocation parameters 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 = 1;

    if (m_pakEnabled)
    {
        // Allocate skip frame copy buffer
        allocParamsForBufferLinear.dwBytes = dwSkipFrameBufferSize = CODECHAL_PAGE_SIZE;
        allocParamsForBufferLinear.pBufName = "Skip Frame Copy Buffer";

        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &resSkipFrameBuffer), "Failed to allocate Skip Frame Copy Buffer\n");
    }

    // Allocate SEI buffer
    SeiData.pSEIBuffer = (uint8_t *)MOS_AllocAndZeroMemory(CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE);
    if (SeiData.pSEIBuffer == nullptr)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate SEI Buffer.");
        eStatus = MOS_STATUS_UNKNOWN;
        return eStatus;
    }
    SeiData.dwSEIBufSize = CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE;

    // Resources required by legacy AVC ENC
    if (m_encEnabled)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesBrc());

        bVMEScratchBuffer =
            (MbEncBindingTable.dwAvcMBEncDebugScratch != CODECHAL_INVALID_BINDING_TABLE_IDX);

        if (bVMEScratchBuffer)
        {
            // VME Scratch buffer (HSW), 256 bytes (8 GRFs) per MB
            uint32_t size = m_picWidthInMb * m_picHeightInMb * 256;
            allocParamsForBufferLinear.dwBytes = size;
            allocParamsForBufferLinear.pBufName = "VME Scratch Buffer";

            eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
                m_osInterface,
                &allocParamsForBufferLinear,
                &resVMEScratchBuffer);

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

            uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
                m_osInterface,
                &(resVMEScratchBuffer),
                &lockFlagsWriteOnly);
            CODECHAL_ENCODE_CHK_NULL_RETURN(data);
            MOS_ZeroMemory(data, size);
            m_osInterface->pfnUnlockResource(
                m_osInterface,
                &resVMEScratchBuffer);
        }

        // allocate VME Kernel Dump buffer
        if (bVMEKernelDump)
        {
            allocParamsForBufferLinear.dwBytes = picWidthHeightInMB;
            allocParamsForBufferLinear.pBufName = "VME Kernel Dump Buffer";

            eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
                m_osInterface,
                &allocParamsForBufferLinear,
                &resVmeKernelDumpBuffer);

            if (eStatus != MOS_STATUS_SUCCESS)
            {
                CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VME Kernel Dump Buffer.");
                return eStatus;
            }
        }

        if (bRefPicSelectListSupported)
        {
            auto refPicSelect = RefPicSelectList;
            for (uint32_t i = 0; i < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; i++, refPicSelect++)
            {
                MOS_ZeroMemory(&refPicSelect->sBuffer, sizeof(MOS_SURFACE));
                refPicSelect->FrameIdx = CODECHAL_ENCODE_AVC_INVALID_PIC_ID;
                refPicSelect->sBuffer.TileType = MOS_TILE_LINEAR;
                refPicSelect->sBuffer.bArraySpacing = true;
                refPicSelect->sBuffer.Format = Format_Buffer_2D;
                refPicSelect->sBuffer.dwWidth = MOS_ALIGN_CEIL((m_picWidthInMb * 8), 64);
                refPicSelect->sBuffer.dwHeight = MOS_ALIGN_CEIL(2 * fieldHeightInMB, 8);
                refPicSelect->sBuffer.dwPitch = MOS_ALIGN_CEIL((m_picWidthInMb * 8), 64);

                allocParamsForBuffer2D.dwWidth = refPicSelect->sBuffer.dwWidth;
                allocParamsForBuffer2D.dwHeight = refPicSelect->sBuffer.dwHeight;
                allocParamsForBuffer2D.pBufName = "RefPicSelectList Buffer";

                eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
                    m_osInterface,
                    &allocParamsForBuffer2D,
                    &refPicSelect->sBuffer.OsResource);

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

    if (bStaticFrameDetectionEnable)
    {
        // SFD output buffer
        allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE_COMMON, CODECHAL_CACHELINE_SIZE);
        allocParamsForBufferLinear.pBufName = "Static frame detection output buffer";

        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &resSFDOutputBuffer[0]), "Failed to allocate static frame detection output buffer\n");

        // SFD P-frame cost table buffer
        allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON, CODECHAL_CACHELINE_SIZE);
        allocParamsForBufferLinear.pBufName = "SFD P-frame cost table buffer";

        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &resSFDCostTablePFrameBuffer), "Failed to allocate SFD P-frame cost table buffer\n");

        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &resSFDCostTableBFrameBuffer), "Failed to allocate SFD B-frame cost table buffer\n");

        // copy SFD P-frame cost table
        uint8_t* data;
        if (nullptr == (data = (uint8_t*)m_osInterface->pfnLockResource(
            m_osInterface,
            &resSFDCostTablePFrameBuffer,
            &lockFlagsWriteOnly)))
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock SFD P-frame cost table Buffer.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }
        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(data,
                                                      CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t),
                                                      m_codechalEncodeAvcSfdCostTablePFrame,
                                                      CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t)),
            "Failed to copy SFD P-frame cost table");
        m_osInterface->pfnUnlockResource(m_osInterface, &resSFDCostTablePFrameBuffer);

        // copy SFD B-frame cost table
        if (nullptr == (data = (uint8_t*)m_osInterface->pfnLockResource(
            m_osInterface,
            &resSFDCostTableBFrameBuffer,
            &lockFlagsWriteOnly)))
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock SFD B-frame cost table Buffer.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }
        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(data,
                                                      CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t),
                                                      m_codechalEncodeAvcSfdCostTableBFrame,
                                                      CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t)),
            "Failed to copy SFD B-frame cost table");
        m_osInterface->pfnUnlockResource(m_osInterface, &resSFDCostTableBFrameBuffer);
    }

    // allocate MB specific data buffer
    allocParamsForBufferLinear.dwBytes = picWidthHeightInMB * sizeof(CODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS);
    allocParamsForBufferLinear.pBufName = "MB Specific Data Buffer";

    for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &resMbSpecificDataBuffer[i]);

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

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::AllocateResourcesBrc()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    // initiate allocation parameters 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 = 1;

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

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

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

    uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource(
        m_osInterface,
        &(BrcBuffers.resBrcHistoryBuffer),
        &lockFlagsWriteOnly);

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

    MOS_ZeroMemory(pData, size);
    m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resBrcHistoryBuffer);

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

    eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
        m_osInterface,
        &allocParamsForBufferLinear,
        &BrcBuffers.resBrcPakStatisticBuffer[0]);

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

    pData = (uint8_t*)m_osInterface->pfnLockResource(
        m_osInterface,
        &(BrcBuffers.resBrcPakStatisticBuffer[0]),
        &lockFlagsWriteOnly);

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

    MOS_ZeroMemory(pData, size);
    m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resBrcPakStatisticBuffer[0]);

    // PAK IMG_STATEs buffer
    // Use BRC_MAXIMUM_NUM_PASSES here since actual number of passes is determined later using PicParams.BRCPrecision
    size = BRC_IMG_STATE_SIZE_PER_PASS * CODECHAL_ENCODE_BRC_MAXIMUM_NUM_PASSES;
    allocParamsForBufferLinear.dwBytes = size;
    allocParamsForBufferLinear.pBufName = "PAK IMG State Read Buffer";

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

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

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

        if (pData == nullptr)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC IMG State Read Buffer.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }

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

    allocParamsForBufferLinear.pBufName = "PAK IMG State Write Buffer";
    eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
        m_osInterface,
        &allocParamsForBufferLinear,
        &BrcBuffers.resBrcImageStatesWriteBuffer);

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

    pData = (uint8_t*)m_osInterface->pfnLockResource(
        m_osInterface,
        &(BrcBuffers.resBrcImageStatesWriteBuffer),
        &lockFlagsWriteOnly);

    if (pData == nullptr)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC IMG State Write Buffer.");
        eStatus = MOS_STATUS_UNKNOWN;
        return eStatus;
    }

    MOS_ZeroMemory(pData, size);
    m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resBrcImageStatesWriteBuffer);

    // Check if the constant data surface is present
    for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        //BRC Constant Data Surfaces
        MOS_ZeroMemory(&BrcBuffers.sBrcConstantDataBuffer[i], sizeof(MOS_SURFACE));
        BrcBuffers.sBrcConstantDataBuffer[i].TileType = MOS_TILE_LINEAR;
        BrcBuffers.sBrcConstantDataBuffer[i].bArraySpacing = true;
        BrcBuffers.sBrcConstantDataBuffer[i].Format = Format_Buffer_2D;
        BrcBuffers.sBrcConstantDataBuffer[i].dwWidth =
            dwBrcConstantSurfaceWidth;
        BrcBuffers.sBrcConstantDataBuffer[i].dwHeight =
            dwBrcConstantSurfaceHeight;
        BrcBuffers.sBrcConstantDataBuffer[i].dwPitch =
            dwBrcConstantSurfaceWidth;

        allocParamsForBuffer2D.dwWidth = MOS_ALIGN_CEIL(dwBrcConstantSurfaceWidth, 64);
        allocParamsForBuffer2D.dwHeight = dwBrcConstantSurfaceHeight;
        allocParamsForBuffer2D.pBufName = "BRC Constant Data Buffer";

        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBuffer2D,
            &BrcBuffers.sBrcConstantDataBuffer[i].OsResource);

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

    uint32_t width, height, downscaledFieldHeightInMB4x;
    if (bBrcDistortionBufferSupported)
    {
        // BRC Distortion Surface
        downscaledFieldHeightInMB4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS((m_frameHeight + 1) >> 3);
        width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 3), 64);
        height = MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x << 2), 8) << 1;

        allocParamsForBuffer2D.dwWidth = width;
        allocParamsForBuffer2D.dwHeight = height;
        allocParamsForBuffer2D.pBufName = "BRC Distortion Surface Buffer";

        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBuffer2D,
            &BrcBuffers.sMeBrcDistortionBuffer.OsResource);

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

        BrcBuffers.sMeBrcDistortionBuffer.TileType = MOS_TILE_LINEAR;
        BrcBuffers.sMeBrcDistortionBuffer.bArraySpacing = true;
        BrcBuffers.sMeBrcDistortionBuffer.Format = Format_Buffer_2D;
        BrcBuffers.sMeBrcDistortionBuffer.dwWidth = width;
        BrcBuffers.sMeBrcDistortionBuffer.dwHeight = height;
        BrcBuffers.sMeBrcDistortionBuffer.dwPitch = (uint32_t)BrcBuffers.sMeBrcDistortionBuffer.OsResource.pGmmResInfo->GetRenderPitch();

        pData = (uint8_t*)m_osInterface->pfnLockResource(
            m_osInterface,
            &(BrcBuffers.sMeBrcDistortionBuffer.OsResource),
            &lockFlagsWriteOnly);

        if (pData == nullptr)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock ME BRC Distortion Buffer.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }

        size = BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight;
        MOS_ZeroMemory(pData, size);
        m_osInterface->pfnUnlockResource(
            m_osInterface, &BrcBuffers.sMeBrcDistortionBuffer.OsResource);
    }

    // MbBrcConstDataBuffer
    // 16 DWs per QP value
    size = 16 * (CODEC_AVC_NUM_QP) * sizeof(uint32_t);
    allocParamsForBufferLinear.dwBytes = size;
    allocParamsForBufferLinear.pBufName = "MB BRC Constant Data Buffer";

    for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &BrcBuffers.resMbBrcConstDataBuffer[i]);

        if (eStatus != MOS_STATUS_SUCCESS)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate MB BRC Constant Data Buffer.");
            return eStatus;
        }
        pData = (uint8_t*)m_osInterface->pfnLockResource(
            m_osInterface,
            &(BrcBuffers.resMbBrcConstDataBuffer[i]),
            &lockFlagsWriteOnly);
        CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
        MOS_ZeroMemory(pData, size);
        m_osInterface->pfnUnlockResource(
            m_osInterface,
            &BrcBuffers.resMbBrcConstDataBuffer[i]);
    }

    // Use a separate surface MbEnc DSH data
    if(!CodecHalIsFeiEncode(m_codecFunction))
    {
    size =
        m_renderEngineInterface->m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData() +
        MOS_ALIGN_CEIL(pMbEncKernelStates->KernelParams.iCurbeLength,
            m_renderEngineInterface->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
    allocParamsForBufferLinear.dwBytes = size;
    allocParamsForBufferLinear.pBufName = "MbEnc Curbe Buffer";

    eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
        m_osInterface,
        &allocParamsForBufferLinear,
        &BrcBuffers.resMbEncAdvancedDsh);

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

    pData = (uint8_t*)m_osInterface->pfnLockResource(
        m_osInterface,
        &BrcBuffers.resMbEncAdvancedDsh,
        &lockFlagsWriteOnly);

    if (pData == nullptr)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock MbEnc Curbe Buffer.");
        eStatus = MOS_STATUS_UNKNOWN;
        return eStatus;
    }

    MOS_ZeroMemory(pData, size);
    m_osInterface->pfnUnlockResource(
        m_osInterface,
        &BrcBuffers.resMbEncAdvancedDsh);
    }
    // MbEnc BRC buffer - buffer written by BRC and used by MbEnc
    if (bDecoupleMbEncCurbeFromBRC)
    {
        size = m_mbencBrcBufferSize;
        allocParamsForBufferLinear.dwBytes = size;
        allocParamsForBufferLinear.pBufName = "MbEnc BRC buffer";

        eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBufferLinear,
            &BrcBuffers.resMbEncBrcBuffer);

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

        pData = (uint8_t*)m_osInterface->pfnLockResource(
            m_osInterface,
            &(BrcBuffers.resMbEncBrcBuffer),
            &lockFlagsWriteOnly);

        if (pData == nullptr)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock MbEnc BRC buffer.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }

        MOS_ZeroMemory(pData, size);
        m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resMbEncBrcBuffer);
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::AllocateResourcesMbBrc()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    // initiate allocation paramters and lock flags
    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 = 1;

    uint32_t downscaledFieldHeightInMB4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS((m_frameHeight + 1) >> 3);

    // Mb QP Surface
    if (Mos_ResourceIsNull(&BrcBuffers.sBrcMbQpBuffer.OsResource))
    {
        uint32_t width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 2), 64);
        uint32_t height = MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x << 2), 8) << 1;
        uint32_t size = width * height;

        MOS_ZeroMemory(&BrcBuffers.sBrcMbQpBuffer, sizeof(MOS_SURFACE));
        BrcBuffers.sBrcMbQpBuffer.TileType = MOS_TILE_LINEAR;
        BrcBuffers.sBrcMbQpBuffer.bArraySpacing = true;
        BrcBuffers.sBrcMbQpBuffer.Format = Format_Buffer_2D;
        BrcBuffers.sBrcMbQpBuffer.dwWidth = allocParamsForBuffer2D.dwWidth = width;
        BrcBuffers.sBrcMbQpBuffer.dwHeight = allocParamsForBuffer2D.dwHeight = height;
        BrcBuffers.sBrcMbQpBuffer.dwPitch = width;
        allocParamsForBuffer2D.pBufName = "BRC MB QP Buffer";

        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBuffer2D,
            &BrcBuffers.sBrcMbQpBuffer.OsResource), "Failed to allocate BRC MB QP surface.");

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

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

        MOS_ZeroMemory(pData, size);
        m_osInterface->pfnUnlockResource(
            m_osInterface,
            &BrcBuffers.sBrcMbQpBuffer.OsResource);
    }

    // BRC ROI Surface
    if (Mos_ResourceIsNull(&BrcBuffers.sBrcRoiSurface.OsResource) && bBrcRoiEnabled)
    {
        uint32_t width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 4), 64);
        uint32_t height = MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x << 2), 8) << 1;

        MOS_ZeroMemory(&BrcBuffers.sBrcRoiSurface, sizeof(MOS_SURFACE));
        allocParamsForBuffer2D.dwWidth = width;
        allocParamsForBuffer2D.dwHeight = height;
        allocParamsForBuffer2D.pBufName = "BRC ROI Surface";

        CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
            m_osInterface,
            &allocParamsForBuffer2D,
            &BrcBuffers.sBrcRoiSurface.OsResource), "Failed to allocate BRC ROI surface.");

        BrcBuffers.sBrcRoiSurface.TileType = MOS_TILE_LINEAR;
        BrcBuffers.sBrcRoiSurface.bArraySpacing = true;
        BrcBuffers.sBrcRoiSurface.Format = Format_Buffer_2D;
        BrcBuffers.sBrcRoiSurface.dwWidth = width;
        BrcBuffers.sBrcRoiSurface.dwHeight = height;
        BrcBuffers.sBrcRoiSurface.dwPitch = (uint32_t)BrcBuffers.sBrcRoiSurface.OsResource.pGmmResInfo->GetRenderPitch();

        uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource(
            m_osInterface,
            &(BrcBuffers.sBrcRoiSurface.OsResource),
            &lockFlagsWriteOnly);

        if (pData == nullptr)
        {
            CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC ROI surface.");
            eStatus = MOS_STATUS_UNKNOWN;
            return eStatus;
        }

        uint32_t size = BrcBuffers.sBrcRoiSurface.dwPitch * BrcBuffers.sBrcRoiSurface.dwHeight;
        MOS_ZeroMemory(pData, size);
        m_osInterface->pfnUnlockResource(
            m_osInterface,
            &BrcBuffers.sBrcRoiSurface.OsResource);
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::ReleaseResourcesBrc()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

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

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &BrcBuffers.resBrcPakStatisticBuffer[0]);

    for (int i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
    {
        m_osInterface->pfnFreeResource(
            m_osInterface,
            &BrcBuffers.resBrcImageStatesReadBuffer[i]);

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

        m_osInterface->pfnFreeResource(
            m_osInterface,
            &BrcBuffers.resMbBrcConstDataBuffer[i]);
    }

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &BrcBuffers.resBrcImageStatesWriteBuffer);

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &BrcBuffers.sMeBrcDistortionBuffer.OsResource);

    m_osInterface->pfnFreeResource(m_osInterface, &BrcBuffers.resMbEncAdvancedDsh);

    m_osInterface->pfnFreeResource(
        m_osInterface,
        &BrcBuffers.resMbEncBrcBuffer);

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::ReleaseResourcesMbBrc()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

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

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

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::GenericEncodeMeKernel(EncodeBrcBuffers* brcBuffers, HmeLevel hmeLevel)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
    // Each ME kernel buffer counts as a separate perf task
    m_osInterface->pfnResetPerfBufferID(m_osInterface);

    CODECHAL_MEDIA_STATE_TYPE EncFunctionType = (hmeLevel == HME_LEVEL_32x) ? CODECHAL_MEDIA_STATE_32X_ME :
        (hmeLevel == HME_LEVEL_16x) ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;

    uint32_t krnStateIdx = ((m_pictureCodingType == P_TYPE) ? CODECHAL_ENCODE_ME_IDX_P : CODECHAL_ENCODE_ME_IDX_B);
    auto kernelState = &m_meKernelStates[krnStateIdx];

    // If Single Task Phase is not enabled, use BT count for the kernel state.
    if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
    {
        uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ?
            m_maxBtCount : kernelState->KernelParams.iBTCount;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
            m_stateHeapInterface,
            dwMaxBtCount));
        m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
        CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
        m_stateHeapInterface,
        kernelState,
        false,
        0,
        false,
        m_storeData));

    MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
    MOS_ZeroMemory(&idParams, sizeof(idParams));
    idParams.pKernelState = kernelState;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
        m_stateHeapInterface,
        1,
        &idParams));

    // Setup AVC Curbe
    MeCurbeParams meParams;
    MOS_ZeroMemory(&meParams, sizeof(meParams));
    meParams.hmeLvl = hmeLevel;
    meParams.pKernelState = kernelState;

    if (!m_useCommonKernel)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeMe(
            &meParams));
    }

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            EncFunctionType,
            MHW_DSH_TYPE,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
            EncFunctionType,
            kernelState));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            EncFunctionType,
            MHW_ISH_TYPE,
            kernelState));
    )

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

    SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
    sendKernelCmdsParams.EncFunctionType = EncFunctionType;
    sendKernelCmdsParams.pKernelState = kernelState;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));

    // Add binding table
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
        m_stateHeapInterface,
        kernelState));

    //Add surface states
    MeSurfaceParams meSurfaceParams;
    MOS_ZeroMemory(&meSurfaceParams, sizeof(meSurfaceParams));
    meSurfaceParams.dwNumRefIdxL0ActiveMinus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1;
    meSurfaceParams.dwNumRefIdxL1ActiveMinus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1;
    meSurfaceParams.pL0RefFrameList = &(m_avcSliceParams->RefPicList[LIST_0][0]);
    meSurfaceParams.pL1RefFrameList = &(m_avcSliceParams->RefPicList[LIST_1][0]);
    meSurfaceParams.ppRefList = &m_refList[0];
    meSurfaceParams.pPicIdx = &m_picIdx[0];
    meSurfaceParams.pCurrOriginalPic = &m_currOriginalPic;
    meSurfaceParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer;
    meSurfaceParams.dw4xMeMvBottomFieldOffset = (uint32_t)m_meMvBottomFieldOffset;
    meSurfaceParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer;
    meSurfaceParams.dw16xMeMvBottomFieldOffset = (uint32_t)m_meMv16xBottomFieldOffset;
    meSurfaceParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer;
    meSurfaceParams.dw32xMeMvBottomFieldOffset = (uint32_t)m_meMv32xBottomFieldOffset;
    meSurfaceParams.dw4xScaledBottomFieldOffset = (uint32_t)m_scaledBottomFieldOffset;
    meSurfaceParams.dw16xScaledBottomFieldOffset = (uint32_t)m_scaled16xBottomFieldOffset;
    meSurfaceParams.dw32xScaledBottomFieldOffset = (uint32_t)m_scaled32xBottomFieldOffset;
    meSurfaceParams.psMeDistortionBuffer = &m_4xMeDistortionBuffer;
    meSurfaceParams.dwMeDistortionBottomFieldOffset = (uint32_t)m_meDistortionBottomFieldOffset;
    meSurfaceParams.psMeBrcDistortionBuffer = &brcBuffers->sMeBrcDistortionBuffer;
    meSurfaceParams.dwMeBrcDistortionBottomFieldOffset = brcBuffers->dwMeBrcDistortionBottomFieldOffset;
    meSurfaceParams.dwDownscaledWidthInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledWidthInMb32x :
        (hmeLevel == HME_LEVEL_16x) ? m_downscaledWidthInMb16x : m_downscaledWidthInMb4x;
    meSurfaceParams.dwDownscaledHeightInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledFrameFieldHeightInMb32x :
        (hmeLevel == HME_LEVEL_16x) ? m_downscaledFrameFieldHeightInMb16x : m_downscaledFrameFieldHeightInMb4x;
    meSurfaceParams.dwVerticalLineStride = m_verticalLineStride;
    meSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset;
    meSurfaceParams.b32xMeInUse = (hmeLevel == HME_LEVEL_32x) ? true : false;
    meSurfaceParams.b16xMeInUse = (hmeLevel == HME_LEVEL_16x) ? true : false;
    meSurfaceParams.b32xMeEnabled = m_32xMeEnabled;
    meSurfaceParams.b16xMeEnabled = m_16xMeEnabled;
    meSurfaceParams.pMeBindingTable = &m_meBindingTable;
    meSurfaceParams.pKernelState = kernelState;

    if (!m_useCommonKernel)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SendMeSurfaces(&cmdBuffer, &meSurfaceParams));
    }

    // Dump SSH for ME kernel
    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
            EncFunctionType,
            MHW_SSH_TYPE,
            kernelState)));

    /* zero out the mv data memory and me distortion buffer for the driver ULT
    kernel only writes out this data used for current frame, in some cases the the data used for
    previous frames would be left in the buffer (for example, the L1 mv for B frame would still show
    in the P frame mv data buffer */

    /* Zeroing out the buffers has perf impact, so zero it out only when dumps are actually enabled */

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
        uint8_t*   data;
        uint32_t   size;
        bool    driverMeDumpEnabled;

        driverMeDumpEnabled = m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel4xMe)||
            m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel16xMe)||
            m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel32xMe);

        if (driverMeDumpEnabled)
        {
            MOS_LOCK_PARAMS lockFlags;
            MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
            lockFlags.WriteOnly = 1;

            switch (hmeLevel)
            {
            case HME_LEVEL_32x:
                data = (uint8_t*)m_osInterface->pfnLockResource(
                    m_osInterface,
                    &m_32xMeMvDataBuffer.OsResource,
                    &lockFlags);
                CODECHAL_ENCODE_CHK_NULL_RETURN(data);
                size = MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) *
                    (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
                MOS_ZeroMemory(data, size);
                m_osInterface->pfnUnlockResource(
                    m_osInterface,
                    &m_32xMeMvDataBuffer.OsResource);
                break;
            case HME_LEVEL_16x:
                data = (uint8_t*)m_osInterface->pfnLockResource(
                    m_osInterface,
                    &m_16xMeMvDataBuffer.OsResource,
                    &lockFlags);
                CODECHAL_ENCODE_CHK_NULL_RETURN(data);
                size = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) *
                    (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
                MOS_ZeroMemory(data, size);
                m_osInterface->pfnUnlockResource(
                    m_osInterface,
                    &m_16xMeMvDataBuffer.OsResource);
                break;
            case HME_LEVEL_4x:
                data = (uint8_t*)m_osInterface->pfnLockResource(
                    m_osInterface,
                    &m_4xMeMvDataBuffer.OsResource,
                    &lockFlags);
                CODECHAL_ENCODE_CHK_NULL_RETURN(data);
                size = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) *
                    (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
                MOS_ZeroMemory(data, size);
                m_osInterface->pfnUnlockResource(
                    m_osInterface,
                    &m_4xMeMvDataBuffer.OsResource);
                break;
            default:
                eStatus = MOS_STATUS_INVALID_PARAMETER;
                return eStatus;
            }

            // zeroing out ME dist buffer
            if (m_4xMeDistortionBufferSupported)
            {
                data = (uint8_t*)m_osInterface->pfnLockResource(
                    m_osInterface, &m_4xMeDistortionBuffer.OsResource, &lockFlags);
                CODECHAL_ENCODE_CHK_NULL_RETURN(data);
                size = m_4xMeDistortionBuffer.dwHeight * m_4xMeDistortionBuffer.dwPitch;
                MOS_ZeroMemory(data, size);
                m_osInterface->pfnUnlockResource(
                    m_osInterface,
                    &m_4xMeDistortionBuffer.OsResource);
            }
        }
    );

    uint32_t uiScalingFactor = (hmeLevel == HME_LEVEL_32x) ? SCALE_FACTOR_32x :
        (hmeLevel == HME_LEVEL_16x) ? SCALE_FACTOR_16x : SCALE_FACTOR_4x;

    uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / uiScalingFactor);
    uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / uiScalingFactor);

    CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
    MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
    walkerCodecParams.WalkerMode = m_walkerMode;
    walkerCodecParams.dwResolutionX = resolutionX;
    walkerCodecParams.dwResolutionY = resolutionY;
    walkerCodecParams.bNoDependency = true;
    walkerCodecParams.bMbaff = m_mbaffEnabled;
    walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported;
    walkerCodecParams.ucGroupId = m_groupId;

    MHW_WALKER_PARAMS walkerParams;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
        m_hwInterface,
        &walkerParams,
        &walkerCodecParams));

    HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
    HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
        &cmdBuffer,
        &walkerParams));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, EncFunctionType));

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

    CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
        & cmdBuffer,
        EncFunctionType,
        nullptr)));

    m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase);

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

    if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
    {
        HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
        m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
        m_lastTaskInPhase = false;
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::InitKernelStateMe()
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    uint8_t* kernelBinary;
    uint32_t kernelSize;

    uint32_t kuid = m_useCommonKernel ? m_kuidCommon : m_kuid;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, kuid, &kernelBinary, &kernelSize));

    for (auto krnStateIdx = 0; krnStateIdx < 2; krnStateIdx++)
    {
        CODECHAL_KERNEL_HEADER              currKrnHeader;
        auto kernelStatePtr = &m_meKernelStates[krnStateIdx];

        auto encOperation = ENC_ME;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(this->pfnGetKernelHeaderAndSize(
            kernelBinary,
            encOperation,
            krnStateIdx,
            &currKrnHeader,
            (uint32_t*)&kernelSize));

        kernelStatePtr->KernelParams.iBTCount = CODECHAL_ENCODE_AVC_ME_NUM_SURFACES_CM;
        kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads;
        kernelStatePtr->KernelParams.iCurbeLength = sizeof(CODECHAL_ENCODE_AVC_ME_CURBE);
        kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
        kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
        kernelStatePtr->KernelParams.iIdCount = 1;

        kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
        kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
        kernelStatePtr->KernelParams.iSize = kernelSize;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
            m_stateHeapInterface,
            kernelStatePtr->KernelParams.iBTCount,
            &kernelStatePtr->dwSshSize,
            &kernelStatePtr->dwBindingTableSize));

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr));

        if (m_noMeKernelForPFrame)
        {
            m_meKernelStates[1] = m_meKernelStates[0];
            break;
        }
    }

    // Until a better way can be found, maintain old binding table structures
    auto bindingTable = &m_meBindingTable;
    bindingTable->dwMEMVDataSurface = CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE_CM;
    bindingTable->dw16xMEMVDataSurface = CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE_CM;
    bindingTable->dw32xMEMVDataSurface = CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE_CM;
    bindingTable->dwMEDist = CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE_CM;
    bindingTable->dwMEBRCDist = CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION_CM;
    bindingTable->dwMECurrForFwdRef = CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF_CM;
    bindingTable->dwMEFwdRefPicIdx[0] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX0_CM;
    bindingTable->dwMEFwdRefPicIdx[1] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX1_CM;
    bindingTable->dwMEFwdRefPicIdx[2] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX2_CM;
    bindingTable->dwMEFwdRefPicIdx[3] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX3_CM;
    bindingTable->dwMEFwdRefPicIdx[4] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX4_CM;
    bindingTable->dwMEFwdRefPicIdx[5] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX5_CM;
    bindingTable->dwMEFwdRefPicIdx[6] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX6_CM;
    bindingTable->dwMEFwdRefPicIdx[7] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX7_CM;
    bindingTable->dwMECurrForBwdRef = CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF_CM;
    bindingTable->dwMEBwdRefPicIdx[0] = CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX0_CM;
    bindingTable->dwMEBwdRefPicIdx[1] = CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX1_CM;

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::SetCurbeMe(MeCurbeParams* params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;
    CODECHAL_ENCODE_ASSERT(m_avcSeqParam->TargetUsage <= NUM_TARGET_USAGE_MODES);

    auto slcParams = m_avcSliceParams;
    auto framePicture = CodecHal_PictureIsFrame(m_avcPicParam->CurrOriginalPic);
    auto qpPrimeY =
        (m_avcPicParam->pic_init_qp_minus26 + 26) +
        m_avcSliceParams->slice_qp_delta;

    auto mvShiftFactor = 0;
    auto prevMvReadPosFactor = 0;
    bool useMvFromPrevStep, writeDistortions;
    uint32_t scaleFactor;

    switch (params->hmeLvl)
    {
    case HME_LEVEL_32x:
        useMvFromPrevStep = CODECHAL_ENCODE_AVC_HME_FIRST_STEP;
        writeDistortions = false;
        scaleFactor = SCALE_FACTOR_32x;
        mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_32x;
        break;
    case HME_LEVEL_16x:
        useMvFromPrevStep = (m_32xMeEnabled) ? CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP : CODECHAL_ENCODE_AVC_HME_FIRST_STEP;
        writeDistortions = false;
        scaleFactor = SCALE_FACTOR_16x;
        mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_16x;
        prevMvReadPosFactor = CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_16x;
        break;
    case HME_LEVEL_4x:
        useMvFromPrevStep = (m_16xMeEnabled) ? CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP : CODECHAL_ENCODE_AVC_HME_FIRST_STEP;
        writeDistortions = true;
        scaleFactor = SCALE_FACTOR_4x;
        mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_4x;
        prevMvReadPosFactor = CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_4x;
        break;
    default:
        eStatus = MOS_STATUS_INVALID_PARAMETER;
        return eStatus;
        break;
    }

    CODECHAL_ENCODE_AVC_ME_CURBE cmd;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
        &cmd,
        sizeof(CODECHAL_ENCODE_AVC_ME_CURBE),
        g_cInit_CODECHAL_ENCODE_AVC_ME_CURBE,
        sizeof(CODECHAL_ENCODE_AVC_ME_CURBE)));

    if (m_avcPicParam->bEnableSubPelMode)
    {
        cmd.DW3.SubPelMode = m_avcPicParam->SubPelMode;
    }
    else
    {
        cmd.DW3.SubPelMode = 3;
    }

    if (m_fieldScalingOutputInterleaved)
    {
        cmd.DW3.SrcAccess =
            cmd.DW3.RefAccess = CodecHal_PictureIsField(m_avcPicParam->CurrOriginalPic) ? 1 : 0;
        cmd.DW7.SrcFieldPolarity = CodecHal_PictureIsBottomField(m_avcPicParam->CurrOriginalPic) ? 1 : 0;
    }

    cmd.DW4.PictureHeightMinus1 = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scaleFactor) - 1;
    cmd.DW4.PictureWidth = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth / scaleFactor);
    cmd.DW5.QpPrimeY = qpPrimeY;
    cmd.DW6.WriteDistortions = writeDistortions;
    cmd.DW6.UseMvFromPrevStep = useMvFromPrevStep;

    cmd.DW6.SuperCombineDist = m_superCombineDistGeneric[m_avcSeqParam->TargetUsage];
    cmd.DW6.MaxVmvR = (framePicture) ?
        CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level) * 4 :
        (CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level) >> 1) * 4;

    if (m_pictureCodingType == B_TYPE)
    {
        // This field is irrelevant since we are not using the bi-direct search.
        // set it to 32
        cmd.DW1.BiWeight = 32;
        cmd.DW13.NumRefIdxL1MinusOne =
            m_avcSliceParams->num_ref_idx_l1_active_minus1;
    }

    if (m_pictureCodingType == P_TYPE ||
        m_pictureCodingType == B_TYPE)
    {
        cmd.DW13.NumRefIdxL0MinusOne =
            m_avcSliceParams->num_ref_idx_l0_active_minus1;
    }

    cmd.DW13.RefStreaminCost = 5;
    // This flag is to indicate the ROI source type instead of indicating ROI is enabled or not
    cmd.DW13.ROIEnable = 0;

    if (!framePicture)
    {
        if (m_pictureCodingType != I_TYPE)
        {
            cmd.DW14.List0RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_0);
            cmd.DW14.List0RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_1);
            cmd.DW14.List0RefID2FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_2);
            cmd.DW14.List0RefID3FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_3);
            cmd.DW14.List0RefID4FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_4);
            cmd.DW14.List0RefID5FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_5);
            cmd.DW14.List0RefID6FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_6);
            cmd.DW14.List0RefID7FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_7);
        }
        if (m_pictureCodingType == B_TYPE)
        {
            cmd.DW14.List1RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_0);
            cmd.DW14.List1RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_1);
        }
    }

    cmd.DW15.MvShiftFactor = mvShiftFactor;
    cmd.DW15.PrevMvReadPosFactor = prevMvReadPosFactor;

    // r3 & r4
    uint8_t                                   meMethod, tableIdx, tu = 0;
    tu = m_avcSeqParam->TargetUsage;
    if (m_pictureCodingType == B_TYPE)
    {
        meMethod = m_bmeMethodTable ?  // use the ME table dependent on prototype or codec standard
                       m_bmeMethodTable[tu]
                                    : m_bMeMethodGeneric[tu];
    }
    else
    {
        meMethod = m_meMethodTable ?  // use the ME table dependent on prototype or codec standard
                       m_meMethodTable[tu]
                                   : m_meMethodGeneric[tu];
    }

    tableIdx = (m_pictureCodingType == B_TYPE) ? 1 : 0;
    eStatus = MOS_SecureMemcpy(&(cmd.SPDelta), 14 * sizeof(uint32_t), m_encodeSearchPath[tableIdx][meMethod], 14 * sizeof(uint32_t));
    if (eStatus != MOS_STATUS_SUCCESS)
    {
        CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
        return eStatus;
    }

    // r5
    cmd.DW32._4xMeMvOutputDataSurfIndex = CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE_CM;
    cmd.DW33._16xOr32xMeMvInputDataSurfIndex = (params->hmeLvl == HME_LEVEL_32x) ?
        CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE_CM : CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE_CM;
    cmd.DW34._4xMeOutputDistSurfIndex = CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE_CM;
    cmd.DW35._4xMeOutputBrcDistSurfIndex = CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION_CM;
    cmd.DW36.VMEFwdInterPredictionSurfIndex = CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF_CM;
    cmd.DW37.VMEBwdInterPredictionSurfIndex = CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF_CM;

    CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
        &cmd,
        params->pKernelState->dwCurbeOffset,
        sizeof(cmd)));

    CODECHAL_DEBUG_TOOL(
        CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateHmeParam(
            m_16xMeEnabled,
            m_32xMeEnabled,
            meMethod,
            &cmd));
    )

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::SendMeSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, MeSurfaceParams* params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pCurrOriginalPic);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps4xMeMvDataBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeDistortionBuffer);
    CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeBrcDistortionBuffer);

    CODECHAL_MEDIA_STATE_TYPE       encMediaStateType;
    encMediaStateType = (params->b32xMeInUse) ? CODECHAL_MEDIA_STATE_32X_ME :
        params->b16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;

    CODECHAL_ENCODE_CHK_NULL_RETURN(params->pMeBindingTable);
    auto meBindingTable = params->pMeBindingTable;

    auto currFieldPicture = CodecHal_PictureIsField(*(params->pCurrOriginalPic)) ? 1 : 0;
    auto currBottomField = CodecHal_PictureIsBottomField(*(params->pCurrOriginalPic)) ? 1 : 0;
    uint8_t ucCurrVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME :
        ((currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);

    PMOS_SURFACE                    currScaledSurface = nullptr, meMvDataBuffer = nullptr;
    uint32_t                           meMvBottomFieldOffset = 0, currScaledBottomFieldOffset = 0, refScaledBottomFieldOffset = 0;
    if (params->b32xMeInUse)
    {
        CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps32xMeMvDataBuffer);
        currScaledSurface = m_trackedBuf->Get32xDsSurface(CODEC_CURR_TRACKED_BUFFER);
        meMvDataBuffer = params->ps32xMeMvDataBuffer;
        meMvBottomFieldOffset = params->dw32xMeMvBottomFieldOffset;
        currScaledBottomFieldOffset = params->dw32xScaledBottomFieldOffset;
    }
    else if (params->b16xMeInUse)
    {
        CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps16xMeMvDataBuffer);
        currScaledSurface = m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER);
        meMvDataBuffer = params->ps16xMeMvDataBuffer;
        meMvBottomFieldOffset = params->dw16xMeMvBottomFieldOffset;
        currScaledBottomFieldOffset = params->dw16xScaledBottomFieldOffset;
    }
    else
    {
        currScaledSurface = m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER);
        meMvDataBuffer = params->ps4xMeMvDataBuffer;
        meMvBottomFieldOffset = params->dw4xMeMvBottomFieldOffset;
        currScaledBottomFieldOffset = params->dw4xScaledBottomFieldOffset;
    }

    // Reference height and width information should be taken from the current scaled surface rather
    // than from the reference scaled surface in the case of PAFF.
    auto refScaledSurface = *currScaledSurface;

    auto width = MOS_ALIGN_CEIL(params->dwDownscaledWidthInMb * 32, 64);
    auto height = params->dwDownscaledHeightInMb * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER;

    // Force the values
    meMvDataBuffer->dwWidth = width;
    meMvDataBuffer->dwHeight = height;
    meMvDataBuffer->dwPitch = width;

    CODECHAL_SURFACE_CODEC_PARAMS   surfaceParams;
    MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
    surfaceParams.bIs2DSurface = true;
    surfaceParams.bMediaBlockRW = true;
    surfaceParams.psSurface = meMvDataBuffer;
    surfaceParams.dwOffset = meMvBottomFieldOffset;
    surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
    surfaceParams.dwBindingTableOffset = meBindingTable->dwMEMVDataSurface;
    surfaceParams.bIsWritable = true;
    surfaceParams.bRenderTarget = true;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
        m_hwInterface,
        cmdBuffer,
        &surfaceParams,
        params->pKernelState));

    if (params->b16xMeInUse && params->b32xMeEnabled)
    {
        // Pass 32x MV to 16x ME operation
        MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
        surfaceParams.bIs2DSurface = true;
        surfaceParams.bMediaBlockRW = true;
        surfaceParams.psSurface = params->ps32xMeMvDataBuffer;
        surfaceParams.dwOffset =
            currBottomField ? params->dw32xMeMvBottomFieldOffset : 0;
        surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
        surfaceParams.dwBindingTableOffset = meBindingTable->dw32xMEMVDataSurface;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
            m_hwInterface,
            cmdBuffer,
            &surfaceParams,
            params->pKernelState));
    }
    else if (!params->b32xMeInUse && params->b16xMeEnabled)
    {
        // Pass 16x MV to 4x ME operation
        MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
        surfaceParams.bIs2DSurface = true;
        surfaceParams.bMediaBlockRW = true;
        surfaceParams.psSurface = params->ps16xMeMvDataBuffer;
        surfaceParams.dwOffset =
            currBottomField ? params->dw16xMeMvBottomFieldOffset : 0;
        surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
        surfaceParams.dwBindingTableOffset = meBindingTable->dw16xMEMVDataSurface;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
            m_hwInterface,
            cmdBuffer,
            &surfaceParams,
            params->pKernelState));
    }

    // Insert Distortion buffers only for 4xMe case
    if (!params->b32xMeInUse && !params->b16xMeInUse)
    {
        MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
        surfaceParams.bIs2DSurface = true;
        surfaceParams.bMediaBlockRW = true;
        surfaceParams.psSurface = params->psMeBrcDistortionBuffer;
        surfaceParams.dwOffset = params->dwMeBrcDistortionBottomFieldOffset;
        surfaceParams.dwBindingTableOffset = meBindingTable->dwMEBRCDist;
        surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value;
        surfaceParams.bIsWritable = true;
        surfaceParams.bRenderTarget = true;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
            m_hwInterface,
            cmdBuffer,
            &surfaceParams,
            params->pKernelState));

        MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
        surfaceParams.bIs2DSurface = true;
        surfaceParams.bMediaBlockRW = true;
        surfaceParams.psSurface = params->psMeDistortionBuffer;
        surfaceParams.dwOffset = params->dwMeDistortionBottomFieldOffset;
        surfaceParams.dwBindingTableOffset = meBindingTable->dwMEDist;
        surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
        surfaceParams.bIsWritable = true;
        surfaceParams.bRenderTarget = true;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
            m_hwInterface,
            cmdBuffer,
            &surfaceParams,
            params->pKernelState));
    }

    // Setup references 1...n
    // LIST 0 references
    uint8_t                           refPicIdx, refIdx;
    CODEC_PICTURE                   refPic;
    bool                            refFieldPicture, refBottomField;
    for (refIdx = 0; refIdx <= params->dwNumRefIdxL0ActiveMinus1; refIdx++)
    {
        refPic = params->pL0RefFrameList[refIdx];

        if (!CodecHal_PictureIsInvalid(refPic) && params->pPicIdx[refPic.FrameIdx].bValid)
        {
            if (refIdx == 0)
            {
                // Current Picture Y - VME
                MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
                surfaceParams.bUseAdvState = true;
                surfaceParams.psSurface = currScaledSurface;
                surfaceParams.dwOffset = currBottomField ? currScaledBottomFieldOffset : 0;
                surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
                surfaceParams.dwBindingTableOffset = meBindingTable->dwMECurrForFwdRef;
                surfaceParams.ucVDirection = ucCurrVDirection;
                CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
                    m_hwInterface,
                    cmdBuffer,
                    &surfaceParams,
                    params->pKernelState));
            }

            refFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0;
            refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
            refPicIdx = params->pPicIdx[refPic.FrameIdx].ucPicIdx;
            uint8_t scaledIdx = params->ppRefList[refPicIdx]->ucScalingIdx;
            MOS_SURFACE* surface;
            if (params->b32xMeInUse)
            {
                surface = m_trackedBuf->Get32xDsSurface(scaledIdx);
            }
            else if (params->b16xMeInUse)
            {
                surface = m_trackedBuf->Get16xDsSurface(scaledIdx);
            }
            else
            {
                surface = m_trackedBuf->Get4xDsSurface(scaledIdx);
            }
            CODECHAL_ENCODE_CHK_NULL_RETURN(surface);
            refScaledSurface.OsResource = surface->OsResource;
            refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
            // L0 Reference Picture Y - VME
            MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
            surfaceParams.bUseAdvState = true;
            surfaceParams.psSurface = &refScaledSurface;
            surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0;
            surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
            surfaceParams.dwBindingTableOffset = meBindingTable->dwMEFwdRefPicIdx[refIdx];
            surfaceParams.ucVDirection = !currFieldPicture ? CODECHAL_VDIRECTION_FRAME :
                ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
            CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
                m_hwInterface,
                cmdBuffer,
                &surfaceParams,
                params->pKernelState));
        }
    }

    // Setup references 1...n
    // LIST 1 references
    for (refIdx = 0; refIdx <= params->dwNumRefIdxL1ActiveMinus1; refIdx++)
    {
        refPic = params->pL1RefFrameList[refIdx];

        if (!CodecHal_PictureIsInvalid(refPic) && params->pPicIdx[refPic.FrameIdx].bValid)
        {
            if (refIdx == 0)
            {
                // Current Picture Y - VME
                MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
                surfaceParams.bUseAdvState = true;
                surfaceParams.psSurface = currScaledSurface;
                surfaceParams.dwOffset = currBottomField ? currScaledBottomFieldOffset : 0;
                surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
                surfaceParams.dwBindingTableOffset = meBindingTable->dwMECurrForBwdRef;
                surfaceParams.ucVDirection = ucCurrVDirection;
                CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
                    m_hwInterface,
                    cmdBuffer,
                    &surfaceParams,
                    params->pKernelState));
            }

            refFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0;
            refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
            refPicIdx = params->pPicIdx[refPic.FrameIdx].ucPicIdx;
            uint8_t scaledIdx = params->ppRefList[refPicIdx]->ucScalingIdx;
            MOS_SURFACE* surface;
            if (params->b32xMeInUse)
            {
                surface = m_trackedBuf->Get32xDsSurface(scaledIdx);
            }
            else if (params->b16xMeInUse)
            {
                surface = m_trackedBuf->Get16xDsSurface(scaledIdx);
            }
            else
            {
                surface = m_trackedBuf->Get4xDsSurface(scaledIdx);
            }
            CODECHAL_ENCODE_CHK_NULL_RETURN(surface);
            refScaledSurface.OsResource = surface->OsResource;
            refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
            // L1 Reference Picture Y - VME
            MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
            surfaceParams.bUseAdvState = true;
            surfaceParams.psSurface = &refScaledSurface;
            surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0;
            surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
            surfaceParams.dwBindingTableOffset = meBindingTable->dwMEBwdRefPicIdx[refIdx];
            surfaceParams.ucVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME :
                ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
            CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
                m_hwInterface,
                cmdBuffer,
                &surfaceParams,
                params->pKernelState));
        }
    }

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::GenericEncodePictureLevel(PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params)
{
    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    auto trellisQuantParams = &m_trellisQuantParams;

    PerfTagSetting perfTag;
    perfTag.Value = 0;
    perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
    perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE;
    perfTag.PictureCodingType = m_pictureCodingType;
    m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);

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

    // set MFX_PIPE_MODE_SELECT values
    MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
    pipeModeSelectParams.Mode = m_mode;
    pipeModeSelectParams.bStreamOutEnabled = (m_currPass != m_numPasses);// Disable Stream Out for final pass; its important for multiple passes, because , next pass will take the qp from stream out

    pipeModeSelectParams.bDeblockerStreamOutEnable = params->bDeblockerStreamOutEnable;
    pipeModeSelectParams.bPostDeblockOutEnable = params->bPostDeblockOutEnable;
    pipeModeSelectParams.bPreDeblockOutEnable = params->bPreDeblockOutEnable;
    pipeModeSelectParams.bDynamicSliceEnable = m_avcSeqParam->EnableSliceLevelRateCtrl;

    // set MFX_PIPE_BUF_ADDR_STATE values
    MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
    pipeBufAddrParams.Mode = m_mode;
    pipeBufAddrParams.psPreDeblockSurface = params->psPreDeblockSurface;
    pipeBufAddrParams.psPostDeblockSurface = params->psPostDeblockSurface;

    CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetPipeBufAddr(&pipeBufAddrParams));

    pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak;
    pipeBufAddrParams.presStreamOutBuffer = &m_resStreamOutBuffer[m_currRecycledBufIdx];
    pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer;
    pipeBufAddrParams.presMfdIntraRowStoreScratchBuffer = &m_intraRowStoreScratchBuffer;
    pipeBufAddrParams.presMacroblockIldbStreamOutBuffer1 = params->presMacroblockIldbStreamOutBuffer1;
    pipeBufAddrParams.presMacroblockIldbStreamOutBuffer2 = params->presMacroblockIldbStreamOutBuffer2;

    CODECHAL_DEBUG_TOOL(
        // PAK Input Raw Surface
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
            m_rawSurfaceToPak,
            CodechalDbgAttr::attrEncodeRawInputSurface,
            "PAK_Input_SrcSurf"));
    )

    auto firstValidFrame = &m_reconSurface.OsResource;

    // Setting invalid entries to nullptr
    for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
    {
        pipeBufAddrParams.presReferences[i] = nullptr;
    }

    uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME;

    for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
    {
        if (m_picIdx[i].bValid)
        {
            uint8_t picIdx = m_picIdx[i].ucPicIdx;
            uint8_t frameStoreId = m_refList[picIdx]->ucFrameId;

            CodecHalGetResourceInfo(
                m_osInterface,
                &(m_refList[picIdx]->sRefReconBuffer));
            pipeBufAddrParams.presReferences[frameStoreId] =
                &(m_refList[picIdx]->sRefReconBuffer.OsResource);

            if (picIdx < firstValidFrameId)
            {
                firstValidFrameId = picIdx;
                firstValidFrame = pipeBufAddrParams.presReferences[picIdx];
            }

            CODECHAL_DEBUG_TOOL(
                CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
                MOS_SURFACE refSurface;

                MOS_ZeroMemory(&refSurface, sizeof(refSurface));
                refSurface.Format     = Format_NV12;
                refSurface.OsResource = *(pipeBufAddrParams.presReferences[frameStoreId]);
                CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
                    m_osInterface,
                    &refSurface));

                m_debugInterface->m_refIndex = frameStoreId;
                std::string refSurfName      = "RefSurf[" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)) + "]";
                CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
                    &refSurface,
                    CodechalDbgAttr::attrReferenceSurfaces,
                    refSurfName.c_str()));)
        }
    }

    for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
    {
        // error concealment for the unset reference addresses
        if (!pipeBufAddrParams.presReferences[i])
        {
            pipeBufAddrParams.presReferences[i] = firstValidFrame;
        }
    }

    if (m_sliceSizeStreamoutSupported)
    {
        pipeBufAddrParams.presSliceSizeStreamOutBuffer = &m_pakSliceSizeStreamoutBuffer;
    }

    // set MFX_IND_OBJ_BASE_ADDR_STATE values
    MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
    MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
    indObjBaseAddrParams.Mode = CODECHAL_ENCODE_MODE_AVC;

    indObjBaseAddrParams.presMvObjectBuffer = &m_resMvDataSurface;
    indObjBaseAddrParams.dwMvObjectOffset = m_mvBottomFieldOffset;
    indObjBaseAddrParams.dwMvObjectSize = m_mvDataSize;
    indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer;
    indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound;

    // set MFX_BSP_BUF_BASE_ADDR_STATE values
    MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
    MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
    bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resMPCRowStoreScratchBuffer;

    MHW_VDBOX_QM_PARAMS qmParams;
    qmParams.Standard = CODECHAL_AVC;
    qmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;

    MHW_VDBOX_QM_PARAMS fqmParams;
    fqmParams.Standard = CODECHAL_AVC;
    fqmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;

    // Add AVC Direct Mode command
    MHW_VDBOX_AVC_DIRECTMODE_PARAMS directmodeParams;
    MOS_ZeroMemory(&directmodeParams, sizeof(directmodeParams));
    directmodeParams.CurrPic = m_avcPicParam->CurrReconstructedPic;
    directmodeParams.isEncode = true;
    directmodeParams.uiUsedForReferenceFlags = 0xFFFFFFFF;
    directmodeParams.pAvcPicIdx = &(m_picIdx[0]);
    directmodeParams.avcRefList = (void**)m_refList;
    directmodeParams.bPicIdRemappingInUse = false;
    directmodeParams.bDisableDmvBuffers = true;

    // PAK cmd buffer header insertion for 1) non STF 2) STF (except VDEnc BRC case inserted in HuC cmd buffer)
    if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
    {
        bool requestFrameTracking = false;

        m_hwInterface->m_numRequestedEuSlices = ((m_frameHeight * m_frameWidth) >= m_ssdResolutionThreshold &&
            m_targetUsage <= m_ssdTargetUsageThreshold) ?
            m_sliceShutdownRequestState : m_sliceShutdownDefaultState;

        // Send command buffer header at the beginning (OS dependent)
        // frame tracking tag is only added in the last command buffer header
        requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));

        m_hwInterface->m_numRequestedEuSlices = CODECHAL_SLICE_SHUTDOWN_DEFAULT;
    }

    if (m_currPass == 0 && params->bBrcEnabled)
    {
        CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS    encodePictureLevelParam;
        MOS_ZeroMemory(&encodePictureLevelParam, sizeof(encodePictureLevelParam));
        encodePictureLevelParam.presBrcHistoryBuffer = params->presBrcHistoryBuffer;
        CODECHAL_ENCODE_CHK_STATUS_RETURN(SceneChangeReport(&cmdBuffer, &encodePictureLevelParam));
    }

    if (m_currPass)
    {
        MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams;
        // Insert conditional batch buffer end
        MOS_ZeroMemory(
            &miConditionalBatchBufferEndParams,
            sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));

        miConditionalBatchBufferEndParams.presSemaphoreBuffer =
            &m_encodeStatusBuf.resStatusBuffer;
        miConditionalBatchBufferEndParams.dwOffset =
            (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
            m_encodeStatusBuf.dwImageStatusMaskOffset +
            (sizeof(uint32_t) * 2);

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

    if (!m_currPass && 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.
        MHW_MI_STORE_DATA_PARAMS                        params;
        PMOS_RESOURCE                                   globalGpuContextSyncTagBuffer = nullptr;
        uint32_t                                        value;

        CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource(
            m_osInterface,
            globalGpuContextSyncTagBuffer));
        CODECHAL_HW_CHK_NULL_RETURN(globalGpuContextSyncTagBuffer);

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

    CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));

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

    // set MFX_SURFACE_STATE values
    // Ref surface
    MHW_VDBOX_SURFACE_PARAMS reconSurfaceParams;
    MOS_ZeroMemory(&reconSurfaceParams, sizeof(reconSurfaceParams));
    reconSurfaceParams.Mode = m_mode;
    reconSurfaceParams.ucSurfaceStateId = CODECHAL_MFX_REF_SURFACE_ID;
    reconSurfaceParams.psSurface = &m_reconSurface;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &reconSurfaceParams));

    // Src surface
    MHW_VDBOX_SURFACE_PARAMS surfaceParams;
    MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
    surfaceParams.Mode = m_mode;
    surfaceParams.ucSurfaceStateId = CODECHAL_MFX_SRC_SURFACE_ID;
    surfaceParams.psSurface = m_rawSurfaceToPak;
    surfaceParams.bDisplayFormatSwizzle = m_avcPicParam->bDisplayFormatSwizzle;
    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));

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

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

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));

    if (params->bBrcEnabled && m_avcSeqParam->RateControlMethod != RATECONTROL_ICQ)
    {
        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
            &cmdBuffer,
            params->pImgStateBatchBuffer));
    }
    else
    {
        //Set MFX_AVC_IMG_STATE command
        MHW_VDBOX_AVC_IMG_PARAMS imageStateParams;
        imageStateParams.currPass = m_currPass;
        imageStateParams.pEncodeAvcPicParams = m_avcPicParam;
        imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam;
        imageStateParams.pEncodeAvcSliceParams = m_avcSliceParams;
        if (CodecHalIsFeiEncode(m_codecFunction) && m_avcFeiPicParams && m_avcFeiPicParams->dwMaxFrameSize)
        {
            imageStateParams.pDeltaQp = m_avcFeiPicParams->pDeltaQp;
            imageStateParams.dwMaxFrameSize = m_avcFeiPicParams->dwMaxFrameSize;
        }
        else if (CodecHalUsesPakEngine(m_codecFunction) && m_avcPicParam->dwMaxFrameSize)
        {
            imageStateParams.pDeltaQp = m_avcPicParam->pDeltaQp;
            imageStateParams.dwMaxFrameSize = m_avcPicParam->dwMaxFrameSize;
        }
        imageStateParams.wPicWidthInMb = m_picWidthInMb;
        imageStateParams.wPicHeightInMb = m_picHeightInMb;
        imageStateParams.ppRefList = &(m_refList[0]);
        imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled;
        imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding;
        imageStateParams.ucKernelMode = m_kernelMode;
        imageStateParams.wSlcHeightInMb = m_sliceHeight;
        imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level);
        imageStateParams.bSliceSizeStreamOutEnabled = m_sliceSizeStreamoutSupported;

        if (m_currPass && m_currPass == m_numPasses)
        {
            // Enable IPCM pass, excluding VDENC BRC case
            imageStateParams.bIPCMPass = true;
        }

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(&cmdBuffer, nullptr, &imageStateParams));

        CODECHAL_DEBUG_TOOL(
            CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam(
                &cmdBuffer,
                nullptr));
        )
    }

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxFqmCmd(&cmdBuffer, &fqmParams));

    CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcDirectmodeCmd(&cmdBuffer, &directmodeParams));

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

    return eStatus;
}

MOS_STATUS CodechalEncodeAvcEnc::SendPrologWithFrameTracking(
    PMOS_COMMAND_BUFFER         cmdBuffer,
    bool                        frameTracking,
    MHW_MI_MMIOREGISTERS       *mmioRegister)
{
    return CodechalEncoderState::SendPrologWithFrameTracking(cmdBuffer, frameTracking, mmioRegister);
}

MOS_STATUS CodechalEncodeAvcEnc::ExecutePreEnc(EncoderParams* encodeParams)
{
    MOS_SYNC_PARAMS                     syncParams;

    CODECHAL_ENCODE_FUNCTION_ENTER;

    CODECHAL_ENCODE_CHK_NULL_RETURN(encodeParams->pPreEncParams);
    FeiPreEncParams *preEncParams = (FeiPreEncParams *)encodeParams->pPreEncParams;

    m_encodeParams           = *encodeParams;
    m_newSeqHeader           = encodeParams->newSeqHeader;
    m_newPpsHeader           = encodeParams->newPpsHeader;
    m_arbitraryNumMbsInSlice = encodeParams->arbitraryNumMbsInSlice;

    if (preEncParams->bDisableMVOutput && preEncParams->bDisableStatisticsOutput)
    {
        m_disableStatusReport = true;
    }

    m_osInterface->pfnIncPerfFrameID(m_osInterface);

    CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(InitializePicture(m_encodeParams),
        "Encoding initialization failed.");

    // Check if source surface needs to be synchronized and should wait for decode or VPP or any other context
    if (m_firstField)
    {
        syncParams = g_cInitSyncParams;
        syncParams.GpuContext = m_renderContext;
        syncParams.presSyncResource = &m_rawSurface.OsResource;
        syncParams.bReadOnly = true;

        CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));

        // Update the resource tag (s/w tag) for On-Demand Sync
        // set the tag on render context for ENC case only, else set it on video context for ENC+PAK case
        m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
    }

    // set render engine context
    m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext);
    m_osInterface->pfnResetOsStates(m_osInterface);

    // set all status reports to completed state
    InitStatusReport();

    // Call ENC Kernels
    CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(ExecuteKernelFunctions(),
        "ENC failed.");

#ifndef FEI_ENABLE_CMRT
    // Flush encode eStatus buffer
    CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(ResetStatusReport(),
        "ResetStatusReprot failed.");
#else
    CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(ResetStatusReport(),
        "ResetStatusReprot failed.");
#endif
    m_disableStatusReport = false;

    if (m_firstFrame == false && m_firstTwoFrames == true)
    {
        m_firstTwoFrames = false;
    }

    m_firstFrame = false;
    return MOS_STATUS_SUCCESS;
}

#if USE_CODECHAL_DEBUG_TOOL
MOS_STATUS CodechalEncodeAvcEnc::PopulateHmeParam(
    bool    is16xMeEnabled,
    bool    is32xMeEnabled,
    uint8_t meMethod,
    void    *cmd)
{
    CODECHAL_DEBUG_FUNCTION_ENTER;

    CODECHAL_DEBUG_CHK_NULL(m_debugInterface);

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

    CODECHAL_ENCODE_AVC_ME_CURBE *curbe = (CODECHAL_ENCODE_AVC_ME_CURBE *)cmd;

    if (m_pictureCodingType == P_TYPE)
    {
        m_avcPar->SuperHME         = is16xMeEnabled;
        m_avcPar->UltraHME         = is32xMeEnabled;
        m_avcPar->SuperCombineDist = curbe->DW6.SuperCombineDist;
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalEncodeAvcEnc::DumpFrameParFile()
{
    CODECHAL_DEBUG_FUNCTION_ENTER;

    CODECHAL_DEBUG_CHK_NULL(m_debugInterface);

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

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

    if (m_pictureCodingType == I_TYPE)
    {
        // I Slice Parameters
        // DDI Params
        oss << "ProfileIDC = " << std::dec << +m_avcPar->ProfileIDC << std::endl;
        oss << "LevelIDC = " << std::dec << +m_avcPar->LevelIDC << std::endl;
        oss << "DisableVUIHeader = " << std::dec << +m_avcPar->DisableVUIHeader << std::endl;
        oss << "ChromaFormatIDC = " << std::dec << +m_avcPar->ChromaFormatIDC << std::endl;
        oss << "ChromaQpOffset = " << std::dec << +m_avcPar->ChromaQpOffset << std::endl;
        oss << "SecondChromaQpOffset = " << std::dec << +m_avcPar->SecondChromaQpOffset << std::endl;
        oss << "PictureCodingType = " << std::dec << +m_avcPar->PictureCodingType << std::endl;
        oss << "NumP = " << std::dec << +m_avcPar->NumP << std::endl;
        oss << "NumB = " << std::dec << +m_avcPar->NumB << std::endl;
        oss << "NumSlices = " << std::dec << +m_avcPar->NumSlices << std::endl;
        oss << "ISliceQP = " << std::dec << +m_avcPar->ISliceQP << std::endl;
        oss << "FrameRateM = " << std::dec << +m_avcPar->FrameRateM << std::endl;
        oss << "FrameRateD = " << std::dec << +m_avcPar->FrameRateD << std::endl;
        oss << "BRCMethod = " << std::dec << +m_avcPar->BRCMethod << std::endl;
        oss << "BRCType = " << std::dec << +m_avcPar->BRCType << std::endl;
        oss << "DeblockingIDC = " << std::dec << +m_avcPar->DeblockingIDC << std::endl;
        oss << "DeblockingFilterAlpha = " << std::dec << +m_avcPar->DeblockingFilterAlpha << std::endl;
        oss << "DeblockingFilterBeta = " << std::dec << +m_avcPar->DeblockingFilterBeta << std::endl;
        oss << "EntropyCodingMode = " << std::dec << +m_avcPar->EntropyCodingMode << std::endl;
        oss << "DirectInference = " << std::dec << +m_avcPar->DirectInference << std::endl;
        oss << "Transform8x8Mode = " << std::dec << +m_avcPar->Transform8x8Mode << std::endl;
        oss << "CRFQualityFactor = " << std::dec << +m_avcPar->CRFQualityFactor << std::endl;
        oss << "ConstrainedIntraPred = " << std::dec << +m_avcPar->ConstrainedIntraPred << std::endl;
        if (m_avcPar->NumP == 0)  // There's no P frame
        {
            oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
            oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
        }

        // DS Params
        oss << "MBFlatnessThreshold = " << std::dec << +m_encodeParState->m_commonPar->mbFlatnessThreshold << std::endl;

        // BRC init Params
        oss << "MBBRCEnable = " << std::dec << +m_avcPar->MBBRCEnable << std::endl;
        oss << "MBRC = " << std::dec << +m_avcPar->MBRC << std::endl;
        oss << "BitRate = " << std::dec << +m_avcPar->BitRate << std::endl;
        oss << "InitVbvFullnessInBit = " << std::dec << +m_avcPar->InitVbvFullnessInBit << std::endl;
        oss << "MaxBitRate = " << std::dec << +m_avcPar->MaxBitRate << std::endl;
        oss << "VbvSzInBit = " << std::dec << +m_avcPar->VbvSzInBit << std::endl;
        oss << "AvbrAccuracy = " << std::dec << +m_avcPar->AvbrAccuracy << std::endl;
        oss << "AvbrConvergence = " << std::dec << +m_avcPar->AvbrConvergence << std::endl;
        oss << "Window_Size = " << std::dec << +m_avcPar->SlidingWindowSize << std::endl;
        oss << "LongTermReferenceInterval = " << std::dec << +m_avcPar->LongTermInterval << std::endl;

        // BRC frame update Params
        oss << "EnableMultipass = " << std::dec << +m_avcPar->EnableMultipass << std::endl;
        oss << "MaxNumPakPasses = " << std::dec << +m_avcPar->MaxNumPakPasses << std::endl;
        oss << "Sliding_Window_Enable = " << std::dec << +m_avcPar->SlidingWindowEnable << std::endl;
        oss << "UserMaxFrame = " << std::dec << +m_avcPar->UserMaxFrame << std::endl;
        oss << "FrameSkip_enable = " << std::dec << +m_avcPar->FrameSkipEnable << std::endl;

        // Enc Params
        oss << "BlockBasedSkip = " << std::dec << +m_avcPar->BlockBasedSkip << std::endl;
        oss << "DisableExtendedMvCostRange = " << std::dec << +m_avcPar->DisableExtendedMvCostRange << std::endl;
        oss << "EnableAdaptiveSearch = " << std::dec << +m_avcPar->EnableAdaptiveSearch << std::endl;
        oss << "EnableFBRBypass = " << std::dec << +m_avcPar->EnableFBRBypass << std::endl;
        oss << "MRDisableQPCheck = " << std::dec << +m_avcPar->MRDisableQPCheck << std::endl;
        oss << "MADEnableFlag = " << std::dec << +m_avcPar->MADEnableFlag << std::endl;
        oss << "EnableMBFlatnessCheckOptimization = " << std::dec << +m_avcPar->EnableMBFlatnessCheckOptimization << std::endl;
        oss << "EnableArbitrarySliceSize = " << std::dec << +m_avcPar->EnableArbitrarySliceSize << std::endl;
        oss << "RefThresh = " << std::dec << +m_avcPar->RefThresh << std::endl;
        oss << "EnableWavefrontOptimization = " << std::dec << +m_avcPar->EnableWavefrontOptimization << std::endl;
        oss << "AllFractional = " << std::dec << +m_avcPar->AllFractional << std::endl;
        oss << "DisableAllFractionalCheckForHighRes = " << std::dec << +m_avcPar->DisableAllFractionalCheckForHighRes << std::endl;
        oss << "MaxLenSP = " << std::dec << +m_avcPar->MaxLenSP << std::endl;

        // PAK Params
        oss << "TrellisQuantizationEnable = " << std::dec << +m_avcPar->TrellisQuantizationEnable << std::endl;
        oss << "RoundingIntraEnabled = " << std::dec << +m_avcPar->RoundingIntraEnabled << std::endl;
        oss << "RoundingIntra = " << std::dec << +m_avcPar->RoundingIntra << std::endl;
        oss << "EnableAdaptiveTrellisQuantization = " << std::dec << +m_avcPar->EnableAdaptiveTrellisQuantization << std::endl;
        oss << "TrellisQuantizationRounding = " << std::dec << +m_avcPar->TrellisQuantizationRounding << std::endl;
        oss << "TrellisQuantizationChromaDisable = " << std::dec << +m_avcPar->TrellisQuantizationChromaDisable << std::endl;
        oss << "ExtendedRhoDomainEn = " << std::dec << +m_avcPar->ExtendedRhoDomainEn << std::endl;
        oss << "EnableSEI = " << std::dec << +m_avcPar->EnableSEI << std::endl;
        if (m_avcPar->NumP == 0)  // There's no P frame
        {
            oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
        }
    }
    else if (m_pictureCodingType == P_TYPE)
    {
        // P Slice Parameters
        // DDI Params
        oss << "PSliceQP = " << std::dec << +m_avcPar->PSliceQP << std::endl;
        oss << "CabacInitIDC = " << std::dec << +m_avcPar->CabacInitIDC << std::endl;
        oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
        oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
        if (m_avcPar->NumB == 0)  // There's no B frame
        {
            oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl;
        }
        oss << "WeightedPred = " << std::dec << +m_avcPar->WeightedPred << std::endl;
        oss << "UseOrigAsRef = " << std::dec << +m_avcPar->UseOrigAsRef << std::endl;
        oss << "BiSubMbPartMask = " << std::dec << +m_avcPar->BiSubMbPartMask << std::endl;

        // HME Params
        oss << "SuperHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superHME : m_avcPar->SuperHME) << std::endl;
        oss << "UltraHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->ultraHME : m_avcPar->UltraHME) << std::endl;
        oss << "SuperCombineDist = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superCombineDist : m_avcPar->SuperCombineDist) << std::endl;

        // Enc Params
        oss << "SubPelMode = " << std::dec << +m_avcPar->SubPelMode << std::endl;
        oss << "FTQBasedSkip = " << std::dec << +m_avcPar->FTQBasedSkip << std::endl;
        oss << "BiMixDisable = " << std::dec << +m_avcPar->BiMixDisable << std::endl;
        oss << "SurvivedSkipCost = " << std::dec << +m_avcPar->SurvivedSkipCost << std::endl;
        oss << "UniMixDisable = " << std::dec << +m_avcPar->UniMixDisable << std::endl;
        oss << "EnableIntraCostScalingForStaticFrame = " << std::dec << +m_avcPar->EnableIntraCostScalingForStaticFrame << std::endl;
        if (m_avcPar->EnableIntraCostScalingForStaticFrame)
        {
            oss << "IntraCostUpdateMethod = 3" << std::endl;
        }
        oss << "StaticFrameIntraCostScalingRatioP = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioP << std::endl;
        oss << "MEMethod = " << std::dec << +m_avcPar->MEMethod << std::endl;
        oss << "HMECombineLen = " << std::dec << +m_avcPar->HMECombineLen << std::endl;
        oss << "HMECombineOverlap = " << std::dec << +m_avcPar->HMECombineOverlap << std::endl;
        oss << "SearchX = " << std::dec << +m_avcPar->SearchX << std::endl;
        oss << "SearchY = " << std::dec << +m_avcPar->SearchY << std::endl;
        oss << "SearchControl = " << std::dec << +m_avcPar->SearchControl << std::endl;
        oss << "MultiplePred = " << std::dec << +m_avcPar->MultiplePred << std::endl;
        oss << "EnableAdaptiveTxDecision = " << std::dec << +m_avcPar->EnableAdaptiveTxDecision << std::endl;
        oss << "MBTextureThreshold = " << std::dec << +m_avcPar->MBTextureThreshold << std::endl;
        oss << "TxDecisionThr = " << std::dec << +m_avcPar->TxDecisionThr << std::endl;
        oss << "EnablePerMBStaticCheck = " << std::dec << +m_avcPar->EnablePerMBStaticCheck << std::endl;
        oss << "EnableAdaptiveSearchWindowSize = " << std::dec << +m_avcPar->EnableAdaptiveSearchWindowSize << std::endl;
        oss << "EnableAdaptiveIntraScaling = " << std::dec << +m_avcPar->EnableAdaptiveIntraScaling << std::endl;

        // BRC Frame Update
        oss << "UserMaxFrame_P = " << std::dec << +m_avcPar->UserMaxFrameP << std::endl;

        // PAK Params
        oss << "RoundingInterEnabled = " << std::dec << +m_avcPar->RoundingInterEnabled << std::endl;
        oss << "RoundingInter = " << std::dec << +m_avcPar->RoundingInter << std::endl;
        oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
        oss << "EnableAdaptiveRounding = " << std::dec << +m_avcPar->EnableAdaptiveRounding << std::endl;
    }
    else if (m_pictureCodingType == B_TYPE)
    {
        // B Slice Parameters
        // DDI Params
        oss << "BSliceQP = " << std::dec << +m_avcPar->BSliceQP << std::endl;
        oss << "MaxBRefIdxL0 = " << std::dec << +m_avcPar->MaxBRefIdxL0 << std::endl;
        oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl;
        oss << "WeightedBiPred = " << std::dec << +m_avcPar->WeightedBiPred << std::endl;

        // Enc Params
        oss << "BMEMethod = " << std::dec << +m_avcPar->BMEMethod << std::endl;
        oss << "HMEBCombineLen = " << std::dec << +m_avcPar->HMEBCombineLen << std::endl;
        oss << "BSearchX = " << std::dec << +m_avcPar->BSearchX << std::endl;
        oss << "BSearchY = " << std::dec << +m_avcPar->BSearchY << std::endl;
        oss << "BSearchControl = " << std::dec << +m_avcPar->BSearchControl << std::endl;
        oss << "BSkipType = " << std::dec << +m_avcPar->BSkipType << std::endl;
        oss << "DirectMode = " << std::dec << +m_avcPar->DirectMode << std::endl;
        oss << "BiWeight = " << std::dec << +m_avcPar->BiWeight << std::endl;
        oss << "StaticFrameIntraCostScalingRatioB = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioB << std::endl;

        // PAK Params
        oss << "RoundingInterB = " << std::dec << +m_avcPar->RoundingInterB << std::endl;
    }

    // Dump per frame par file
    const char *fileName = m_debugInterface->CreateFileName(
        "EncodeFrame",
        "EncodePar",
        CodechalDbgExtType::par);

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

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS CodechalEncodeAvcEnc::DumpSeqParFile()
{
    CODECHAL_DEBUG_FUNCTION_ENTER;

    CODECHAL_DEBUG_CHK_NULL(m_debugInterface);

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

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

    // I Slice Parameters
    // DDI Params
    oss << "ProfileIDC = " << std::dec << +m_avcPar->ProfileIDC << std::endl;
    oss << "LevelIDC = " << std::dec << +m_avcPar->LevelIDC << std::endl;
    oss << "DisableVUIHeader = " << std::dec << +m_avcPar->DisableVUIHeader << std::endl;
    oss << "ChromaFormatIDC = " << std::dec << +m_avcPar->ChromaFormatIDC << std::endl;
    oss << "ChromaQpOffset = " << std::dec << +m_avcPar->ChromaQpOffset << std::endl;
    oss << "SecondChromaQpOffset = " << std::dec << +m_avcPar->SecondChromaQpOffset << std::endl;
    oss << "PictureCodingType = " << std::dec << +m_avcPar->PictureCodingType << std::endl;
    oss << "NumP = " << std::dec << +m_avcPar->NumP << std::endl;
    oss << "NumB = " << std::dec << +m_avcPar->NumB << std::endl;
    oss << "NumSlices = " << std::dec << +m_avcPar->NumSlices << std::endl;
    oss << "ISliceQP = " << std::dec << +m_avcPar->ISliceQP << std::endl;
    oss << "FrameRateM = " << std::dec << +m_avcPar->FrameRateM << std::endl;
    oss << "FrameRateD = " << std::dec << +m_avcPar->FrameRateD << std::endl;
    oss << "BRCMethod = " << std::dec << +m_avcPar->BRCMethod << std::endl;
    oss << "BRCType = " << std::dec << +m_avcPar->BRCType << std::endl;
    oss << "DeblockingIDC = " << std::dec << +m_avcPar->DeblockingIDC << std::endl;
    oss << "DeblockingFilterAlpha = " << std::dec << +m_avcPar->DeblockingFilterAlpha << std::endl;
    oss << "DeblockingFilterBeta = " << std::dec << +m_avcPar->DeblockingFilterBeta << std::endl;
    oss << "EntropyCodingMode = " << std::dec << +m_avcPar->EntropyCodingMode << std::endl;
    oss << "DirectInference = " << std::dec << +m_avcPar->DirectInference << std::endl;
    oss << "Transform8x8Mode = " << std::dec << +m_avcPar->Transform8x8Mode << std::endl;
    oss << "CRFQualityFactor = " << std::dec << +m_avcPar->CRFQualityFactor << std::endl;
    oss << "ConstrainedIntraPred = " << std::dec << +m_avcPar->ConstrainedIntraPred << std::endl;
    if (m_avcPar->NumP == 0)  // There's no P frame
    {
        oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
        oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
    }

    // DS Params
    oss << "MBFlatnessThreshold = " << std::dec << +m_encodeParState->m_commonPar->mbFlatnessThreshold << std::endl;

    // BRC init Params
    oss << "MBBRCEnable = " << std::dec << +m_avcPar->MBBRCEnable << std::endl;
    oss << "MBRC = " << std::dec << +m_avcPar->MBRC << std::endl;
    oss << "BitRate = " << std::dec << +m_avcPar->BitRate << std::endl;
    oss << "InitVbvFullnessInBit = " << std::dec << +m_avcPar->InitVbvFullnessInBit << std::endl;
    oss << "MaxBitRate = " << std::dec << +m_avcPar->MaxBitRate << std::endl;
    oss << "VbvSzInBit = " << std::dec << +m_avcPar->VbvSzInBit << std::endl;
    oss << "AvbrAccuracy = " << std::dec << +m_avcPar->AvbrAccuracy << std::endl;
    oss << "AvbrConvergence = " << std::dec << +m_avcPar->AvbrConvergence << std::endl;
    oss << "Window_Size = " << std::dec << +m_avcPar->SlidingWindowSize << std::endl;
    oss << "LongTermReferenceInterval = " << std::dec << +m_avcPar->LongTermInterval << std::endl;

    // BRC frame update Params
    oss << "EnableMultipass = " << std::dec << +m_avcPar->EnableMultipass << std::endl;
    oss << "MaxNumPakPasses = " << std::dec << +m_avcPar->MaxNumPakPasses << std::endl;
    oss << "Sliding_Window_Enable = " << std::dec << +m_avcPar->SlidingWindowEnable << std::endl;
    oss << "UserMaxFrame = " << std::dec << +m_avcPar->UserMaxFrame << std::endl;
    oss << "FrameSkip_enable = " << std::dec << +m_avcPar->FrameSkipEnable << std::endl;

    // Enc Params
    oss << "BlockBasedSkip = " << std::dec << +m_avcPar->BlockBasedSkip << std::endl;
    oss << "DisableExtendedMvCostRange = " << std::dec << +m_avcPar->DisableExtendedMvCostRange << std::endl;
    oss << "EnableAdaptiveSearch = " << std::dec << +m_avcPar->EnableAdaptiveSearch << std::endl;
    oss << "EnableFBRBypass = " << std::dec << +m_avcPar->EnableFBRBypass << std::endl;
    oss << "MRDisableQPCheck = " << std::dec << +m_avcPar->MRDisableQPCheck << std::endl;
    oss << "MADEnableFlag = " << std::dec << +m_avcPar->MADEnableFlag << std::endl;
    oss << "EnableMBFlatnessCheckOptimization = " << std::dec << +m_avcPar->EnableMBFlatnessCheckOptimization << std::endl;
    oss << "EnableArbitrarySliceSize = " << std::dec << +m_avcPar->EnableArbitrarySliceSize << std::endl;
    oss << "RefThresh = " << std::dec << +m_avcPar->RefThresh << std::endl;
    oss << "EnableWavefrontOptimization = " << std::dec << +m_avcPar->EnableWavefrontOptimization << std::endl;
    oss << "AllFractional = " << std::dec << +m_avcPar->AllFractional << std::endl;
    oss << "DisableAllFractionalCheckForHighRes = " << std::dec << +m_avcPar->DisableAllFractionalCheckForHighRes << std::endl;
    oss << "MaxLenSP = " << std::dec << +m_avcPar->MaxLenSP << std::endl;

    // PAK Params
    oss << "TrellisQuantizationEnable = " << std::dec << +m_avcPar->TrellisQuantizationEnable << std::endl;
    oss << "RoundingIntraEnabled = " << std::dec << +m_avcPar->RoundingIntraEnabled << std::endl;
    oss << "RoundingIntra = " << std::dec << +m_avcPar->RoundingIntra << std::endl;
    oss << "EnableAdaptiveTrellisQuantization = " << std::dec << +m_avcPar->EnableAdaptiveTrellisQuantization << std::endl;
    oss << "TrellisQuantizationRounding = " << std::dec << +m_avcPar->TrellisQuantizationRounding << std::endl;
    oss << "TrellisQuantizationChromaDisable = " << std::dec << +m_avcPar->TrellisQuantizationChromaDisable << std::endl;
    oss << "ExtendedRhoDomainEn = " << std::dec << +m_avcPar->ExtendedRhoDomainEn << std::endl;
    oss << "EnableSEI = " << std::dec << +m_avcPar->EnableSEI << std::endl;
    if (m_avcPar->NumP == 0)  // There's no P frame
    {
        oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
    }

    if (m_avcPar->NumP > 0)
    {
        // P Slice Parameters
        // DDI Params
        oss << "PSliceQP = " << std::dec << +m_avcPar->PSliceQP << std::endl;
        oss << "CabacInitIDC = " << std::dec << +m_avcPar->CabacInitIDC << std::endl;
        oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
        oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
        if (m_avcPar->NumB == 0)  // There's no B frame
        {
            oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl;
        }
        oss << "WeightedPred = " << std::dec << +m_avcPar->WeightedPred << std::endl;
        oss << "UseOrigAsRef = " << std::dec << +m_avcPar->UseOrigAsRef << std::endl;
        oss << "BiSubMbPartMask = " << std::dec << +m_avcPar->BiSubMbPartMask << std::endl;

        // HME Params
        oss << "SuperHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superHME : m_avcPar->SuperHME) << std::endl;
        oss << "UltraHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->ultraHME : m_avcPar->UltraHME) << std::endl;
        oss << "SuperCombineDist = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superCombineDist : m_avcPar->SuperCombineDist) << std::endl;

        // Enc Params
        oss << "SubPelMode = " << std::dec << +m_avcPar->SubPelMode << std::endl;
        oss << "FTQBasedSkip = " << std::dec << +m_avcPar->FTQBasedSkip << std::endl;
        oss << "BiMixDisable = " << std::dec << +m_avcPar->BiMixDisable << std::endl;
        oss << "SurvivedSkipCost = " << std::dec << +m_avcPar->SurvivedSkipCost << std::endl;
        oss << "UniMixDisable = " << std::dec << +m_avcPar->UniMixDisable << std::endl;
        oss << "EnableIntraCostScalingForStaticFrame = " << std::dec << +m_avcPar->EnableIntraCostScalingForStaticFrame << std::endl;
        if (m_avcPar->EnableIntraCostScalingForStaticFrame)
        {
            oss << "IntraCostUpdateMethod = 3" << std::endl;
        }
        oss << "StaticFrameIntraCostScalingRatioP = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioP << std::endl;
        oss << "MEMethod = " << std::dec << +m_avcPar->MEMethod << std::endl;
        oss << "HMECombineLen = " << std::dec << +m_avcPar->HMECombineLen << std::endl;
        oss << "HMECombineOverlap = " << std::dec << +m_avcPar->HMECombineOverlap << std::endl;
        oss << "SearchX = " << std::dec << +m_avcPar->SearchX << std::endl;
        oss << "SearchY = " << std::dec << +m_avcPar->SearchY << std::endl;
        oss << "SearchControl = " << std::dec << +m_avcPar->SearchControl << std::endl;
        oss << "MultiplePred = " << std::dec << +m_avcPar->MultiplePred << std::endl;
        oss << "EnableAdaptiveTxDecision = " << std::dec << +m_avcPar->EnableAdaptiveTxDecision << std::endl;
        oss << "MBTextureThreshold = " << std::dec << +m_avcPar->MBTextureThreshold << std::endl;
        oss << "TxDecisionThr = " << std::dec << +m_avcPar->TxDecisionThr << std::endl;
        oss << "EnablePerMBStaticCheck = " << std::dec << +m_avcPar->EnablePerMBStaticCheck << std::endl;
        oss << "EnableAdaptiveSearchWindowSize = " << std::dec << +m_avcPar->EnableAdaptiveSearchWindowSize << std::endl;
        oss << "EnableAdaptiveIntraScaling = " << std::dec << +m_avcPar->EnableAdaptiveIntraScaling << std::endl;

        // BRC Frame Update
        oss << "UserMaxFrame_P = " << std::dec << +m_avcPar->UserMaxFrameP << std::endl;

        // PAK Params
        oss << "RoundingInterEnabled = " << std::dec << +m_avcPar->RoundingInterEnabled << std::endl;
        oss << "RoundingInter = " << std::dec << +m_avcPar->RoundingInter << std::endl;
        oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
        oss << "EnableAdaptiveRounding = " << std::dec << +m_avcPar->EnableAdaptiveRounding << std::endl;
    }

    if (m_avcPar->NumB > 0)
    {
        // B Slice Parameters
        // DDI Params
        oss << "BSliceQP = " << std::dec << +m_avcPar->BSliceQP << std::endl;
        oss << "MaxBRefIdxL0 = " << std::dec << +m_avcPar->MaxBRefIdxL0 << std::endl;
        oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl;
        oss << "WeightedBiPred = " << std::dec << +m_avcPar->WeightedBiPred << std::endl;

        // Enc Params
        oss << "BMEMethod = " << std::dec << +m_avcPar->BMEMethod << std::endl;
        oss << "HMEBCombineLen = " << std::dec << +m_avcPar->HMEBCombineLen << std::endl;
        oss << "BSearchX = " << std::dec << +m_avcPar->BSearchX << std::endl;
        oss << "BSearchY = " << std::dec << +m_avcPar->BSearchY << std::endl;
        oss << "BSearchControl = " << std::dec << +m_avcPar->BSearchControl << std::endl;
        oss << "BSkipType = " << std::dec << +m_avcPar->BSkipType << std::endl;
        oss << "DirectMode = " << std::dec << +m_avcPar->DirectMode << std::endl;
        oss << "BiWeight = " << std::dec << +m_avcPar->BiWeight << std::endl;
        oss << "StaticFrameIntraCostScalingRatioB = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioB << std::endl;

        // PAK Params
        oss << "RoundingInterB = " << std::dec << +m_avcPar->RoundingInterB << std::endl;
    }

    const char *fileName = m_debugInterface->CreateFileName(
        "EncodeSequence",
        "EncodePar",
        CodechalDbgExtType::par);

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

    return MOS_STATUS_SUCCESS;
}
#endif
