/*
* Copyright (c) 2017, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file     codechal_encode_hevc_base.h
//! \brief    Defines base class for HEVC encoder.
//!

#ifndef __CODECHAL_ENCODE_HEVC_BASE_H__
#define __CODECHAL_ENCODE_HEVC_BASE_H__

#include "codechal_encoder_base.h"

#if USE_CODECHAL_DEBUG_TOOL
#include "codechal_debug_encode_par.h"
#endif

//*------------------------------------------------------------------------------
//* Codec Definitions
//*------------------------------------------------------------------------------
#define CODECHAL_HEVC_MAX_SPS_NUM       16
#define CODECHAL_HEVC_MAX_PPS_NUM       64
#define CODECHAL_VDENC_HEVC_MAX_SLICE_NUM   70

#define CODECHAL_HEVC_MAX_LCU_SIZE_G9          32
#define CODECHAL_HEVC_MIN_LCU_SIZE             16
#define CODECHAL_HEVC_MIN_CU_SIZE              8
#define CODECHAL_HEVC_MIN_TILE_SIZE            128
#define CODECHAL_HEVC_FRAME_BRC_BLOCK_SIZE     32
#define CODECHAL_HEVC_LCU_BRC_BLOCK_SIZE       128

#define CODECHAL_ENCODE_HEVC_NUM_MAX_VME_L0_REF_G9  3
#define CODECHAL_ENCODE_HEVC_NUM_MAX_VME_L1_REF_G9  1

#define CODECHAL_ENCODE_HEVC_NUM_MAX_VME_L0_REF_G10 4
#define CODECHAL_ENCODE_HEVC_NUM_MAX_VME_L1_REF_G10 4

#define CODECHAL_ENCODE_HEVC_MAX_NUM_WEIGHTED_PRED_L0 1
#define CODECHAL_ENCODE_HEVC_MAX_NUM_WEIGHTED_PRED_L1 1

#define CODECHAL_HEVC_MAX_NUM_HCP_PIPE      8
#define CODECHAL_HEVC_MAX_NUM_BRC_PASSES    4 // It doesn't include the 5th PAK pass for the BRC panic mode

#define ENCODE_HEVC_4K_PIC_WIDTH     3840
#define ENCODE_HEVC_4K_PIC_HEIGHT    2160

#define ENCODE_HEVC_5K_PIC_WIDTH     5120
#define ENCODE_HEVC_5K_PIC_HEIGHT    2880

#define ENCODE_HEVC_8K_PIC_WIDTH     7680
#define ENCODE_HEVC_8K_PIC_HEIGHT    4320

#define ENCODE_HEVC_16K_PIC_WIDTH    16384
#define ENCODE_HEVC_16K_PIC_HEIGHT   4096

// Max supported resolution for HEVC encode is 4K X 2K
#define ENCODE_HEVC_MAX_4K_PIC_WIDTH     4096
#define ENCODE_HEVC_MAX_4K_PIC_HEIGHT    2176

#define ENCODE_HEVC_MAX_8K_PIC_WIDTH     8192
#define ENCODE_HEVC_MAX_8K_PIC_HEIGHT    8192

#define ENCODE_HEVC_MAX_16K_PIC_WIDTH    16384
#define ENCODE_HEVC_MAX_16K_PIC_HEIGHT   16384

#define ENCODE_HEVC_MIN_DSS_PIC_WIDTH    480
#define ENCODE_HEVC_MIN_DSS_PIC_HEIGHT   320

// HEVC has only 3 target usage modes
#define CODECHAL_ENCODE_HEVC_TARGET_USAGE_MODE_PERFORMANCE  0
#define CODECHAL_ENCODE_HEVC_TARGET_USAGE_MODE_NORMAL       1
#define CODECHAL_ENCODE_HEVC_TARGET_USAGE_MODE_QUALITY      2

#define HEVC_BRC_CONSTANT_SURFACE_WIDTH_G9          (64)
#define HEVC_BRC_CONSTANT_SURFACE_HEIGHT_G9         (53)
#define HEVC_BRC_HISTORY_BUFFER_SIZE_G9             (576)
#define HEVC_BRC_HISTORY_BUFFER_SIZE_G10            (832)
#define HEVC_BRC_HISTORY_BUFFER_SIZE_G12            (1088)
#define HEVC_BRC_CONSTANT_SURFACE_HEIGHT_G10        (35)

#define CODECHAL_HEVC_NUM_PAK_SLICE_BATCH_BUFFERS   (3)
#define HEVC_CONCURRENT_SURFACE_HEIGHT              (32)
#define HEVC_BRC_SKIP_VAL_TABLE_SIZE                (128)
#define HEVC_BRC_LAMBDA_TABLE_SIZE                  (1024)
#define HEVC_BRC_MVMODE_TABLE_SIZE                  (1664)
#define CODECHAL_INIT_DSH_SIZE_HEVC_ENC             (MHW_PAGE_SIZE * 2)
#define HEVC_START_CODE_NAL_OFFSET                  (2)
#define HEVC_PAK_STATISTICS_SSE_OFFSET              (32)

#define CODECHAL_ENCODE_HEVC_MAX_SLICE_QP               51

#define CODECHAL_ENCODE_HEVC_MIN_ICQ_QUALITYFACTOR      1
#define CODECHAL_ENCODE_HEVC_MAX_ICQ_QUALITYFACTOR      51

#define CODECHAL_ENCODE_HEVC_NUM_SYNC_TAGS              36

#define CODECHAL_ENCODE_HEVC_DEFAULT_AVBR_ACCURACY      30
#define CODECHAL_ENCODE_HEVC_DEFAULT_AVBR_CONVERGENCE   150

// Hevc always uses maxMvLen corresponding to AVC level 51. Refer GetMaxMvLen from AVC.
#define CODECHAL_ENCODE_HEVC_MAX_MV_LEN_AVC_LEVEL_51    511

#define CODECHAL_ENCODE_HEVC_GET_SIZE_IN_LCU(var, lcu_size)         \
    ((var + (lcu_size - 1)) / lcu_size)

#define CODECHAL_HEVC_PAK_STREAMOUT_SIZE 0x500000  //size is accounted for 4Kx4K with all 8x8 CU,based on streamout0 and streamout1 requirements
//(4096*4096)/64 *16 (streamout0) + 1MB(streamout 1). there is scope to reduce streamout1 size. Need to check with HW team.
// 8K is just an estimation
#define CODECHAL_HEVC_BRC_QP_ADJUST_SIZE    576

#define CODECHAL_ENCODE_HEVC_NUM_MAX_VDENC_L0_REF_G10  3 // multiref, hevc vdenc
#define CODECHAL_ENCODE_HEVC_NUM_MAX_VDENC_L1_REF_G10  3 // multiref, hevc vdenc

#define CODECHAL_VDENC_HEVC_BRC_DEBUG_BUF_SIZE               0x1000 // 0x1000 = 4096
#define CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_ERROR_MASK        (1<<30)
#define CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_ARITHMETIC_OVERFLOW_ERROR_MASK   (1<<29)
#define CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_MEMORY_ACCESS_ERROR_MASK         (1<<28)
#define CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_HISTORY_BUFFER_ERROR_MASK        (1<<27)
#define CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_DMEM_ERROR_MASK                  (1<<26)

#define CODECHAL_VDENC_HEVC_BRC_PAK_STATS_BUF_SIZE                  464     // 116 DWORDs HEVC Frame Statistics

const char QPcTable[22] = { 29, 30, 31, 32, 32, 33, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39 };

const unsigned char g_cInit_HEVC_BRC_QP_ADJUST[CODECHAL_HEVC_BRC_QP_ADJUST_SIZE] = {
    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 uint16_t SLCSZ_THRDELTAI_U16[52] =
{   //assuming Mb lag = 8
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[0-9]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[10-19]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[20-29]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[30-39]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[40-49]
    100, 100                                            //[50-51]
};

const uint16_t SLCSZ_THRDELTAP_U16[52] =
{   //assuming Mb lag = 6
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[0-9]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[10-19]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[20-29]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[30-39]
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100,   //[40-49]
    100, 100                                            //[50-51]
};

enum
{
    // 2x down-scaling kernel
    CODECHAL_HEVC_SCALING_FRAME_BEGIN = 0,
    CODECHAL_HEVC_SCALING_FRAME_SRC_Y = CODECHAL_HEVC_SCALING_FRAME_BEGIN + 0,
    CODECHAL_HEVC_SCALING_FRAME_DST_Y = CODECHAL_HEVC_SCALING_FRAME_BEGIN + 1,
    CODECHAL_HEVC_SCALING_FRAME_END = CODECHAL_HEVC_SCALING_FRAME_BEGIN + 2,

    // 32x32 PU mode decision kernel
    CODECHAL_HEVC_32x32_PU_BEGIN = CODECHAL_HEVC_SCALING_FRAME_END,
    CODECHAL_HEVC_32x32_PU_OUTPUT = CODECHAL_HEVC_32x32_PU_BEGIN + 0,
    CODECHAL_HEVC_32x32_PU_SRC_Y = CODECHAL_HEVC_32x32_PU_BEGIN + 1,
    CODECHAL_HEVC_32x32_PU_SRC_UV = CODECHAL_HEVC_32x32_PU_BEGIN + 2,
    CODECHAL_HEVC_32x32_PU_SRC_Y2x = CODECHAL_HEVC_32x32_PU_BEGIN + 3,
    CODECHAL_HEVC_32x32_PU_SLICE_MAP = CODECHAL_HEVC_32x32_PU_BEGIN + 4,
    CODECHAL_HEVC_32x32_PU_SRC_Y2x_VME = CODECHAL_HEVC_32x32_PU_BEGIN + 5,
    CODECHAL_HEVC_32x32_PU_BRC_Input = CODECHAL_HEVC_32x32_PU_BEGIN + 6,
    CODECHAL_HEVC_32x32_PU_LCU_QP = CODECHAL_HEVC_32x32_PU_BEGIN + 7,
    CODECHAL_HEVC_32x32_PU_BRC_DATA = CODECHAL_HEVC_32x32_PU_BEGIN + 8,
    CODECHAL_HEVC_32x32_PU_STATS_DATA = CODECHAL_HEVC_32x32_PU_BEGIN + 9,
    CODECHAL_HEVC_32x32_PU_DEBUG = CODECHAL_HEVC_32x32_PU_BEGIN + 10,
    CODECHAL_HEVC_32x32_PU_END = CODECHAL_HEVC_32x32_PU_BEGIN + 11,

    // 16x16 SAD computation kernel
    CODECHAL_HEVC_16x16_PU_SAD_BEGIN = CODECHAL_HEVC_32x32_PU_END,
    CODECHAL_HEVC_16x16_PU_SAD_SRC_Y = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 0,
    CODECHAL_HEVC_16x16_PU_SAD_SRC_UV = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 1,
    CODECHAL_HEVC_16x16_PU_SAD_OUTPUT = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 2,
    CODECHAL_HEVC_16x16_PU_SAD_32x32_MD_DATA = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 3,
    CODECHAL_HEVC_16x16_PU_SLICE_MAP = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 4,
    CODECHAL_HEVC_16x16_PU_Simplest_Intra = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 5,
    CODECHAL_HEVC_16x16_PU_SAD_DEBUG = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 6,
    CODECHAL_HEVC_16x16_PU_SAD_END = CODECHAL_HEVC_16x16_PU_SAD_BEGIN + 7,

    // 16x16 PU mode decision kernel
    CODECHAL_HEVC_16x16_PU_MD_BEGIN = CODECHAL_HEVC_16x16_PU_SAD_END,
    CODECHAL_HEVC_16x16_PU_MD_SRC_Y = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 0,
    CODECHAL_HEVC_16x16_PU_MD_SRC_UV = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 1,
    CODECHAL_HEVC_16x16_PU_MD_16x16_SAD_DATA = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 2,
    CODECHAL_HEVC_16x16_PU_MD_PAK_OBJ = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 3,
    CODECHAL_HEVC_16x16_PU_MD_32x32_MD_DATA = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 4,
    CODECHAL_HEVC_16x16_PU_MD_VME_8x8_MD_DATA = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 5,
    CODECHAL_HEVC_16x16_PU_MD_SLICE_MAP = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 6,
    CODECHAL_HEVC_16x16_PU_MD_VME_SRC = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 7,
    CODECHAL_HEVC_16x16_PU_MD_BRC_Input = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 8,
    CODECHAL_HEVC_16x16_PU_MD_Simplest_Intra = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 9,
    CODECHAL_HEVC_16x16_PU_MD_LCU_QP = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 10,
    CODECHAL_HEVC_16x16_PU_MD_BRC_Data = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 11,
    CODECHAL_HEVC_16x16_PU_MD_DEBUG = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 12,
    CODECHAL_HEVC_16x16_PU_MD_END = CODECHAL_HEVC_16x16_PU_MD_BEGIN + 13,

    // 8x8 PU kernel
    CODECHAL_HEVC_8x8_PU_BEGIN = CODECHAL_HEVC_16x16_PU_MD_END,
    CODECHAL_HEVC_8x8_PU_SRC_Y = CODECHAL_HEVC_8x8_PU_BEGIN + 0,
    CODECHAL_HEVC_8x8_PU_SRC_UV = CODECHAL_HEVC_8x8_PU_BEGIN + 1,
    CODECHAL_HEVC_8x8_PU_SLICE_MAP = CODECHAL_HEVC_8x8_PU_BEGIN + 2,
    CODECHAL_HEVC_8x8_PU_VME_8x8_MODE = CODECHAL_HEVC_8x8_PU_BEGIN + 3,
    CODECHAL_HEVC_8x8_PU_INTRA_MODE = CODECHAL_HEVC_8x8_PU_BEGIN + 4,
    CODECHAL_HEVC_8x8_PU_BRC_Input = CODECHAL_HEVC_8x8_PU_BEGIN + 5,
    CODECHAL_HEVC_8x8_PU_Simplest_Intra = CODECHAL_HEVC_8x8_PU_BEGIN + 6,
    CODECHAL_HEVC_8x8_PU_LCU_QP = CODECHAL_HEVC_8x8_PU_BEGIN + 7,
    CODECHAL_HEVC_8x8_PU_BRC_Data = CODECHAL_HEVC_8x8_PU_BEGIN + 8,
    CODECHAL_HEVC_8x8_PU_DEBUG = CODECHAL_HEVC_8x8_PU_BEGIN + 9,
    CODECHAL_HEVC_8x8_PU_END = CODECHAL_HEVC_8x8_PU_BEGIN + 10,

    // 8x8 PU FMODE kernel
    CODECHAL_HEVC_8x8_PU_FMODE_BEGIN = CODECHAL_HEVC_8x8_PU_END,
    CODECHAL_HEVC_8x8_PU_FMODE_PAK_OBJECT = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 0,
    CODECHAL_HEVC_8x8_PU_FMODE_VME_8x8_MODE = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 1,
    CODECHAL_HEVC_8x8_PU_FMODE_INTRA_MODE = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 2,
    CODECHAL_HEVC_8x8_PU_FMODE_PAK_COMMAND = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 3,
    CODECHAL_HEVC_8x8_PU_FMODE_SLICE_MAP = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 4,
    CODECHAL_HEVC_8x8_PU_FMODE_INTRADIST = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 5,
    CODECHAL_HEVC_8x8_PU_FMODE_BRC_Input = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 6,
    CODECHAL_HEVC_8x8_PU_FMODE_Simplest_Intra = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 7,
    CODECHAL_HEVC_8x8_PU_FMODE_LCU_QP = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 8,
    CODECHAL_HEVC_8x8_PU_FMODE_BRC_Data = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 9,
    CODECHAL_HEVC_8x8_PU_FMODE_HAAR_DIST16x16 = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 10,
    CODECHAL_HEVC_8x8_PU_FMODE_STATS_DATA = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 11,
    CODECHAL_HEVC_8x8_PU_FMODE_FRAME_STATS_DATA = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 12,
    CODECHAL_HEVC_8x8_PU_FMODE_DEBUG = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 13,
    CODECHAL_HEVC_8x8_PU_FMODE_END = CODECHAL_HEVC_8x8_PU_FMODE_BEGIN + 14,

    // B 32x32 PU intra check kernel
    CODECHAL_HEVC_B_32x32_PU_BEGIN = CODECHAL_HEVC_8x8_PU_FMODE_END,
    CODECHAL_HEVC_B_32x32_PU_OUTPUT = CODECHAL_HEVC_B_32x32_PU_BEGIN + 0,
    CODECHAL_HEVC_B_32x32_PU_SRC_Y = CODECHAL_HEVC_B_32x32_PU_BEGIN + 1,
    CODECHAL_HEVC_B_32x32_PU_SRC_UV = CODECHAL_HEVC_B_32x32_PU_BEGIN + 2,
    CODECHAL_HEVC_B_32x32_PU_SRC_Y2x = CODECHAL_HEVC_B_32x32_PU_BEGIN + 3,
    CODECHAL_HEVC_B_32x32_PU_SLICE_MAP = CODECHAL_HEVC_B_32x32_PU_BEGIN + 4,
    CODECHAL_HEVC_B_32x32_PU_SRC_Y2x_VME = CODECHAL_HEVC_B_32x32_PU_BEGIN + 5,
    CODECHAL_HEVC_B_32x32_PU_Simplest_Intra = CODECHAL_HEVC_B_32x32_PU_BEGIN + 6,
    CODECHAL_HEVC_B_32x32_PU_HME_MVP = CODECHAL_HEVC_B_32x32_PU_BEGIN + 7,
    CODECHAL_HEVC_B_32x32_PU_HME_DIST = CODECHAL_HEVC_B_32x32_PU_BEGIN + 8,
    CODECHAL_HEVC_B_32x32_PU_LCU_SKIP = CODECHAL_HEVC_B_32x32_PU_BEGIN + 9,
    CODECHAL_HEVC_B_32x32_PU_DEBUG = CODECHAL_HEVC_B_32x32_PU_BEGIN + 10,
    CODECHAL_HEVC_B_32x32_PU_END = CODECHAL_HEVC_B_32x32_PU_BEGIN + 11,

    // B MB ENC kernel
    CODECHAL_HEVC_B_MBENC_BEGIN = CODECHAL_HEVC_B_32x32_PU_END,
    CODECHAL_HEVC_B_MBENC_CU_RECORD = CODECHAL_HEVC_B_MBENC_BEGIN + 0,
    CODECHAL_HEVC_B_MBENC_PAK_CMD = CODECHAL_HEVC_B_MBENC_BEGIN + 1,
    CODECHAL_HEVC_B_MBENC_SRC_Y = CODECHAL_HEVC_B_MBENC_BEGIN + 2,
    CODECHAL_HEVC_B_MBENC_SRC_UV = CODECHAL_HEVC_B_MBENC_BEGIN + 3,
    CODECHAL_HEVC_B_MBENC_INTRA_DIST = CODECHAL_HEVC_B_MBENC_BEGIN + 4,
    CODECHAL_HEVC_B_MBENC_MIN_DIST = CODECHAL_HEVC_B_MBENC_BEGIN + 5,
    CODECHAL_HEVC_B_MBENC_HME_MVP = CODECHAL_HEVC_B_MBENC_BEGIN + 6,
    CODECHAL_HEVC_B_MBENC_HME_DIST = CODECHAL_HEVC_B_MBENC_BEGIN + 7,
    CODECHAL_HEVC_B_MBENC_SLICE_MAP = CODECHAL_HEVC_B_MBENC_BEGIN + 8,
    CODECHAL_HEVC_B_MBENC_VME_UNISIC_DATA = CODECHAL_HEVC_B_MBENC_BEGIN + 9,
    CODECHAL_HEVC_B_MBENC_Simplest_Intra = CODECHAL_HEVC_B_MBENC_BEGIN + 10,
    CODECHAL_HEVC_B_MBENC_REF_COLLOC = CODECHAL_HEVC_B_MBENC_BEGIN + 11,
    CODECHAL_HEVC_B_MBENC_Reserved = CODECHAL_HEVC_B_MBENC_BEGIN + 12,
    CODECHAL_HEVC_B_MBENC_BRC_Input = CODECHAL_HEVC_B_MBENC_BEGIN + 13,
    CODECHAL_HEVC_B_MBENC_LCU_QP = CODECHAL_HEVC_B_MBENC_BEGIN + 14,
    CODECHAL_HEVC_B_MBENC_BRC_DATA = CODECHAL_HEVC_B_MBENC_BEGIN + 15,
    //
    CODECHAL_HEVC_B_MBENC_VME_CURRENT = CODECHAL_HEVC_B_MBENC_BEGIN + 16,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_0 = CODECHAL_HEVC_B_MBENC_BEGIN + 17,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_0 = CODECHAL_HEVC_B_MBENC_BEGIN + 18,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_1 = CODECHAL_HEVC_B_MBENC_BEGIN + 19,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_1 = CODECHAL_HEVC_B_MBENC_BEGIN + 20,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_2 = CODECHAL_HEVC_B_MBENC_BEGIN + 21,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_2 = CODECHAL_HEVC_B_MBENC_BEGIN + 22,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_3 = CODECHAL_HEVC_B_MBENC_BEGIN + 23,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_3 = CODECHAL_HEVC_B_MBENC_BEGIN + 24,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_4 = CODECHAL_HEVC_B_MBENC_BEGIN + 25,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_4 = CODECHAL_HEVC_B_MBENC_BEGIN + 26,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_5 = CODECHAL_HEVC_B_MBENC_BEGIN + 27,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_5 = CODECHAL_HEVC_B_MBENC_BEGIN + 28,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_6 = CODECHAL_HEVC_B_MBENC_BEGIN + 29,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_6 = CODECHAL_HEVC_B_MBENC_BEGIN + 30,
    CODECHAL_HEVC_B_MBENC_VME_FORWARD_7 = CODECHAL_HEVC_B_MBENC_BEGIN + 31,
    CODECHAL_HEVC_B_MBENC_VME_BACKWARD_7 = CODECHAL_HEVC_B_MBENC_BEGIN + 32,
    //
    CODECHAL_HEVC_B_MBENC_VME_MUL_CURRENT = CODECHAL_HEVC_B_MBENC_BEGIN + 33,
    CODECHAL_HEVC_B_MBENC_VME_MUL_BACKWARD_0 = CODECHAL_HEVC_B_MBENC_BEGIN + 34,
    CODECHAL_HEVC_B_MBENC_VME_MUL_NOUSE_0 = CODECHAL_HEVC_B_MBENC_BEGIN + 35,
    CODECHAL_HEVC_B_MBENC_VME_MUL_BACKWARD_1 = CODECHAL_HEVC_B_MBENC_BEGIN + 36,
    CODECHAL_HEVC_B_MBENC_VME_MUL_NOUSE_1 = CODECHAL_HEVC_B_MBENC_BEGIN + 37,
    CODECHAL_HEVC_B_MBENC_VME_MUL_BACKWARD_2 = CODECHAL_HEVC_B_MBENC_BEGIN + 38,
    CODECHAL_HEVC_B_MBENC_VME_MUL_NOUSE_2 = CODECHAL_HEVC_B_MBENC_BEGIN + 39,
    CODECHAL_HEVC_B_MBENC_VME_MUL_BACKWARD_3 = CODECHAL_HEVC_B_MBENC_BEGIN + 40,
    CODECHAL_HEVC_B_MBENC_VME_MUL_NOUSE_3 = CODECHAL_HEVC_B_MBENC_BEGIN + 41,
    //
    CODECHAL_HEVC_B_MBENC_CONCURRENT_THD_MAP = CODECHAL_HEVC_B_MBENC_BEGIN + 42,
    CODECHAL_HEVC_B_MBENC_MV_IDX = CODECHAL_HEVC_B_MBENC_BEGIN + 43,
    CODECHAL_HEVC_B_MBENC_MVP_IDX = CODECHAL_HEVC_B_MBENC_BEGIN + 44,
    CODECHAL_HEVC_B_MBENC_HAAR_DIST16x16 = CODECHAL_HEVC_B_MBENC_BEGIN + 45,
    CODECHAL_HEVC_B_MBENC_STATS_DATA = CODECHAL_HEVC_B_MBENC_BEGIN + 46,
    CODECHAL_HEVC_B_MBENC_FRAME_STATS_DATA = CODECHAL_HEVC_B_MBENC_BEGIN + 47,
    CODECHAL_HEVC_B_MBENC_DEBUG = CODECHAL_HEVC_B_MBENC_BEGIN + 48,
    //
    CODECHAL_HEVC_B_MBENC_END = CODECHAL_HEVC_B_MBENC_BEGIN + 49,

    //Coarse Intra distortion
    CODECHAL_HEVC_COARSE_INTRA_BEGIN = CODECHAL_HEVC_B_MBENC_END,
    CODECHAL_HEVC_COARSE_INTRA_Y4 = CODECHAL_HEVC_COARSE_INTRA_BEGIN + 0,
    CODECHAL_HEVC_COARSE_INTRA_DISTORTION = CODECHAL_HEVC_COARSE_INTRA_BEGIN + 1,
    CODECHAL_HEVC_COARSE_INTRA_VME_Y4 = CODECHAL_HEVC_COARSE_INTRA_BEGIN + 2,
    CODECHAL_HEVC_COARSE_INTRA_END = CODECHAL_HEVC_COARSE_INTRA_BEGIN + 3,

    // HEVC B PAK kernel
    CODECHAL_HEVC_B_PAK_BEGIN = CODECHAL_HEVC_COARSE_INTRA_END,
    CODECHAL_HEVC_B_PAK_CU_RECORD = CODECHAL_HEVC_B_PAK_BEGIN + 0,
    CODECHAL_HEVC_B_PAK_PAK_OBJ = CODECHAL_HEVC_B_PAK_BEGIN + 1,
    CODECHAL_HEVC_B_PAK_SLICE_MAP = CODECHAL_HEVC_B_PAK_BEGIN + 2,
    CODECHAL_HEVC_B_PAK_BRC_INPUT = CODECHAL_HEVC_B_PAK_BEGIN + 3,
    CODECHAL_HEVC_B_PAK_LCU_QP = CODECHAL_HEVC_B_PAK_BEGIN + 4,
    CODECHAL_HEVC_B_PAK_BRC_DATA = CODECHAL_HEVC_B_PAK_BEGIN + 5,
    CODECHAL_HEVC_B_PAK_MB_DATA = CODECHAL_HEVC_B_PAK_BEGIN + 6,
    CODECHAL_HEVC_B_PAK_MVP_DATA = CODECHAL_HEVC_B_PAK_BEGIN + 7,
    CODECHAL_HEVC_B_PAK_WA_PAK_DATA = CODECHAL_HEVC_B_PAK_BEGIN + 8,
    CODECHAL_HEVC_B_PAK_WA_PAK_OBJ = CODECHAL_HEVC_B_PAK_BEGIN + 9,
    CODECHAL_HEVC_B_PAK_DEBUG = CODECHAL_HEVC_B_PAK_BEGIN + 10,
    CODECHAL_HEVC_B_PAK_END = CODECHAL_HEVC_B_PAK_BEGIN + 11,

    //HEVC FORMAT CONVERSION AND DOWNSCALING KERNEL
    CODECHAL_HEVC_DS_COMBINED_BEGIN = CODECHAL_HEVC_B_PAK_END,
    CODECHAL_HEVC_DS_COMBINED_10BIT_Y = CODECHAL_HEVC_DS_COMBINED_BEGIN + 0,
    CODECHAL_HEVC_DS_COMBINED_10BIT_UV = CODECHAL_HEVC_DS_COMBINED_BEGIN + 1,
    CODECHAL_HEVC_DS_COMBINED_8BIT_Y = CODECHAL_HEVC_DS_COMBINED_BEGIN + 2,
    CODECHAL_HEVC_DS_COMBINED_8BIT_UV = CODECHAL_HEVC_DS_COMBINED_BEGIN + 3,
    CODECHAL_HEVC_DS_COMBINED_4xDOWNSCALE = CODECHAL_HEVC_DS_COMBINED_BEGIN + 4,
    CODECHAL_HEVC_DS_COMBINED_MB_STATS = CODECHAL_HEVC_DS_COMBINED_BEGIN + 5,
    CODECHAL_HEVC_DS_COMBINED_2xDOWNSCALE = CODECHAL_HEVC_DS_COMBINED_BEGIN + 6,
    CODECHAL_HEVC_DS_COMBINED_END = CODECHAL_HEVC_DS_COMBINED_BEGIN + 7,

    //BRC Init/Reset
    CODECHAL_HEVC_BRC_INIT_RESET_BEGIN = CODECHAL_HEVC_DS_COMBINED_END,
    CODECHAL_HEVC_BRC_INIT_RESET_HISTORY = CODECHAL_HEVC_BRC_INIT_RESET_BEGIN + 0,
    CODECHAL_HEVC_BRC_INIT_RESET_DISTORTION = CODECHAL_HEVC_BRC_INIT_RESET_BEGIN + 1,
    CODECHAL_HEVC_BRC_INIT_RESET_END = CODECHAL_HEVC_BRC_INIT_RESET_BEGIN + 2,

    //BRC Update (frame based)
    CODECHAL_HEVC_BRC_UPDATE_BEGIN = CODECHAL_HEVC_BRC_INIT_RESET_END,
    CODECHAL_HEVC_BRC_UPDATE_HISTORY = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 0,
    CODECHAL_HEVC_BRC_UPDATE_PREV_PAK = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 1,
    CODECHAL_HEVC_BRC_UPDATE_PIC_STATE_R = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 2,
    CODECHAL_HEVC_BRC_UPDATE_PIC_STATE_W = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 3,
    CODECHAL_HEVC_BRC_UPDATE_ENC_OUTPUT = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 4,
    CODECHAL_HEVC_BRC_UPDATE_DISTORTION = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 5,
    CODECHAL_HEVC_BRC_UPDATE_BRCDATA = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 6,
    CODECHAL_HEVC_BRC_UPDATE_END = CODECHAL_HEVC_BRC_UPDATE_BEGIN + 7,

    //BRC Update (LCU-based)
    CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN = CODECHAL_HEVC_BRC_UPDATE_END,
    CODECHAL_HEVC_BRC_LCU_UPDATE_HISTORY = CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN + 0,
    CODECHAL_HEVC_BRC_LCU_UPDATE_HME_DISTORTION = CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN + 1,
    CODECHAL_HEVC_BRC_LCU_UPDATE_INTRA_DISTORTION = CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN + 2,
    CODECHAL_HEVC_BRC_LCU_UPDATE_HME_MVP = CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN + 3,
    CODECHAL_HEVC_BRC_LCU_UPDATE_LCU_QP = CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN + 4,
    CODECHAL_HEVC_BRC_LCU_UPDATE_ROI = CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN + 5,
    CODECHAL_HEVC_BRC_LCU_UPDATE_END = CODECHAL_HEVC_BRC_LCU_UPDATE_BEGIN + 6,

    // P MB ENC kernel
    CODECHAL_HEVC_P_MBENC_BEGIN = CODECHAL_HEVC_BRC_LCU_UPDATE_END,
    CODECHAL_HEVC_P_MBENC_CU_RECORD = CODECHAL_HEVC_P_MBENC_BEGIN + 0,
    CODECHAL_HEVC_P_MBENC_PAK_CMD = CODECHAL_HEVC_P_MBENC_BEGIN + 1,
    CODECHAL_HEVC_P_MBENC_SRC_Y = CODECHAL_HEVC_P_MBENC_BEGIN + 2,
    CODECHAL_HEVC_P_MBENC_SRC_UV = CODECHAL_HEVC_P_MBENC_BEGIN + 3,
    CODECHAL_HEVC_P_MBENC_INTRA_DIST = CODECHAL_HEVC_P_MBENC_BEGIN + 4,
    CODECHAL_HEVC_P_MBENC_MIN_DIST = CODECHAL_HEVC_P_MBENC_BEGIN + 5,
    CODECHAL_HEVC_P_MBENC_HME_MVP = CODECHAL_HEVC_P_MBENC_BEGIN + 6,
    CODECHAL_HEVC_P_MBENC_HME_DIST = CODECHAL_HEVC_P_MBENC_BEGIN + 7,
    CODECHAL_HEVC_P_MBENC_SLICE_MAP = CODECHAL_HEVC_P_MBENC_BEGIN + 8,
    CODECHAL_HEVC_P_MBENC_VME_UNISIC_DATA = CODECHAL_HEVC_P_MBENC_BEGIN + 9,
    CODECHAL_HEVC_P_MBENC_Simplest_Intra = CODECHAL_HEVC_P_MBENC_BEGIN + 10,
    CODECHAL_HEVC_P_MBENC_REF_COLLOC = CODECHAL_HEVC_P_MBENC_BEGIN + 11,
    CODECHAL_HEVC_P_MBENC_Reserved = CODECHAL_HEVC_P_MBENC_BEGIN + 12,
    CODECHAL_HEVC_P_MBENC_BRC_Input = CODECHAL_HEVC_P_MBENC_BEGIN + 13,
    CODECHAL_HEVC_P_MBENC_LCU_QP = CODECHAL_HEVC_P_MBENC_BEGIN + 14,
    CODECHAL_HEVC_P_MBENC_BRC_DATA = CODECHAL_HEVC_P_MBENC_BEGIN + 15,
    //
    CODECHAL_HEVC_P_MBENC_VME_CURRENT = CODECHAL_HEVC_P_MBENC_BEGIN + 16,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_0 = CODECHAL_HEVC_P_MBENC_BEGIN + 17,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_1 = CODECHAL_HEVC_P_MBENC_BEGIN + 19,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_2 = CODECHAL_HEVC_P_MBENC_BEGIN + 21,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_3 = CODECHAL_HEVC_P_MBENC_BEGIN + 23,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_4 = CODECHAL_HEVC_P_MBENC_BEGIN + 25,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_5 = CODECHAL_HEVC_P_MBENC_BEGIN + 27,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_6 = CODECHAL_HEVC_P_MBENC_BEGIN + 29,
    CODECHAL_HEVC_P_MBENC_VME_FORWARD_7 = CODECHAL_HEVC_P_MBENC_BEGIN + 31,

    //
    CODECHAL_HEVC_P_MBENC_CONCURRENT_THD_MAP = CODECHAL_HEVC_P_MBENC_BEGIN + 33,
    CODECHAL_HEVC_P_MBENC_MV_IDX = CODECHAL_HEVC_P_MBENC_BEGIN + 34,
    CODECHAL_HEVC_P_MBENC_MVP_IDX = CODECHAL_HEVC_P_MBENC_BEGIN + 35,
    CODECHAL_HEVC_P_MBENC_DEBUG = CODECHAL_HEVC_P_MBENC_BEGIN + 36,
    //
    CODECHAL_HEVC_P_MBENC_END = CODECHAL_HEVC_P_MBENC_BEGIN + 37,

    CODECHAL_HEVC_NUM_SURFACES = CODECHAL_HEVC_P_MBENC_END
};

enum
{
    // 2x down-scaling kernel
    CODECHAL_HEVC_FEI_SCALING_FRAME_BEGIN = 0,
    CODECHAL_HEVC_FEI_SCALING_FRAME_SRC_Y = CODECHAL_HEVC_FEI_SCALING_FRAME_BEGIN + 0,
    CODECHAL_HEVC_FEI_SCALING_FRAME_DST_Y = CODECHAL_HEVC_FEI_SCALING_FRAME_BEGIN + 1,
    CODECHAL_HEVC_FEI_SCALING_FRAME_END = CODECHAL_HEVC_FEI_SCALING_FRAME_BEGIN + 2,

    // 32x32 PU mode decision kernel
    CODECHAL_HEVC_FEI_32x32_PU_BEGIN = CODECHAL_HEVC_FEI_SCALING_FRAME_END,
    CODECHAL_HEVC_FEI_32x32_PU_OUTPUT = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 0,
    CODECHAL_HEVC_FEI_32x32_PU_SRC_Y = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 1,
    CODECHAL_HEVC_FEI_32x32_PU_SRC_UV = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 2,
    CODECHAL_HEVC_FEI_32x32_PU_SRC_Y2x = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 3,
    CODECHAL_HEVC_FEI_32x32_PU_SLICE_MAP = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 4,
    CODECHAL_HEVC_FEI_32x32_PU_SRC_Y2x_VME = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 5,
    CODECHAL_HEVC_FEI_32x32_PU_BRC_Input = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 6,
    CODECHAL_HEVC_FEI_32x32_PU_LCU_QP = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 7,
    CODECHAL_HEVC_FEI_32x32_PU_BRC_DATA = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 8,
    CODECHAL_HEVC_FEI_32x32_PU_STATS_DATA = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 9,
    CODECHAL_HEVC_FEI_32x32_PU_DEBUG = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 10,
    CODECHAL_HEVC_FEI_32x32_PU_END = CODECHAL_HEVC_FEI_32x32_PU_BEGIN + 11,

    // 16x16 SAD computation kernel
    CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN = CODECHAL_HEVC_FEI_32x32_PU_END,
    CODECHAL_HEVC_FEI_16x16_PU_SAD_SRC_Y = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 0,
    CODECHAL_HEVC_FEI_16x16_PU_SAD_SRC_UV = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 1,
    CODECHAL_HEVC_FEI_16x16_PU_SAD_OUTPUT = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 2,
    CODECHAL_HEVC_FEI_16x16_PU_SAD_32x32_MD_DATA = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 3,
    CODECHAL_HEVC_FEI_16x16_PU_SLICE_MAP = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 4,
    CODECHAL_HEVC_FEI_16x16_PU_Simplest_Intra = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 5,
    CODECHAL_HEVC_FEI_16x16_PU_SAD_DEBUG = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 6,
    CODECHAL_HEVC_FEI_16x16_PU_SAD_END = CODECHAL_HEVC_FEI_16x16_PU_SAD_BEGIN + 7,

    // 16x16 PU mode decision kernel
    CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN = CODECHAL_HEVC_FEI_16x16_PU_SAD_END,
    CODECHAL_HEVC_FEI_16x16_PU_MD_SRC_Y = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 0,
    CODECHAL_HEVC_FEI_16x16_PU_MD_SRC_UV = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 1,
    CODECHAL_HEVC_FEI_16x16_PU_MD_16x16_SAD_DATA = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 2,
    CODECHAL_HEVC_FEI_16x16_PU_MD_PAK_OBJ = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 3,
    CODECHAL_HEVC_FEI_16x16_PU_MD_32x32_MD_DATA = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 4,
    CODECHAL_HEVC_FEI_16x16_PU_MD_VME_8x8_MD_DATA = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 5,
    CODECHAL_HEVC_FEI_16x16_PU_MD_SLICE_MAP = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 6,
    CODECHAL_HEVC_FEI_16x16_PU_MD_VME_SRC = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 7,
    CODECHAL_HEVC_FEI_16x16_PU_MD_BRC_Input = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 8,
    CODECHAL_HEVC_FEI_16x16_PU_MD_Simplest_Intra = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 9,
    CODECHAL_HEVC_FEI_16x16_PU_MD_LCU_QP = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 10,
    CODECHAL_HEVC_FEI_16x16_PU_MD_BRC_Data = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 11,
    CODECHAL_HEVC_FEI_16x16_PU_MD_DEBUG = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 12,
    CODECHAL_HEVC_FEI_16x16_PU_MD_END = CODECHAL_HEVC_FEI_16x16_PU_MD_BEGIN + 13,

    // 8x8 PU kernel
    CODECHAL_HEVC_FEI_8x8_PU_BEGIN = CODECHAL_HEVC_FEI_16x16_PU_MD_END,
    CODECHAL_HEVC_FEI_8x8_PU_SRC_Y = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 0,
    CODECHAL_HEVC_FEI_8x8_PU_SRC_UV = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 1,
    CODECHAL_HEVC_FEI_8x8_PU_SLICE_MAP = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 2,
    CODECHAL_HEVC_FEI_8x8_PU_VME_8x8_MODE = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 3,
    CODECHAL_HEVC_FEI_8x8_PU_INTRA_MODE = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 4,
    CODECHAL_HEVC_FEI_8x8_PU_BRC_Input = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 5,
    CODECHAL_HEVC_FEI_8x8_PU_Simplest_Intra = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 6,
    CODECHAL_HEVC_FEI_8x8_PU_LCU_QP = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 7,
    CODECHAL_HEVC_FEI_8x8_PU_BRC_Data = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 8,
    CODECHAL_HEVC_FEI_8x8_PU_DEBUG = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 9,
    CODECHAL_HEVC_FEI_8x8_PU_END = CODECHAL_HEVC_FEI_8x8_PU_BEGIN + 10,

    // 8x8 PU FMODE kernel
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN = CODECHAL_HEVC_FEI_8x8_PU_END,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_PAK_OBJECT = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 0,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_VME_8x8_MODE = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 1,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_INTRA_MODE = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 2,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_PAK_COMMAND = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 3,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_SLICE_MAP = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 4,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_INTRADIST = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 5,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_BRC_Input = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 6,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_Simplest_Intra = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 7,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_LCU_QP = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 8,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_BRC_Data = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 9,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_HAAR16x16 = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 10,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_STATS_DATA = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 11,
    CODECHAL_HEVC_FEI_8X8_PU_FMODE_FRAME_STATS_DATA = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 12,
    CODECHAL_HEVC_FEI_8X8_PU_FMODE_CTB_DISTORTION = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 13,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_DEBUG = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 14,
    CODECHAL_HEVC_FEI_8x8_PU_FMODE_END = CODECHAL_HEVC_FEI_8x8_PU_FMODE_BEGIN + 15,

    // B 32x32 PU intra check kernel
    CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN = CODECHAL_HEVC_FEI_8x8_PU_FMODE_END,
    CODECHAL_HEVC_FEI_B_32x32_PU_OUTPUT = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 0,
    CODECHAL_HEVC_FEI_B_32x32_PU_SRC_Y = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 1,
    CODECHAL_HEVC_FEI_B_32x32_PU_SRC_UV = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 2,
    CODECHAL_HEVC_FEI_B_32x32_PU_SRC_Y2x = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 3,
    CODECHAL_HEVC_FEI_B_32x32_PU_SLICE_MAP = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 4,
    CODECHAL_HEVC_FEI_B_32x32_PU_SRC_Y2x_VME = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 5,
    CODECHAL_HEVC_FEI_B_32x32_PU_Simplest_Intra = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 6,
    CODECHAL_HEVC_FEI_B_32x32_PU_HME_MVP = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 7,
    CODECHAL_HEVC_FEI_B_32x32_PU_HME_DIST = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 8,
    CODECHAL_HEVC_FEI_B_32x32_PU_LCU_SKIP = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 9,
    CODECHAL_HEVC_FEI_B_32x32_PU_DEBUG = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 10,
    CODECHAL_HEVC_FEI_B_32x32_PU_END = CODECHAL_HEVC_FEI_B_32x32_PU_BEGIN + 11,

    // B MB ENC kernel
    CODECHAL_HEVC_FEI_B_MBENC_BEGIN = CODECHAL_HEVC_FEI_B_32x32_PU_END,
    CODECHAL_HEVC_FEI_B_MBENC_CU_RECORD = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 0,
    CODECHAL_HEVC_FEI_B_MBENC_PAK_CMD = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 1,
    CODECHAL_HEVC_FEI_B_MBENC_SRC_Y = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 2,
    CODECHAL_HEVC_FEI_B_MBENC_SRC_UV = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 3,
    CODECHAL_HEVC_FEI_B_MBENC_INTRA_DIST = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 4,
    CODECHAL_HEVC_FEI_B_MBENC_MIN_DIST = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 5,
    CODECHAL_HEVC_FEI_B_MBENC_HME_MVP = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 6,
    CODECHAL_HEVC_FEI_B_MBENC_HME_DIST = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 7,
    CODECHAL_HEVC_FEI_B_MBENC_SLICE_MAP = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 8,
    CODECHAL_HEVC_FEI_B_MBENC_VME_UNISIC_DATA = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 9,
    CODECHAL_HEVC_FEI_B_MBENC_Simplest_Intra = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 10,
    CODECHAL_HEVC_FEI_B_MBENC_REF_COLLOC = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 11,
    CODECHAL_HEVC_FEI_B_MBENC_Reserved = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 12,
    CODECHAL_HEVC_FEI_B_MBENC_BRC_Input = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 13,
    CODECHAL_HEVC_FEI_B_MBENC_LCU_QP = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 14,
    CODECHAL_HEVC_FEI_B_MBENC_BRC_DATA = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 15,
    //
    CODECHAL_HEVC_FEI_B_MBENC_VME_CURRENT = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 16,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_0 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 17,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_0 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 18,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_1 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 19,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_1 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 20,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_2 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 21,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_2 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 22,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_3 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 23,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_3 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 24,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_4 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 25,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_4 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 26,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_5 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 27,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_5 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 28,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_6 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 29,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_6 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 30,
    CODECHAL_HEVC_FEI_B_MBENC_VME_FORWARD_7 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 31,
    CODECHAL_HEVC_FEI_B_MBENC_VME_BACKWARD_7 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 32,
    //
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_CURRENT = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 33,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_BACKWARD_0 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 34,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_NOUSE_0 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 35,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_BACKWARD_1 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 36,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_NOUSE_1 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 37,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_BACKWARD_2 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 38,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_NOUSE_2 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 39,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_BACKWARD_3 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 40,
    CODECHAL_HEVC_FEI_B_MBENC_VME_MUL_NOUSE_3 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 41,
    //
    CODECHAL_HEVC_FEI_B_MBENC_CONCURRENT_THD_MAP = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 42,
    CODECHAL_HEVC_FEI_B_MBENC_MV_IDX = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 43,
    CODECHAL_HEVC_FEI_B_MBENC_MVP_IDX = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 44,
    CODECHAL_HEVC_FEI_B_MBENC_HAAR_DIST16x16 = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 45,
    CODECHAL_HEVC_FEI_B_MBENC_STATS_DATA = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 46,
    CODECHAL_HEVC_FEI_B_MBENC_FRAME_STATS_DATA = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 47,
    //
    CODECHAL_HEVC_FEI_B_MBENC_EXTERNAL_MVP = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 48,
    CODECHAL_HEVC_FEI_B_MBENC_PER_CTB_CTRL = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 49,
    CODECHAL_HEVC_FEI_B_MBENC_CTB_DISTORTION = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 50,
    CODECHAL_HEVC_FEI_B_MBENC_DEBUG = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 51,
    //
    CODECHAL_HEVC_FEI_B_MBENC_END = CODECHAL_HEVC_FEI_B_MBENC_BEGIN + 52,

    // HEVC B PAK kernel
    CODECHAL_HEVC_FEI_B_PAK_BEGIN = CODECHAL_HEVC_FEI_B_MBENC_END,
    CODECHAL_HEVC_FEI_B_PAK_CU_RECORD = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 0,
    CODECHAL_HEVC_FEI_B_PAK_PAK_OBJ = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 1,
    CODECHAL_HEVC_FEI_B_PAK_SLICE_MAP = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 2,
    CODECHAL_HEVC_FEI_B_PAK_BRC_INPUT = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 3,
    CODECHAL_HEVC_FEI_B_PAK_LCU_QP = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 4,
    CODECHAL_HEVC_FEI_B_PAK_BRC_DATA = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 5,
    CODECHAL_HEVC_FEI_B_PAK_MB_DATA = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 6,
    CODECHAL_HEVC_FEI_B_PAK_MVP_DATA = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 7,
    CODECHAL_HEVC_FEI_B_PAK_WA_PAK_DATA = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 8,
    CODECHAL_HEVC_FEI_B_PAK_WA_PAK_OBJ = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 9,
    CODECHAL_HEVC_FEI_B_PAK_DEBUG = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 10,
    CODECHAL_HEVC_FEI_B_PAK_END = CODECHAL_HEVC_FEI_B_PAK_BEGIN + 11,

    //HEVC FORMAT CONVERSION AND DOWNSCALING KERNEL
    CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN = CODECHAL_HEVC_FEI_B_PAK_END,
    CODECHAL_HEVC_FEI_DS_COMBINED_10BIT_Y = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 0,
    CODECHAL_HEVC_FEI_DS_COMBINED_10BIT_UV = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 1,
    CODECHAL_HEVC_FEI_DS_COMBINED_8BIT_Y = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 2,
    CODECHAL_HEVC_FEI_DS_COMBINED_8BIT_UV = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 3,
    CODECHAL_HEVC_FEI_DS_COMBINED_4xDOWNSCALE = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 4,
    CODECHAL_HEVC_FEI_DS_COMBINED_MB_STATS = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 5,
    CODECHAL_HEVC_FEI_DS_COMBINED_2xDOWNSCALE = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 6,
    CODECHAL_HEVC_FEI_DS_COMBINED_END = CODECHAL_HEVC_FEI_DS_COMBINED_BEGIN + 7,

    // P MB ENC kernel
    CODECHAL_HEVC_FEI_P_MBENC_BEGIN = CODECHAL_HEVC_FEI_DS_COMBINED_END,
    CODECHAL_HEVC_FEI_P_MBENC_CU_RECORD = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 0,
    CODECHAL_HEVC_FEI_P_MBENC_PAK_CMD = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 1,
    CODECHAL_HEVC_FEI_P_MBENC_SRC_Y = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 2,
    CODECHAL_HEVC_FEI_P_MBENC_SRC_UV = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 3,
    CODECHAL_HEVC_FEI_P_MBENC_INTRA_DIST = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 4,
    CODECHAL_HEVC_FEI_P_MBENC_MIN_DIST = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 5,
    CODECHAL_HEVC_FEI_P_MBENC_HME_MVP = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 6,
    CODECHAL_HEVC_FEI_P_MBENC_HME_DIST = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 7,
    CODECHAL_HEVC_FEI_P_MBENC_SLICE_MAP = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 8,
    CODECHAL_HEVC_FEI_P_MBENC_VME_UNISIC_DATA = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 9,
    CODECHAL_HEVC_FEI_P_MBENC_Simplest_Intra = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 10,
    CODECHAL_HEVC_FEI_P_MBENC_REF_COLLOC = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 11,
    CODECHAL_HEVC_FEI_P_MBENC_Reserved = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 12,
    CODECHAL_HEVC_FEI_P_MBENC_BRC_Input = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 13,
    CODECHAL_HEVC_FEI_P_MBENC_LCU_QP = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 14,
    CODECHAL_HEVC_FEI_P_MBENC_BRC_DATA = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 15,
    //
    CODECHAL_HEVC_FEI_P_MBENC_VME_CURRENT = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 16,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_0 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 17,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_1 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 19,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_2 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 21,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_3 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 23,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_4 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 25,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_5 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 27,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_6 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 29,
    CODECHAL_HEVC_FEI_P_MBENC_VME_FORWARD_7 = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 31,
    //
    CODECHAL_HEVC_FEI_P_MBENC_CONCURRENT_THD_MAP = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 33,
    CODECHAL_HEVC_FEI_P_MBENC_MV_IDX = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 34,
    CODECHAL_HEVC_FEI_P_MBENC_MVP_IDX = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 35,
    CODECHAL_HEVC_FEI_P_MBENC_DEBUG = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 36,
    //
    CODECHAL_HEVC_FEI_P_MBENC_END = CODECHAL_HEVC_FEI_P_MBENC_BEGIN + 37,

    CODECHAL_HEVC_FEI_NUM_SURFACES = CODECHAL_HEVC_FEI_P_MBENC_END
};

//!
//! \enum     HEVC_ME_DIST_TYPE
//! \brief    HEVC me dist type
//!
enum HEVC_ME_DIST_TYPE
{
    HEVC_ME_DIST_TYPE_INTRA = 0,
    HEVC_ME_DIST_TYPE_INTRA_BRC_DIST,
    HEVC_ME_DIST_TYPE_INTER_BRC_DIST
};

//!
//! \enum     CODECHAL_ENCODE_HEVC_MULTIPRED
//! \brief    Codechal encode HEVC multipred
//!
enum CODECHAL_ENCODE_HEVC_MULTIPRED
{
    CODECHAL_ENCODE_HEVC_MULTIPRED_ENABLE = 0x01,
    CODECHAL_ENCODE_HEVC_MULTIPRED_DISABLE = 0x80
} ;

//!
//! \struct   CODECHAL_ENCODE_HEVC_SLICE_MAP
//! \brief    Codechal encode HEVC slice map
//!
struct CODECHAL_ENCODE_HEVC_SLICE_MAP
{
    uint8_t   ucSliceID;
    uint8_t   Reserved[3];
};
using PCODECHAL_ENCODE_HEVC_SLICE_MAP = CODECHAL_ENCODE_HEVC_SLICE_MAP*;

//!
//! \struct   CODECHAL_ENCODE_HEVC_WALKING_CONTROL_REGION
//! \brief    Codechal encode HEVC walking control region
//!
struct CODECHAL_ENCODE_HEVC_WALKING_CONTROL_REGION
{
    uint16_t  Reserve0[2];
    uint16_t  StartYCurrentSlice;
    uint16_t  StartYNextSlice;
    uint16_t  Xoffset;
    uint16_t  Reserve1[2];
    uint16_t  Yoffset;
    uint32_t  Reserve2[4];
    uint32_t  alignment[8];
};
using PCODECHAL_ENCODE_HEVC_WALKING_CONTROL_REGION = CODECHAL_ENCODE_HEVC_WALKING_CONTROL_REGION*;

//!
//! \struct   CODECHAL_ENCODE_HEVC_REFFRAME_SYNC_OBJ
//! \brief    Codechal encode HEVC reference frame sync object
//!
struct CODECHAL_ENCODE_HEVC_REFFRAME_SYNC_OBJ
{
    uint32_t                uiSemaphoreObjCount = 0;
    MOS_RESOURCE            resSyncObject       = {};
    bool                    bInUsed             = false;
    CODECHAL_ENCODE_BUFFER  resSemaphoreMem     = {};
};
using PCODECHAL_ENCODE_HEVC_REFFRAME_SYNC_OBJ = CODECHAL_ENCODE_HEVC_REFFRAME_SYNC_OBJ*;

C_ASSERT((sizeof(CODECHAL_ENCODE_HEVC_WALKING_CONTROL_REGION)) == 64);

//!
//! \struct   CODECHAL_ENCODE_HEVC_WALKINGPATTERN_PARAM
//! \brief    Codechal encode HEVC walking pattern parameter
//!
struct CODECHAL_ENCODE_HEVC_WALKINGPATTERN_PARAM
{
    // Media Walker setting
    MHW_WALKER_PARAMS           MediaWalker;
    MHW_VFE_SCOREBOARD          ScoreBoard;

    int                         Offset_Y;
    int                         Offset_Delta;
    uint32_t                    dwNumRegion;
    uint32_t                    dwMaxHeightInRegion;
    uint32_t                    dwNumUnitsInRegion;
};
using PCODECHAL_ENCODE_HEVC_WALKINGPATTERN_PARAM = CODECHAL_ENCODE_HEVC_WALKINGPATTERN_PARAM*;

//!
//! \struct   CODECHAL_ENCODE_HEVC_PAK_STATS_BUFFER
//! \brief    Codechal encode HEVC PAK States buffer
//!
struct CODECHAL_ENCODE_HEVC_PAK_STATS_BUFFER
{
    uint32_t HCP_BITSTREAM_BYTECOUNT_FRAME;
    uint32_t HCP_BITSTREAM_BYTECOUNT_FRAME_NOHEADER;
    uint32_t HCP_IMAGE_STATUS_CONTROL;
    uint32_t Reserved0;
    uint32_t HCP_IMAGE_STATUS_CONTROL_FOR_LAST_PASS;
    uint32_t Reserved1[3];
};

//!
//! \enum     CODECHAL_HEVC_MBENC_KRNIDX
//! \brief    Codechal HEVC MBENC KRNIDX
//!
enum CODECHAL_HEVC_MBENC_KRNIDX
{
    CODECHAL_HEVC_MBENC_2xSCALING = 0,
    CODECHAL_HEVC_MBENC_32x32MD,
    CODECHAL_HEVC_MBENC_16x16SAD,
    CODECHAL_HEVC_MBENC_16x16MD,
    CODECHAL_HEVC_MBENC_8x8PU,
    CODECHAL_HEVC_MBENC_8x8FMODE,
    CODECHAL_HEVC_MBENC_32x32INTRACHECK,
    CODECHAL_HEVC_MBENC_BENC,
    CODECHAL_HEVC_MBENC_BPAK,
    CODECHAL_HEVC_MBENC_ADV,
    CODECHAL_HEVC_MBENC_NUM,
    CODECHAL_HEVC_MBENC_DS_COMBINED = CODECHAL_HEVC_MBENC_NUM, //this will be added for 10 bit for KBL
    CODECHAL_HEVC_MBENC_NUM_KBL,
    CODECHAL_HEVC_MBENC_PENC = CODECHAL_HEVC_MBENC_NUM_KBL,
    CODECHAL_HEVC_MBENC_ADV_P,
    CODECHAL_HEVC_MBENC_NUM_BXT_SKL //Only BXT and SKL support HEVC P frame
};

//!
//! \enum     CODECHAL_HEVC_FEI_MBENC_KRNIDX
//! \brief    Codechal HEVC FEI MBENC KRNIDX
//!
enum CODECHAL_HEVC_FEI_MBENC_KRNIDX
{
    CODECHAL_HEVC_FEI_MBENC_BENC = CODECHAL_HEVC_MBENC_BENC,
    CODECHAL_HEVC_FEI_MBENC_BPAK,
    CODECHAL_HEVC_FEI_MBENC_NUM,
    CODECHAL_HEVC_FEI_MBENC_DS_COMBINED = CODECHAL_HEVC_FEI_MBENC_NUM, //this will be added for 10 bit for KBL
    CODECHAL_HEVC_FEI_MBENC_NUM_KBL,
    CODECHAL_HEVC_FEI_MBENC_PENC = CODECHAL_HEVC_FEI_MBENC_NUM_KBL,
    CODECHAL_HEVC_FEI_MBENC_NUM_BXT_SKL //Only BXT and SKL support HEVC P frame
} ;

//!
//! \enum     CODECHAL_HEVC_BRC_KRNIDX
//! \brief    Codechal HEVC BRC KRNIDX
//!
enum CODECHAL_HEVC_BRC_KRNIDX
{
    CODECHAL_HEVC_BRC_COARSE_INTRA = 0,
    CODECHAL_HEVC_BRC_INIT,
    CODECHAL_HEVC_BRC_RESET,
    CODECHAL_HEVC_BRC_FRAME_UPDATE,
    CODECHAL_HEVC_BRC_LCU_UPDATE,
    CODECHAL_HEVC_BRC_NUM
};

//! \class    CodechalEncodeHevcBase
//! \brief    HEVC encoder base class
//! \details  This class defines the base class for HEVC encoder, it includes
//!           common member fields, functions, interfaces etc shared by both dual-pipe and VDEnc for all Gens.
//!
//!           To create a HEVC encoder instance, client needs to call CodechalEncodeHevcBase::CreateHevcState()
//!
class CodechalEncodeHevcBase : public CodechalEncoderState
{
public:
    static constexpr uint32_t                   MAX_LCU_SIZE = 64;                              //!< Max LCU size 64
    static constexpr uint32_t                   QP_NUM = 52;                                    //!< Number of QP values

    static const uint8_t                        TransformSkipCoeffsTable[4][2][2][2][2];        //!< Transform skip related coeff table
    static const uint16_t                       TransformSkipLambdaTable[QP_NUM];               //!< Transform skip related lambda table

    static const uint8_t CC_BYPASS = 0x0;                                                       //!< MFX Video Copy Mode
    static const uint8_t CC_LIST_MODE = 0x1;                                                    //!< MFX Video CP Copy Mode

    //! HEVC encoder slice type enum
    enum
    {
        CODECHAL_ENCODE_HEVC_B_SLICE = 0,
        CODECHAL_ENCODE_HEVC_P_SLICE = 1,
        CODECHAL_ENCODE_HEVC_I_SLICE = 2,
        CODECHAL_ENCODE_HEVC_NUM_SLICE_TYPES =  3
    };

    // Parameters passed from application
    PCODEC_HEVC_ENCODE_PICTURE_PARAMS  m_hevcPicParams      = nullptr;  //!< Pointer to picture parameter
    PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS m_hevcSeqParams      = nullptr;  //!< Pointer to sequence parameter
    PCODEC_HEVC_ENCODE_SLICE_PARAMS    m_hevcSliceParams    = nullptr;  //!< Pointer to slice parameter
    CodecEncodeHevcFeiPicParams *      m_hevcFeiPicParams   = nullptr;  //!< Pointer to FEI picture parameter
    PCODECHAL_HEVC_IQ_MATRIX_PARAMS    m_hevcIqMatrixParams = nullptr;  //!< Pointer to IQ matrix parameter

    uint32_t m_widthAlignedMaxLcu  = 0;  //!< Picture width aligned in max LCU size
    uint32_t m_heightAlignedMaxLcu = 0;  //!< Picture height aligned in max LCU size

    // PAK resources
    MOS_RESOURCE     m_resDeblockingFilterRowStoreScratchBuffer;                            //!< Deblocking filter row store scratch data buffer
    MOS_RESOURCE     m_resDeblockingFilterTileRowStoreScratchBuffer;                        //!< Deblocking filter tile row store Scratch data buffer
    MOS_RESOURCE     m_resDeblockingFilterColumnRowStoreScratchBuffer;                      //!< Deblocking filter column row Store scratch data buffer
    MOS_RESOURCE     m_resMetadataLineBuffer;                                               //!< Metadata line data buffer
    MOS_RESOURCE     m_resMetadataTileLineBuffer;                                           //!< Metadata tile line data buffer
    MOS_RESOURCE     m_resMetadataTileColumnBuffer;                                         //!< Metadata tile column data buffer
    MOS_RESOURCE     m_resSaoLineBuffer;                                                    //!< SAO line data buffer
    MOS_RESOURCE     m_resSaoTileLineBuffer;                                                //!< SAO tile line data buffer
    MOS_RESOURCE     m_resSaoTileColumnBuffer;                                              //!< SAO tile column data buffer
    MOS_RESOURCE     m_resLcuBaseAddressBuffer;                                             //!< LCU base address buffer
    MOS_RESOURCE     m_resLcuIldbStreamOutBuffer;                                           //!< LCU ILDB streamout buffer
    MOS_RESOURCE     m_resSaoStreamOutBuffer;                                               //!< SAO streamout buffer
    MOS_RESOURCE     m_resFrameStatStreamOutBuffer;                                         //!< Frame statistics streamout buffer
    MOS_RESOURCE     m_resSseSrcPixelRowStoreBuffer;                                        //!< SSE src pixel row store buffer
    MHW_BATCH_BUFFER m_batchBufferForPakSlices[CODECHAL_HEVC_NUM_PAK_SLICE_BATCH_BUFFERS];  //!< Batch buffer for pak slice commands
    uint32_t         m_currPakSliceIdx                    = 0;                              //!< Current pak slice index
    bool             m_useBatchBufferForPakSlices         = false;                          //!< Flag to indicate if batch buffer is used for PAK slice level commands
    uint32_t         m_batchBufferForPakSlicesStartOffset = 0;                              //!< Pak slice command start offset within batch buffer

    uint32_t m_defaultPictureStatesSize    = 0;  //!< Picture state command size
    uint32_t m_defaultPicturePatchListSize = 0;  //!< Picture state patch list size
    uint32_t m_defaultSliceStatesSize      = 0;  //!< Slice state command size
    uint32_t m_defaultSlicePatchListSize   = 0;  //!< Slice state patch list size

    unsigned char m_uc2NdSaoPass      = 0;      //!< Second SAO pass number
    bool          m_b2NdSaoPassNeeded = false;  //!< Second SAO pass enable flag

    CODECHAL_ENCODE_HEVC_REFFRAME_SYNC_OBJ  m_refSync[CODEC_NUM_TRACKED_BUFFERS];  //!< Reference frame sync object
    PCODECHAL_ENCODE_HEVC_REFFRAME_SYNC_OBJ m_currRefSync           = nullptr;     //!< Pointer to current frame sync object
    unsigned char                           m_lastMbCodeIndex       = 0;           //!< Used in the non-parallel BRC to check if the previous PAK is ready
    unsigned char                           m_currMinus2MbCodeIndex = 0;           //!< Used in the parallel BRC to check if the (N-2)th PAK is ready, where N is the frame number

    int8_t        m_refIdxMapping[CODEC_MAX_NUM_REF_FRAME_HEVC];                          //!< Reference frame index mapping
    bool          m_lowDelay                              = false;                        //!< Low delay flag
    bool          m_sameRefList                           = false;                        //!< Flag to specify if ref list L0 and L1 are same
    bool          m_isMaxLcu64                            = false;                        //!< Flag to specify if max LCU size is 64
    uint32_t      m_sizeOfMvTemporalBuffer                = 0;                            //!< MV temporal buffer size
    bool          m_encode4KSequence                      = false;                        //!< Flag to specify if input sequence is 4k size
    bool          m_encode16KSequence                     = false;                        //!< Flag to specify if input sequence is 16k size
    bool          m_hevcRdoqEnabled                       = false;                        //!< RDOQ enable flag
    uint32_t      m_rdoqIntraTuThreshold                  = 0;                            //!< RDOQ intra threshold
    bool          m_hevcIFrameRdoqEnabled                 = true;                        //!< Control intra frame RDOQ enable/disable
#if (_DEBUG || _RELEASE_INTERNAL)
    bool          m_rdoqIntraTuOverride                   = false;                        //!< Override RDOQ intra TU or not
    bool          m_rdoqIntraTuDisableOverride            = false;                        //!< Override RDOQ intra TU disable
    uint16_t      m_rdoqIntraTuThresholdOverride          = 0;                            //!< Override RDOQ intra TU threshold
#endif
    bool          m_is10BitHevc                           = false;                        //!< 10bit encoding flag
    unsigned char m_chromaFormat                          = HCP_CHROMA_FORMAT_YUV420;     //!< Chroma format(420, 422 etc)
    unsigned char m_bitDepth                              = 8;                            //!< Bit depth
    uint32_t      m_maxNumSlicesSupported                 = CODECHAL_HEVC_MAX_NUM_SLICES_LVL_5;  //!< Maximal number of slices supported
    uint32_t      m_sizeOfSseSrcPixelRowStoreBufferPerLcu = 0;                            //!< Size of SSE row store buffer per LCU
    uint32_t      m_sizeOfHcpPakFrameStats                = 0;                            //!> Size of HEVC PAK frame statistics
    uint8_t       m_roundingInter                         = 4;                            // the value is from prototype
    uint8_t       m_roundingIntra                         = 10;                           // the value is from prototype

    bool                       m_currUsedRefPic[CODEC_MAX_NUM_REF_FRAME_HEVC];     //!< Reference picture usage array
    CODEC_PIC_ID               m_picIdx[CODEC_MAX_NUM_REF_FRAME_HEVC];             //!< Reference picture index array
    PCODEC_REF_LIST            m_refList[CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC];  //!< Pointer to reference pictures
    PCODECHAL_NAL_UNIT_PARAMS *m_nalUnitParams          = nullptr;                 //!< Pointer to NAL unit parameters
    bool                       m_enable26WalkingPattern = false;                   //!< 26 walking pattern enable flag

    // ME
    bool        m_hmeEnabled    = false;                     //!< HME enable flag
    bool        m_b16XMeEnabled = false;                     //!< 16xME enable flag
    bool        m_b32XMeEnabled = false;                     //!< 32xME enable flag
    MOS_SURFACE m_s4XMeMvDataBuffer;                         //!< 4xME mv data buffer
    MOS_SURFACE m_s16XMeMvDataBuffer;                        //!< 16xME mv data buffer
    MOS_SURFACE m_s32XMeMvDataBuffer;                        //!< 32xME mv data buffer
    MOS_SURFACE m_s4XMeDistortionBuffer;                     //!< 4xME distortion buffer
    bool        m_brcDistortionBufferSupported   = false;    //!< Brc distorion supported flag
    bool        m_b4XMeDistortionBufferSupported = false;    //!< 4xME distorion supported flag
    uint8_t *   m_bmeMethodTable                 = nullptr;  //!< Pointer for ME method table based on TargetUsage
    uint8_t *   m_meMethodTable                  = nullptr;  //!< Pointer for ME method table based on TargetUsage

    // BRC
    uint16_t m_usAvbrAccuracy                     = 0;      //!< AVBR accuracy
    uint16_t m_usAvbrConvergence                  = 0;      //!< AVBR convergence
    double   m_dBrcInitCurrentTargetBufFullInBits = 0.0;    //!< Initial value of target buffer fullness in bits
    double   m_dBrcInitResetInputBitsPerFrame     = 0.0;    //!< Input bits per frame
    uint32_t m_brcInitResetBufSizeInBits          = 0;      //!< Target buffer size in bits
    uint32_t m_hevcBrcPakStatisticsSize           = 0;      //!< BRC PAK statistics size
    bool     m_brcEnabled                         = false;  //!< BRC enable flag
    bool     m_lcuBrcEnabled                      = false;  //!< LCU BRC enable flag
    bool     m_brcInit                            = true;   //!< BRC init flag
    bool     m_brcReset                           = false;  //!< BRC reset flag
    bool     m_brcRoiEnabled                      = false;  //!< BRC Roi flag
    bool     m_roiValueInDeltaQp                  = true;   //!< ROI Value in deltaQP or priority flag

    CODECHAL_ENCODE_BUFFER m_resPakcuLevelStreamoutData;  //!< PAK LCU level stream out data buffer

    // Mb Qp Data
    bool            m_mbQpDataEnabled = false;      //!< Mb Qp Data Enable Flag.
    MOS_SURFACE     m_mbQpDataSurface;              //!< Pointer to MOS_SURFACE of Mb Qp data surface, provided by DDI.

protected:
    //!
    //! \brief    Constructor
    //!
    CodechalEncodeHevcBase(CodechalHwInterface* hwInterface,
        CodechalDebugInterface* debugInterface,
        PCODECHAL_STANDARD_INFO standardInfo);

    uint8_t*                                    m_kernelBinary = nullptr;               //!< Pointer to the kernel binary
    uint32_t                                    m_combinedKernelSize = 0;               //!< Combined kernel binary size
    PMHW_VDBOX_HEVC_SLICE_STATE                 m_sliceStateParams = nullptr;           //!< Slice state parameters
    PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS          m_pipeModeSelectParams = nullptr;       //!< Pipe mode select parameters
    PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS             m_pipeBufAddrParams = nullptr;          //!< Pipe buffer addr parameters

public:
    //!
    //! \brief    Destructor
    //!
    virtual ~CodechalEncodeHevcBase() {};

    //!
    //! \brief    Help function to check if the rate control method is BRC
    //!
    //! \param    [in] rc
    //!           Rate control method
    //!
    //! \return   True if using BRC , else return false
    //!
    bool IsRateControlBrc(uint8_t rc)
    {
        return  (rc == RATECONTROL_CBR) ||
                (rc == RATECONTROL_VBR) ||
                (rc == RATECONTROL_AVBR) ||
                (rc == RATECONTROL_VCM) ||
                (rc == RATECONTROL_ICQ) ||
                (rc == RATECONTROL_QVBR);
    }

    //!
    //! \brief    Help function to calculate the slice QP
    //!
    //! \return   Slice QP value
    //!
    int CalSliceQp()
    {
        CODECHAL_ENCODE_ASSERT(m_hevcSliceParams);
        CODECHAL_ENCODE_ASSERT(m_hevcPicParams);

        int qp = m_hevcSliceParams->slice_qp_delta + m_hevcPicParams->QpY;
        CODECHAL_ENCODE_ASSERT(qp >= 0 && qp < QP_NUM);
        return qp;
    }

    //!
    //! \brief    Help function to get current PAK pass
    //!
    //! \return   Current PAK pass
    //!
    virtual int GetCurrentPass()
    {
        return m_currPass;
    }

    //!
    //! \brief    Help function to check if current PAK pass is first pass
    //!
    //! \return   True if current PAK pass is first pass, otherwise return false
    //!
    virtual bool IsFirstPass()
    {
        return GetCurrentPass() == 0 ? true : false;
    }

    //!
    //! \brief    Help function to check if current PAK pass is last pass
    //!
    //! \return   True if current PAK pass is last pass, otherwise return false
    //!
    virtual bool IsLastPass()
    {
        return GetCurrentPass() == m_numPasses ? true : false;
    }

    //!
    //! \brief    Help function to check if legacy command buffer is used
    //!
    //! \return   True if using legacy command buffer, otherwise return false
    //!
    bool UseRenderCommandBuffer()
    {
        return (m_osInterface->pfnGetGpuContext(m_osInterface) == m_renderContext);
    }

    //!
    //! \brief    Help function to retrieve a command buffer
    //!
    //! \param    [in, out] cmdBuffer
    //!           Pointer to command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS GetCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer);

    //!
    //! \brief    Help function to return a command buffer
    //!
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ReturnCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer);

    //!
    //! \brief    Help function to submit a command buffer
    //!
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //! \param    [in] nullRendering
    //!           Null rendering flag
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS SubmitCommandBuffer(
        PMOS_COMMAND_BUFFER cmdBuffer,
        bool                bNullRendering);

    //!
    //! \brief    Help function to verify command buffer size
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS VerifyCommandBufferSize();

    //!
    //! \brief    Help function to send prolog with frame tracking information
    //!
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //! \param    [in] frameTrackingRequested
    //!           True if frame tracking info is needed, false otherwise
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS SendPrologWithFrameTracking(
        PMOS_COMMAND_BUFFER cmdBuffer,
        bool frameTrackingRequested,
        MHW_MI_MMIOREGISTERS *mmioRegister = nullptr);

    //!
    //! \brief    Wait for dependent VDBOX to get ready
    //!
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS WaitForVDBOX(PMOS_COMMAND_BUFFER cmdBuffer);

    //!
    //! \brief    Add MI_SEMAPHORE_WAIT command in command buffer
    //!
    //! \param    [in] semaphoreMem
    //!           Pointer to semaphore resource
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //! \param    [in] semValue
    //!           Value to wait on semaphore memory
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS SendHWWaitCommand(
        PMOS_RESOURCE semaphoreMem,
        PMOS_COMMAND_BUFFER cmdBuffer,
        uint32_t semValue);

    //!
    //! \brief      Send MI atomic command
    //!
    //! \param    [in] semaMem
    //!           Pointer to semaphore resource
    //! \param    [in] ImmData
    //!           immediate data for atomic operation
    //! \param    [in] opCode
    //!           enum value of MHW_COMMON_MI_ATOMIC_OPCODE
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS SendMIAtomicCmd(
        PMOS_RESOURCE               semaMem,
        uint32_t                    ImmData,
        MHW_COMMON_MI_ATOMIC_OPCODE opCode,
        PMOS_COMMAND_BUFFER         cmdBuffer);

    //!
    //! \brief    Store data to semaphore memory
    //!
    //! \param    [in] semaphoreMem
    //!           Pointer to semaphore resource
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //! \param    [in] value
    //!           Value to store in semaphore memory
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS SetSemaphoreMem(
        PMOS_RESOURCE semaphoreMem,
        PMOS_COMMAND_BUFFER cmdBuffer,
        uint32_t value);

    //!
    //! \brief    Allocate resources for encoder instance
    //! \details  It is invoked when initializing encoder instance and it would call #AllocateEncResources(), #AllocateBrcResources(),
    //!           #AllocatePakResources() and #InitSurfaceInfoTable()
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateResources();

    //!
    //! \brief    Free encoder resources
    //! \details  It is invoked when destorying encoder instance and it would call #FreeEncResources(), #FreeBrcResources()
    //!           and #FreePakResources()
    //!
    //! \return   void
    //!
    void FreeResources();

    //!
    //! \brief    Help function to allocate a 1D buffer
    //!
    //! \param    [in,out] buffer
    //!           Pointer to allocated buffer
    //! \param    [in] size
    //!           Buffer size
    //! \param    [in] name
    //!           Buffer name
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateBuffer(
        PCODECHAL_ENCODE_BUFFER buffer,
        uint32_t size,
        const char* name,
        int32_t dwMemType = 0);

    //!
    //! \brief    Help function to allocate a generic 2D surface
    //!
    //! \param    [in,out] surface
    //!           Pointer to allocated surface
    //! \param    [in] width
    //!           Surface width
    //! \param    [in] height
    //!           Surface height
    //! \param    [in] name
    //!           Surface name
    //! \param    [in] tileType
    //!           Tile type
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateBuffer2D(
        PMOS_SURFACE surface,
        uint32_t width,
        uint32_t height,
        const char* name,
        MOS_TILE_TYPE tileType = MOS_TILE_LINEAR,
        int32_t dwMemType = 0);

    //!
    //! \brief    Help function to allocate a NV12 TILE_Y surface
    //!
    //! \param    [in,out] surface
    //!           Pointer to allocated surface
    //! \param    [in] width
    //!           Surface width
    //! \param    [in] height
    //!           Surface height
    //! \param    [in] name
    //!           Surface name
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateSurface(
        PMOS_SURFACE surface,
        uint32_t width,
        uint32_t height,
        const char* name,
        int32_t dwMemType = 0);

    //!
    //! \brief    Help function to allocate PAK slice level batch buffers
    //!
    //! \param    [in] numSlices
    //!           Number of slices
    //! \param    [in] numPakPasses
    //!           Number of PAK passes
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateBatchBufferForPakSlices(
        uint32_t numSlices,
        unsigned char numPakPasses);

    //! \brief    Calculates the PSNR values for luma/ chroma
    //!
    //! \param    [in, out] encodeStatus
    //!           Pointer to encoder status
    //! \param    [in, out] encodeStatusReport
    //!           Pointer to encoder status report
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS CalculatePSNR(
        EncodeStatus        *encodeStatus,
        EncodeStatusReport  *encodeStatusReport);

    //! \brief    Copy sum square error for luma/ chroma channel from
    //!           frame statistics report into encodeStatus buffer
    //!
    //! \param    [in, out] cmdBuffer
    //!           Pointer to command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ReadSseStatistics(PMOS_COMMAND_BUFFER cmdBuffer);

    //!
    //! \brief    Help function to release PAK slice level batch buffers
    //!
    //! \param    [in] index
    //!           Index of batch buffer to be released
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS ReleaseBatchBufferForPakSlices(uint32_t index);

    //!
    //! \brief    Help function to get the MaxMBPS for speicifc level Id
    //!
    //! \param    [in] levelIdc
    //!           HEVC level Id
    //! \param    [in] maxMBPS
    //!           Max MBPS
    //! \param    [in] maxBytePerPic
    //!           Max byte per picture
    //!
    //! \return   MaxMBPS(max number of MB per second) for input level Id
    //!
    MOS_STATUS GetMaxMBPS(uint32_t levelIdc, uint32_t* maxMBPS, uint64_t* maxBytePerPic);

    //!
    //! \brief    Help function to calcuate max frame size corresponding to the input profile/level
    //!
    //! \return   Max frame size in bytes
    //!
    uint32_t GetProfileLevelMaxFrameSize();

    //!
    //! \brief    Help function to create a flat scaling list (when scaling list is not passed in sequence parameter)
    //!
    //! \return   void
    //!
    void CreateFlatScalingList();

    //!
    //! \brief    Help function to create a default scaling list (when scaling list data is not presented in picture parameter)
    //!
    //! \return   void
    //!
    void CreateDefaultScalingList();

    //!
    //! \brief    Validate low delay mode for B frame
    //!
    //! \param    [in] slcParams
    //!           Pointer to slice parameter
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS ValidateLowDelayBFrame(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams);

    //!
    //! \brief    Validate if reference list L0 and L1 are same
    //!
    //! \param    [in] slcParams
    //!           Pointer to slice parameter
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS ValidateSameRefInL0L1(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams);

    //!
    //! \brief    Verify slice SAO state
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS VerifySliceSAOState();

    //!
    //! \brief    Update recon surface to Variant format for 422 10-bit
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS UpdateYUY2SurfaceInfo(
        PMOS_SURFACE        surface,
        bool                is10Bit);

    //!
    //! \brief    Check if the color format of the surface is supported
    //!
    //! \details  If the color format is not supported, and the Codec/Gen supports color space conversion feature
    //            then Csc+Ds+Conversion kernel will be called to convert raw surface to supported color format
    //!
    //! \param    [in] surface
    //!           pointer to surface
    //!
    //! \return   bool
    //!           true if the color format is supported, false otherwise
    //!
    virtual bool CheckSupportedFormat(PMOS_SURFACE surface) { return true; }

    //!
    //! \brief    Initialize encoder instance with the provided settings
    //! \details  When derived class overwrite this function to do its own initialization,
    //            it should call #CodechalEncodeHevcBase::Initialize() first
    //            to do common initializations
    //!
    //! \param    [in] settings
    //!           Encoder settings
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS Initialize(CodechalSetting * settings);

    //!
    //! \brief    Initialize surface info
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS InitSurfaceInfoTable()
    {
        return MOS_STATUS_SUCCESS;
    }

    //!
    //! \brief    Setup/configure encoder based on sequence parameter set
    //! \details  It is invoked when the encoder receives a new sequence parameter set and it would
    //!           set up and configure the encoder state that used for the sequence
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS SetSequenceStructs();

    //!
    //! \brief    Setup/configure encoder based on picture parameter set
    //! \details  It is invoked for every picture and it would set up and configure the
    //            encoder state that used for current picture
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS SetPictureStructs();

    //!
    //! \brief    Calculate maximum bitsize allowed for LCU
    //! \details  Calculate LCU max coding size according to log2_max_coding_block_size_minus3
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS CalcLCUMaxCodingSize();

    //!
    //! \brief    Setup/configure encoder based on slice parameter set
    //! \details  It is invoked for every picture and and it would set up and configure the
    //            encoder state that used for current picture and slices
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS SetSliceStructs();

    //!
    //! \brief    Calculate transform skip parameters
    //!
    //! \param    [in, out] params
    //!           Transform skip parameters
    //!
    //! \return   void
    //!
    virtual void CalcTransformSkipParameters(MHW_VDBOX_ENCODE_HEVC_TRANSFORM_SKIP_PARAMS& params);

    //!
    //! \brief    Retreive image status information
    //!
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ReadImageStatus(PMOS_COMMAND_BUFFER cmdBuffer);

    //!
    //! \brief    Retreive HCP status
    //!
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ReadHcpStatus(PMOS_COMMAND_BUFFER cmdBuffer);

    //!
    //! \brief    Retreive BRC Pak statistics
    //!
    //! \param    [in] cmdBuffer
    //!           Pointer to command buffer
    //! \param    [in] params
    //!           BRC pak statistics parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ReadBrcPakStatistics(
        PMOS_COMMAND_BUFFER cmdBuffer,
        EncodeReadBrcPakStatsParams* params);

    //!
    //! \brief    Get encoder status report
    //!
    //! \param    [in, out] encodeStatus
    //!           Pointer to encoder status
    //! \param    [in, out] encodeStatusReport
    //!           Pointer to encoder status report
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS GetStatusReport(
        EncodeStatus       *encodeStatus,
        EncodeStatusReport *encodeStatusReport);

    //!
    //! \brief    User Feature key report
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS UserFeatureKeyReport();

    //!
    //! \brief    Initialize encoder at picture level
    //!
    //! \param    [in] params
    //!           Picture encoding parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS InitializePicture(const EncoderParams& params);

    //!
    //! \brief    Perform platform capability check
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS PlatformCapabilityCheck()
    {
        return MOS_STATUS_SUCCESS;
    }

    //!
    //! \brief    Set batch buffer for PAK slices
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS SetBatchBufferForPakSlices();

    // HCP/PAK functions

    //!
    //! \brief    Set HCP_PIPE_MODE_SELECT parameters
    //!
    //! \param    [in, out] pipeModeSelectParams
    //!           HCP_PIPE_MODE_SELECT parameters
    //!
    //! \return   void
    //!
    virtual void SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS& pipeModeSelectParams);

    //!
    //! \brief    Set HCP_SURFACE_PARAMS for source picture
    //!
    //! \param    [in, out] srcSurfaceParams
    //!           HCP_SURFACE_PARAMS for source picture
    //!
    //! \return   void
    //!
    virtual void SetHcpSrcSurfaceParams(MHW_VDBOX_SURFACE_PARAMS& srcSurfaceParams);

    //!
    //! \brief    Set HCP_SURFACE_PARAMS for recon picture
    //!
    //! \param    [in, out] reconSurfaceParams
    //!           HCP_SURFACE_PARAMS for recon picture
    //!
    //! \return   void
    //!
    virtual void SetHcpReconSurfaceParams(MHW_VDBOX_SURFACE_PARAMS &reconSurfaceParams);

    //!
    //! \brief    Set HCP_SURFACE_PARAMS for reference picture
    //!
    //! \param    [in, out] refSurfaceParams
    //!           HCP_SURFACE_PARAMS for reference picture
    //!
    //! \return   void
    //!
    virtual void SetHcpRefSurfaceParams(MHW_VDBOX_SURFACE_PARAMS &refSurfaceParams);

    //!
    //! \brief    Set HCP_PIPE_BUF_ADDR parameters
    //!
    //! \param    [in, out] pipeBufAddrParams
    //!           HCP_PIPE_BUF_ADDR parameters
    //!
    //! \return   void
    //!
    virtual void SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams);

    //!
    //! \brief    Set HCP_IND_OBJ_BASE_ADDR parameters
    //!
    //! \param    [in, out] indObjBaseAddrParams
    //!           HCP_IND_OBJ_BASE_ADDR parameters
    //!
    //! \return   void
    //!
    virtual void SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams);

    //!
    //! \brief    Set HCP_QM_STATE and HCP_FQM_STATE parameters
    //!
    //! \param    [in, out] fqmParams
    //!           HCP_FQM_STATE parameters
    //! \param    [in, out] qmParams
    //!           HCP_QM_STATE parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual void SetHcpQmStateParams(MHW_VDBOX_QM_PARAMS& fqmParams, MHW_VDBOX_QM_PARAMS& qmParams);

    //!
    //! \brief    Set HCP_PIC_STATE parameters
    //!
    //! \param    [in, out] picStateParams
    //!           HCP_PIC_STATE parameters
    //!
    //! \return   void
    //!
    virtual void SetHcpPicStateParams(MHW_VDBOX_HEVC_PIC_STATE& picStateParams);

    //!
    //! \brief    Set HCP_SLICE_STATE parameters shared by all slices
    //!
    //! \param    [in, out] sliceStateParams
    //!           HCP_SLICE_STATE parameters
    //!
    //! \return   void
    //!
    virtual void SetHcpSliceStateCommonParams(MHW_VDBOX_HEVC_SLICE_STATE& sliceStateParams);

    //!
    //! \brief    Create HCP_SLICE_STATE parameters shared by all slices
    //!
    //! \return   void
    //!
    virtual void CreateMhwParams();

    //!
    //! \brief    Set HCP_SLICE_STATE parameters that are different at slice level
    //!
    //! \param    [in, out] sliceStateParams
    //!           HCP_SLICE_STATE parameters
    //! \param    [in] slcData
    //!           Pointer to CODEC_ENCODE_SLCDATA
    //! \param    [in] currSlcIdx
    //!           Current slice index
    //!
    //! \return   void
    //!
    virtual void SetHcpSliceStateParams(
        MHW_VDBOX_HEVC_SLICE_STATE& sliceStateParams,
        PCODEC_ENCODER_SLCDATA slcData,
        uint32_t currSlcIdx);

    //!
    //! \brief    Add HCP_REF_IDX command to command buffer or batch buffer
    //!
    //! \param    [in, out] cmdBuffer
    //!           Pointer to the command buffer
    //! \param    [in, out] batchBuffer
    //!           Pointer to the batch buffer
    //! \param    [in] params
    //!           Pointer to MHW_VDBOX_HEVC_SLICE_STATE parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS AddHcpRefIdxCmd(
        PMOS_COMMAND_BUFFER cmdBuffer,
        PMHW_BATCH_BUFFER batchBuffer,
        PMHW_VDBOX_HEVC_SLICE_STATE params);

    //!
    //! \brief    Add HCP_PAK_INSERT_OBJECT commands for NALUs to command buffer or batch buffer
    //! \details  This function would add multiple HCP_PAK_INSERT_OBJECT, one of each NALU
    //!
    //! \param    [in, out] cmdBuffer
    //!           Pointer to the command buffer
    //! \param    [in, out] batchBuffer
    //!           Pointer to the batch buffer
    //! \param    [in] params
    //!           Pointer to MHW_VDBOX_HEVC_SLICE_STATE parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS AddHcpPakInsertNALUs(
        PMOS_COMMAND_BUFFER cmdBuffer,
        PMHW_BATCH_BUFFER batchBuffer,
        PMHW_VDBOX_HEVC_SLICE_STATE params);

    //!
    //! \brief    Add HCP_PAK_INSERT_OBJECT commands for slice header to command buffer or batch buffer
    //!
    //! \param    [in, out] cmdBuffer
    //!           Pointer to the command buffer
    //! \param    [in, out] batchBuffer
    //!           Pointer to the batch buffer
    //! \param    [in] params
    //!           Pointer to MHW_VDBOX_HEVC_SLICE_STATE parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS AddHcpPakInsertSliceHeader(
        PMOS_COMMAND_BUFFER cmdBuffer,
        PMHW_BATCH_BUFFER batchBuffer,
        PMHW_VDBOX_HEVC_SLICE_STATE params);

    //! \brief    Initialize kernel state
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS InitKernelState() = 0;

    //!
    //! \brief    Get max binding table count required
    //!
    //! \return   Value of max binding table count
    //!
    virtual uint32_t GetMaxBtCount() = 0;

    //!
    //! \brief    Allocate resources for PAK
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS AllocatePakResources();

    //!
    //! \brief    Free PAK resources
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS FreePakResources();

    //!
    //! \brief    Allocate resources for ENC
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS AllocateEncResources() = 0;

    //!
    //! \brief    Free ENC resources
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS FreeEncResources() = 0;

    //!
    //! \brief    Allocate BRC resources
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS AllocateBrcResources() = 0;

    //!
    //! \brief    Free BRC resources
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS FreeBrcResources() = 0;

    //!
    //! \brief    Calculate down scaled dimensions
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS CalcScaledDimensions() = 0;

    //!
    //! \brief    Validate ref frame data
    //!
    //! \param    [in] slcParams
    //!           Slice parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ValidateRefFrameData(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams) = 0;

    //!
    //! \brief    Encode kernel functions
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS EncodeKernelFunctions() = 0;

    //!
    //! \brief    Execute kernel functions
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS ExecuteKernelFunctions();

    //!
    //! \brief    Encode command at picture level
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ExecutePictureLevel() = 0;

    //!
    //! \brief    Encode command at slice level
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS ExecuteSliceLevel() = 0;

    //!
    //! \brief    Calculate picture state command size
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS CalculatePictureStateCommandSize();

    //!
    //! \brief    Calculate picture state command size
    //!
    //! \param    [in, out] cmdBuffer
    //!           Pointer to the command buffer
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    virtual MOS_STATUS AddHcpPipeBufAddrCmd(
        PMOS_COMMAND_BUFFER  cmdBuffer);

    //!
    //! \brief    Initialize MMC state
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success
    //!
    virtual MOS_STATUS InitMmcState();

    //!
    //! \brief    Compute Temporal Different
    //!
    //! \return   short
    //!           return the current picordercnt difference
    //!
    short ComputeTemporalDifferent(
        CODEC_PICTURE    refPic);

    //!
    //! \brief    Init surface codec params 1D
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success
    //!
    MOS_STATUS InitSurfaceCodecParams1D(
        CODECHAL_SURFACE_CODEC_PARAMS* p,
        PMOS_RESOURCE   buffer,
        uint32_t        size,
        uint32_t        offset,
        uint32_t        cacheabilityControl,
        uint32_t        bindingTableOffset,
        bool            isWritable);

    //!
    //! \brief    Init surface codec params 2D
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success
    //!
    MOS_STATUS InitSurfaceCodecParams2D(
        CODECHAL_SURFACE_CODEC_PARAMS* p,
        PMOS_SURFACE    surface,
        uint32_t        cacheabilityControl,
        uint32_t        bindingTableOffset,
        uint32_t        verticalLineStride,
        bool            isWritable);

    //!
    //! \brief    Update the slice count according to the slice shutdown policy
    //!
    virtual void UpdateSSDSliceCount() { return; };

    void MotionEstimationDisableCheck();

    //!
    //! \brief    Allocate 4x ME resources
    //!
    //! \param    [in] param
    //!           Pointer to parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateResources4xME(
        HmeParams* param);

    //!
    //! \brief    Allocate 16x ME resources
    //!
    //! \param    [in] param
    //!           Pointer to parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateResources16xME(
        HmeParams* param);

    //!
    //! \brief    Allocate 32x ME resources
    //!
    //! \param    [in] param
    //!           Pointer to parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS AllocateResources32xME(
        HmeParams* param);

    //!
    //! \brief    Destroy ME resources
    //!
    //! \param    [in] param
    //!           Pointer to parameters
    //!
    //! \return   MOS_STATUS
    //!           MOS_STATUS_SUCCESS if success, else fail reason
    //!
    MOS_STATUS DestroyMEResources(
        HmeParams* param);

#if USE_CODECHAL_DEBUG_TOOL
    MOS_STATUS DumpSeqParams(
        PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS seqParams);

    MOS_STATUS DumpPicParams(
        PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams);

    MOS_STATUS DumpFeiPicParams(
        CodecEncodeHevcFeiPicParams *feiPicParams);

    MOS_STATUS DumpSliceParams(
        PCODEC_HEVC_ENCODE_SLICE_PARAMS   sliceParams,
        PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams);

    MOS_STATUS DumpMbEncPakOutput(PCODEC_REF_LIST currRefList, CodechalDebugInterface* debugInterface);

    MOS_STATUS DumpFrameStatsBuffer(CodechalDebugInterface* debugInterface);

#endif
};

#endif  // __CODECHAL_ENCODE_HEVC_BASE_H__
