text: ﻿/*
  * 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"
  
  #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;
      }
  }
  
  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));
      )
  
      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));
  
          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;
      }
  
      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;
  
          CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->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));
  
      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));
  
          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));
      )
  
      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);
      }
  
      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;
  
      if (picParams != nullptr)
      {
          forceRepartitionCheck = (CODECHAL_ENCODE_AVC_RPC)picParams->ForceRepartitionCheck;
      }
      else
      {
          forceRepartitionCheck = CODECHAL_ENCODE_RPC_FOLLOW_DRIVER;
      }
  
      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);
      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<(m_avcPicParam->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);
              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);
          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));
  
      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;
          MOS_RESOURCE                                    globalGpuContextSyncTagBuffer;
          uint32_t                                           value;
  
          CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource(
              m_osInterface,
              &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.ucCurrPass = 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
      // if(GFX_IS_RENDERCORE(m_hwInterface->GetPlatform(), IGFX_GEN8_CORE)) //WA for G8
      // {
      //     eStatus = pEncoder->pfnResetStatusReport(pEncoder);
      // }
      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
  