/* * Copyright (c) 2011-2020, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ //! //! \file codechal_encode_avc.cpp //! \brief This file implements the base C++ class/interface for AVC DualPipe encoding //! to be used across CODECHAL components. //! #include "codechal_encode_avc.h" #include "codechal_encode_wp.h" #include "codeckrnheader.h" #include "hal_oca_interface.h" #include "mos_os_cp_interface_specific.h" #define CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_DPB_LIST_SIZE 128 #define CODECHAL_ENCODE_AVC_BRC_CONSTANTSURFACE_POCS_IN_FINAL_LIST_SIZE 128 #define CODECHAL_ENCODE_AVC_CQP_NUM_OF_PASSES 2 // 1 additional pass for IPCM #define CODECHAL_ENCODE_AVC_ICQ_NUM_OF_PASSES 2 // 1 additional pass for IPCM #define CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_ROUNDING 6 #define CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE 10240 // 10K is just estimation #define CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON 52 #define CODECHAL_ENCODE_AVC_SKIP_BIAS_ADJUSTMENT_QP_THRESHOLD 22 #define CODECHAL_ENCODE_AVC_HME_FIRST_STEP 0 #define CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP 1 #define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_32x 1 #define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_16x 2 #define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_4x 2 #define CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_16x 1 #define CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_4x 0 #define CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_INTRA_ROUNDING 5 const uint32_t CodechalEncodeAvcEnc::MaxLenSP[NUM_TARGET_USAGE_MODES] = { 0, 57, 57, 25, 25, 25, 16, 9 }; const uint32_t CodechalEncodeAvcEnc::FTQBasedSkip[NUM_TARGET_USAGE_MODES] = { 0, 3, 3, 3, 3, 3, 3, 0 }; const uint32_t CodechalEncodeAvcEnc::HMEBCombineLen[NUM_TARGET_USAGE_MODES] = { 0, 8, 8, 8, 8, 8, 8, 8 }; const uint32_t CodechalEncodeAvcEnc::HMECombineLen[NUM_TARGET_USAGE_MODES] = { 0, 8, 8, 8, 8, 8, 16, 8 }; const uint32_t CodechalEncodeAvcEnc::SearchX[NUM_TARGET_USAGE_MODES] = { 0, 48, 48, 48, 48, 48, 48, 28 }; const uint32_t CodechalEncodeAvcEnc::SearchY[NUM_TARGET_USAGE_MODES] = { 0, 40, 40, 40, 40, 40, 40, 28 }; const uint32_t CodechalEncodeAvcEnc::BSearchX[NUM_TARGET_USAGE_MODES] = { 0, 32, 32, 32, 32, 32, 32, 24 }; const uint32_t CodechalEncodeAvcEnc::BSearchY[NUM_TARGET_USAGE_MODES] = { 0, 32, 32, 32, 32, 32, 32, 24 }; const uint32_t CodechalEncodeAvcEnc::EnableAdaptiveSearch[NUM_TARGET_USAGE_MODES] = { 0, 1, 1, 1, 1, 1, 0, 0 }; const uint32_t CodechalEncodeAvcEnc:: InterRoundingP_TQ[NUM_TARGET_USAGE_MODES] = { 0, 3, 3, 3, 3, 3, 3, 3 }; const uint32_t CodechalEncodeAvcEnc:: InterRoundingBRef_TQ[NUM_TARGET_USAGE_MODES] = { 0, 2, 2, 2, 2, 2, 2, 2 }; const uint32_t CodechalEncodeAvcEnc:: InterRoundingB_TQ[NUM_TARGET_USAGE_MODES] = { 0, 0, 0, 0, 0, 0, 0, 0 }; const uint32_t CodechalEncodeAvcEnc:: TrellisQuantizationEnable[NUM_TARGET_USAGE_MODES] = { 0, 1, 0, 0, 0, 0, 0, 0 }; const uint32_t CodechalEncodeAvcEnc:: EnableAdaptiveTrellisQuantization[NUM_TARGET_USAGE_MODES] = { 0, 1, 0, 0, 0, 0, 0, 0 }; // Lambda values for Trellis Quantization const uint32_t CodechalEncodeAvcEnc::TQ_LAMBDA_I_FRAME[CODEC_AVC_NUM_QP][2] = { {0x00070000, 0x00060000}, {0x00080000, 0x00080000}, {0x000a0000, 0x00090000}, {0x000d0000, 0x000c0000}, {0x00110000, 0x000f0000}, {0x00150000, 0x00130000}, {0x001b0000, 0x00180000}, {0x00220000, 0x001f0000}, {0x002b0000, 0x00270000}, {0x00360000, 0x00310000}, {0x00440000, 0x003e0000}, {0x00550000, 0x004e0000}, {0x006c0000, 0x00630000}, {0x00870000, 0x007d0000}, {0x00ab0000, 0x009d0000}, {0x00d70000, 0x00c70000}, {0x010f0000, 0x00fb0000}, {0x01560000, 0x013d0000}, {0x01af0000, 0x01900000}, {0x021f0000, 0x01f90000}, {0x02ac0000, 0x027e0000}, {0x035e0000, 0x03260000}, {0x043e0000, 0x03fa0000}, {0x057a0000, 0x05070000}, {0x06f90000, 0x065a0000}, {0x08770000, 0x08060000}, {0x0af50000, 0x0a240000}, {0x0d720000, 0x0cd10000}, {0x10ef0000, 0x10340000}, {0x156a0000, 0x147b0000}, {0x1ae50000, 0x19e50000}, {0x225d0000, 0x20be0000}, {0x2ad50000, 0x29670000}, {0x36490000, 0x345c0000}, {0x443b0000, 0x423a0000}, {0x56290000, 0x53c50000}, {0x6c930000, 0x69f90000}, {0x88770000, 0x86130000}, {0xabd30000, 0xa9a40000}, {0xd8a60000, 0xd6aa0000}, // Rounding offsets {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000}, {0xfffa0000, 0xfffa0000} }; const uint32_t CodechalEncodeAvcEnc::TQ_LAMBDA_P_FRAME[CODEC_AVC_NUM_QP][2] = { {0x00070009, 0x00060009}, {0x0008000c, 0x0008000c}, {0x000a000f, 0x0009000f}, {0x000d0013, 0x000c0013}, {0x00110018, 0x000f0018}, {0x0015001e, 0x0013001e}, {0x001b0026, 0x00180026}, {0x00220030, 0x001f0030}, {0x002b003c, 0x0027003c}, {0x0036004c, 0x0031004c}, {0x00440060, 0x003e0060}, {0x00550079, 0x004e0079}, {0x006c0099, 0x00630099}, {0x008700c1, 0x007d00c1}, {0x00ab00f3, 0x009d00f3}, {0x00d70132, 0x00c70133}, {0x010f0181, 0x00fb0183}, {0x015601e5, 0x013d01e8}, {0x01af0264, 0x01900268}, {0x021f0303, 0x01f90309}, {0x02ac03cb, 0x027e03d5}, {0x035e04c8, 0x032604d5}, {0x043e0606, 0x03fa061a}, {0x057a07c7, 0x050707b3}, {0x06f909e6, 0x065a09b8}, {0x08770c05, 0x08060c45}, {0x0af50f8e, 0x0a240f7e}, {0x0d721317, 0x0cd1138f}, {0x10ef180a, 0x103418b2}, {0x156a1e67, 0x147b1f30}, {0x1ae5262e, 0x19e52762}, {0x225d30c9, 0x20be31bd}, {0x2ad53cce, 0x29673ed2}, {0x36494d11, 0x345c4f59}, {0x443b60dd, 0x423a643c}, {0x56297a51, 0x53c57e9f}, {0x6c939a22, 0x69f99ff9}, {0x8877c1ba, 0x8613ca1e}, {0xabd3ffef, 0xa9a4ffef}, {0xd8a6ffef, 0xd6aaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef} }; const uint32_t CodechalEncodeAvcEnc::TQ_LAMBDA_B_FRAME[CODEC_AVC_NUM_QP][2] = { {0x00070009, 0x00060009}, {0x0008000c, 0x0008000c}, {0x000a000f, 0x0009000f}, {0x000d0013, 0x000c0013}, {0x00110018, 0x000f0018}, {0x0015001e, 0x0013001e}, {0x001b0026, 0x00180026}, {0x00220030, 0x001f0030}, {0x002b003c, 0x0027003c}, {0x0036004c, 0x0031004c}, {0x00440060, 0x003e0060}, {0x00550079, 0x004e0079}, {0x006c0099, 0x00630099}, {0x008700c1, 0x007d00c1}, {0x00ab00f3, 0x009d00f3}, {0x00d70132, 0x00c70133}, {0x010f0181, 0x00fb0183}, {0x015601e5, 0x013d01e8}, {0x01af0264, 0x01900268}, {0x021f0303, 0x01f90309}, {0x02ac03cb, 0x027e03d5}, {0x035e04c8, 0x032604d5}, {0x043e0606, 0x03fa061a}, {0x057a07c7, 0x050707b3}, {0x06f909e6, 0x065a09b8}, {0x08770c05, 0x08060c45}, {0x0af50f8e, 0x0a240f7e}, {0x0d721317, 0x0cd1138f}, {0x10ef180a, 0x103418b2}, {0x156a1e67, 0x147b1f30}, {0x1ae5262e, 0x19e52762}, {0x225d30c9, 0x20be31bd}, {0x2ad53cce, 0x29673ed2}, {0x36494d11, 0x345c4f59}, {0x443b60dd, 0x423a643c}, {0x56297a51, 0x53c57e9f}, {0x6c939a22, 0x69f99ff9}, {0x8877c1ba, 0x8613ca1e}, {0xabd3ffef, 0xa9a4ffef}, {0xd8a6ffef, 0xd6aaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef}, {0xfffaffef, 0xfffaffef} }; typedef enum _CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_ME_CM { CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE_CM = 0, CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE_CM = 1, CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE_CM = 1, CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE_CM = 2, CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION_CM = 3, CODECHAL_ENCODE_AVC_ME_RESERVED0_CM = 4, CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF_CM = 5, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX0_CM = 6, CODECHAL_ENCODE_AVC_ME_RESERVED1_CM = 7, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX1_CM = 8, CODECHAL_ENCODE_AVC_ME_RESERVED2_CM = 9, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX2_CM = 10, CODECHAL_ENCODE_AVC_ME_RESERVED3_CM = 11, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX3_CM = 12, CODECHAL_ENCODE_AVC_ME_RESERVED4_CM = 13, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX4_CM = 14, CODECHAL_ENCODE_AVC_ME_RESERVED5_CM = 15, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX5_CM = 16, CODECHAL_ENCODE_AVC_ME_RESERVED6_CM = 17, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX6_CM = 18, CODECHAL_ENCODE_AVC_ME_RESERVED7_CM = 19, CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX7_CM = 20, CODECHAL_ENCODE_AVC_ME_RESERVED8_CM = 21, CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF_CM = 22, CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX0_CM = 23, CODECHAL_ENCODE_AVC_ME_RESERVED9_CM = 24, CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX1_CM = 25, CODECHAL_ENCODE_AVC_ME_VDENC_STREAMIN_CM = 26, CODECHAL_ENCODE_AVC_ME_NUM_SURFACES_CM = 27 } CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_ME_CM; // binding table for State Content Detection typedef enum _CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_SFD_COMMON { CODECHAL_ENCODE_AVC_SFD_VDENC_INPUT_IMAGE_STATE_COMMON = 0, CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON = 1, CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON = 2, CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON = 3, CODECHAL_ENCODE_AVC_SFD_VDENC_OUTPUT_IMAGE_STATE_COMMON = 4, CODECHAL_ENCODE_AVC_SFD_NUM_SURFACES = 5 } CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_SFD_COMMON; // QP is from 0 - 51, pad it to 64 since BRC needs array size to be 64 bytes const uint8_t CodechalEncodeAvcEnc::IntraScalingFactor_Cm_Common[64] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // QP is from 0 - 51, pad it to 64 since BRC needs array size to be 64 bytes const uint8_t CodechalEncodeAvcEnc::AdaptiveIntraScalingFactor_Cm_Common[64] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const uint32_t CodechalEncodeAvcEnc::OldIntraModeCost_Cm_Common[CODEC_AVC_NUM_QP] = { 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x1e03000a, 0x2e06001a, 0x2e06001a, 0x2e06001a, 0x2e06001a, 0x3b09001f, 0x3b09001f, 0x3b09001f, 0x3e0c002a, 0x3e0c002a, 0x3e0c002a, 0x490f002d, 0x4b19002f, 0x4b19002f, 0x4c1b0039, 0x4e1c003a, 0x581e003b, 0x591f003d, 0x5a28003e, 0x5b2a0048, 0x5c2b0049, 0x5e2c004a, 0x682e004b, 0x692f004d, 0x6a39004e, 0x6b390058, 0x6d3b0059, 0x6e3c005a, 0x783e005b, 0x793f005d, 0x7a48005e, 0x7b4a0068, 0x7c4b0069, 0x7e4c006a, 0x884e006b, 0x894f006d, 0x8a59006e }; const uint32_t CodechalEncodeAvcEnc::MvCost_PSkipAdjustment_Cm_Common[CODEC_AVC_NUM_QP] = { 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x09060500, 0x190c0a00, 0x190c0a00, 0x190c0a00, 0x190c0a00, 0x1e190f00, 0x1e190f00, 0x1e190f00, 0x291c1a00, 0x291c1a00, 0x291c1a00, 0x2b1f1d00, 0x2e291f00, 0x2e291f00, 0x382b2900, 0x392c2a00, 0x3a2e2b00, 0x3b2f2d00, 0x3c382e00, 0x3f3a3800, 0x483b3900, 0x493c3a00, 0x4a3e3b00, 0x4b3f3d00, 0x4d493e00, 0x4e494800, 0x584b4900, 0x594c4a00, 0x5a4e4b00, 0x5b4f4d00, 0x5d584e00, 0x5e5a5800, 0x685b5900, 0x695c5a00, 0x6a5e5b00, 0x6b5f5d00, 0x6d695e00 }; const uint16_t CodechalEncodeAvcEnc::SkipVal_B_Common[2][2][64] = { { // Block Based Skip = 0 and Transform Flag = 0 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0024, 0x0024, 0x0060, 0x0060, 0x0099, 0x0099, 0x00cf, 0x00cf, 0x0105, 0x0105, 0x0141, 0x0141, 0x0183, 0x0183, 0x01ce, 0x01ce, 0x0228, 0x0228, 0x0291, 0x0291, 0x030c, 0x030c, 0x039f, 0x039f, 0x0447, 0x0447, 0x050d, 0x050d, 0x05f1, 0x05f1, 0x06f6, 0x06f6, 0x0822, 0x0822, 0x0972, 0x0972, 0x0aef, 0x0aef, 0x0c96, 0x0c96, 0x0e70, 0x0e70, 0x107a, 0x107a, 0x1284, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, // Block Based Skip = 0 and Transform Flag = 1 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0024, 0x0024, 0x0060, 0x0060, 0x0099, 0x0099, 0x00cf, 0x00cf, 0x0105, 0x0105, 0x0141, 0x0141, 0x0183, 0x0183, 0x01ce, 0x01ce, 0x0228, 0x0228, 0x0291, 0x0291, 0x030c, 0x030c, 0x039f, 0x039f, 0x0447, 0x0447, 0x050d, 0x050d, 0x05f1, 0x05f1, 0x06f6, 0x06f6, 0x0822, 0x0822, 0x0972, 0x0972, 0x0aef, 0x0aef, 0x0c96, 0x0c96, 0x0e70, 0x0e70, 0x107a, 0x107a, 0x1284, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } }, { // Block Based Skip = 1 and Transform Flag = 0 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x0010, 0x0010, 0x0019, 0x0019, 0x0022, 0x0022, 0x002b, 0x002b, 0x0035, 0x0035, 0x0040, 0x0040, 0x004d, 0x004d, 0x005c, 0x005c, 0x006d, 0x006d, 0x0082, 0x0082, 0x009a, 0x009a, 0x00b6, 0x00b6, 0x00d7, 0x00d7, 0x00fd, 0x00fd, 0x0129, 0x0129, 0x015b, 0x015b, 0x0193, 0x0193, 0x01d2, 0x01d2, 0x0219, 0x0219, 0x0268, 0x0268, 0x02bf, 0x02bf, 0x0316, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, // Block Based Skip = 1 and Transform Flag = 1 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, 0x000c, 0x0020, 0x0020, 0x0033, 0x0033, 0x0045, 0x0045, 0x0057, 0x0057, 0x006b, 0x006b, 0x0081, 0x0081, 0x009a, 0x009a, 0x00b8, 0x00b8, 0x00db, 0x00db, 0x0104, 0x0104, 0x0135, 0x0135, 0x016d, 0x016d, 0x01af, 0x01af, 0x01fb, 0x01fb, 0x0252, 0x0252, 0x02b6, 0x02b6, 0x0326, 0x0326, 0x03a5, 0x03a5, 0x0432, 0x0432, 0x04d0, 0x04d0, 0x057e, 0x057e, 0x062c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } } }; // AVC MBEnc SkipVal Table, index [BlockBasedSkip][TransformFlag][SliceQP] // QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes. const uint16_t CodechalEncodeAvcEnc::SkipVal_P_Common[2][2][64] = { { // Block Based Skip = 0 and Transform Flag = 0 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x000c, 0x000c, 0x0015, 0x0015, 0x0021, 0x0021, 0x0033, 0x0033, 0x004b, 0x004b, 0x0069, 0x0069, 0x0096, 0x0096, 0x00cc, 0x00cc, 0x0111, 0x0111, 0x0165, 0x0165, 0x01cb, 0x01cb, 0x0246, 0x0246, 0x02d3, 0x02d3, 0x0378, 0x0378, 0x0438, 0x0438, 0x0510, 0x0510, 0x0603, 0x0603, 0x0714, 0x0714, 0x0846, 0x0846, 0x0999, 0x0999, 0x0b10, 0x0b10, 0x0c3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, // Block Based Skip = 0 and Transform Flag = 1 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x000c, 0x000c, 0x0015, 0x0015, 0x0021, 0x0021, 0x0033, 0x0033, 0x004b, 0x004b, 0x0069, 0x0069, 0x0096, 0x0096, 0x00cc, 0x00cc, 0x0111, 0x0111, 0x0165, 0x0165, 0x01cb, 0x01cb, 0x0246, 0x0246, 0x02d3, 0x02d3, 0x0378, 0x0378, 0x0438, 0x0438, 0x0510, 0x0510, 0x0603, 0x0603, 0x0714, 0x0714, 0x0846, 0x0846, 0x0999, 0x0999, 0x0b10, 0x0b10, 0x0c3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } }, { // Block Based Skip = 1 and Transform Flag = 0 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0002, 0x0002, 0x0003, 0x0003, 0x0005, 0x0005, 0x0008, 0x0008, 0x000c, 0x000c, 0x0011, 0x0011, 0x0019, 0x0019, 0x0022, 0x0022, 0x002d, 0x002d, 0x003b, 0x003b, 0x004c, 0x004c, 0x0061, 0x0061, 0x0078, 0x0078, 0x0094, 0x0094, 0x00b4, 0x00b4, 0x00d8, 0x00d8, 0x0100, 0x0100, 0x012e, 0x012e, 0x0161, 0x0161, 0x0199, 0x0199, 0x01d8, 0x01d8, 0x020a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, // Block Based Skip = 1 and Transform Flag = 1 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0004, 0x0004, 0x0007, 0x0007, 0x000b, 0x000b, 0x0011, 0x0011, 0x0019, 0x0019, 0x0023, 0x0023, 0x0032, 0x0032, 0x0044, 0x0044, 0x005b, 0x005b, 0x0077, 0x0077, 0x0099, 0x0099, 0x00c2, 0x00c2, 0x00f1, 0x00f1, 0x0128, 0x0128, 0x0168, 0x0168, 0x01b0, 0x01b0, 0x0201, 0x0201, 0x025c, 0x025c, 0x02c2, 0x02c2, 0x0333, 0x0333, 0x03b0, 0x03b0, 0x0414, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } } }; const uint32_t CodechalEncodeAvcEnc::PreProcFtqLut_Cm_Common[CODEC_AVC_NUM_QP][16] = { //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3), MVCOST(4), QP(5), FTQ Thds(6), FTQ Thds(7), RefCost(8), SkipVal(9), IntraSF(10) ,Zero(11), Zero(12), Zero(13), Zero(14) , Zero(15) { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff040404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff070707, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff080808, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff090909, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0a0a0a, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0b0b0b, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0c0c0c, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0d0d0d, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0e0e0e, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff101010, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff111111, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff121212, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff131313, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff141414, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff151515, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff161616, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff171717, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff181818, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff191919, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1d1d1d, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1e1e1e, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1f1f1f, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff202020, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff212121, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff222222, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff232323, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff242424, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff252525, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff262626, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff272727, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff282828, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff292929, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2a2a2a, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2d2d2d, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2e2e2e, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff303030, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff313131, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff323232, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff333333, 0x73730073, 0x73737373, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }; // SkipVal (DW offset 9) in the following table needs to be changed by Driver based on the BlockbasedSkip and Transform Flag. // Kernel indexes this table based on the MB QP. it's different with g75, but mainline did not support g75 anymore const uint32_t CodechalEncodeAvcEnc::MBBrcConstantData_Cm_Common[3][CODEC_AVC_NUM_QP][16] = { //I-slice { //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3), MVCOST(4), QP(5), FTQ Thds(6), FTQ Thds(7), RefCost(8), SkipVal(9), IntraSF(10) ,Zero(11), Zero(12), Zero(13), Zero(14) , Zero(15) { 0x0d000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x0f000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x19000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x1a000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x1b000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff040404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x1c000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x1e000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x28000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff070707, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x29000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff080808, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x2a00000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff090909, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x2b00000b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0a0a0a, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x2c00000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0b0b0b, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x2e00000e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0c0c0c, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x38000018, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0d0d0d, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x39000019, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0e0e0e, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a00001b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3b00001c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff101010, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3c00001d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff111111, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3e00001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff121212, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x48020028, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff131313, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x49020029, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff141414, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4a03002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff151515, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4b03002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff161616, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4c04002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff171717, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4e04002c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff181818, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5805002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff191919, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5905002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5a06002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5b07002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5c080039, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1d1d1d, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5e09003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1e1e1e, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6828003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1f1f1f, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6929003b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff202020, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6a2a003c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff212121, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6b2c003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff222222, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6c3a003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff232323, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6e3b0048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff242424, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x783c0049, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff252525, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x793e004a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff262626, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7a3e004b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff272727, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7b48004c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff282828, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7c49004e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff292929, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7e4a0058, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2a2a2a, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x884d0059, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x894f005a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8a58005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2d2d2d, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8b59005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2e2e2e, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8c5c005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8e5d005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff303030, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f5f005d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff313131, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f68005f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff323232, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f690068, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff333333, 0x73730073, 0x73737373, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, //P-slice { //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3), MVCOST(4), QP(5), FTQ Thds(6), FTQ Thds(7), RefCost(8), SkipVal(9), IntraSF(10) ,Zero(11), Zero(12), Zero(13), Zero(14) , Zero(15) { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff040404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff070707, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff080808, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff090909, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff131313, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff141414, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff151515, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff161616, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff171717, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff181818, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5b493d29, 0x281c0d2b, 0x001a001e, 0x2b1d1a05, 0x39392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5f4c492c, 0x2c28192f, 0x001e002a, 0x38291e07, 0x3d3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x694e4a2e, 0x2d291b39, 0x0028002b, 0x392a2808, 0x3f3e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6a584b38, 0x2f2a1c3a, 0x0029002c, 0x3a2b2909, 0x48483e3b, 0xff1f1f1f, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6b594d39, 0x382c1d3b, 0x002a002e, 0x3b2d2a0a, 0x49493f3d, 0xff202020, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6c5a4e3a, 0x392d1f3c, 0x002b002f, 0x3c2e2b0b, 0x4a4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6e5b583b, 0x3b2f293e, 0x002d0039, 0x3f382d0d, 0x4c4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6f5c593c, 0x3c38293f, 0x002e003a, 0x48392e0e, 0x4d4c4b49, 0xff232323, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x795e5a3e, 0x3d392b49, 0x0038003b, 0x493a3818, 0x4f4e4c4a, 0xff242424, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7a685b48, 0x3f3a2c4a, 0x0039003c, 0x4a3b3919, 0x58584e4b, 0xff252525, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7b695d49, 0x483c2d4b, 0x003a003e, 0x4b3d3a1a, 0x59594f4d, 0xff262626, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7d6a5e4a, 0x4a3d2f4c, 0x003c0048, 0x4d3e3c1c, 0x5b5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7e6b684b, 0x4a3e384d, 0x003d0049, 0x4e483d1d, 0x5c5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x886d694d, 0x4c483a4f, 0x003f004a, 0x58493f1f, 0x5e5d5b59, 0xff292929, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x896e6a4e, 0x4d493b59, 0x0048004b, 0x594a4828, 0x5f5e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8a786b58, 0x4f4a3c5a, 0x0049004c, 0x5a4b4929, 0x68685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8b796d59, 0x584c3d5b, 0x004a004e, 0x5b4d4a2a, 0x69695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8c7a6e5a, 0x594d3f5c, 0x004b004f, 0x5d4e4b2b, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8e7b785b, 0x5b4f485e, 0x004d0059, 0x5e584d2d, 0x6c6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f7c795c, 0x5c58495f, 0x004e005a, 0x68594e2e, 0x6d6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f7e7a5e, 0x5d594b69, 0x0058005b, 0x695a5838, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f887b68, 0x5f5a4c6a, 0x0059005c, 0x6a5b5939, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f897d69, 0x685c4d6b, 0x005a005e, 0x6b5d5a3a, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f8a7e6a, 0x695d4f6c, 0x005b0068, 0x6d5e5b3b, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, //B-slice { //ModeCOST(0), ModeCOST(1), ModeCOST(2), MVCOST(3), MVCOST(4), QP(5), FTQ Thds(6), FTQ Thds(7), RefCost(8), SkipVal(9), IntraSF(10) ,Zero(11), Zero(12), Zero(13), Zero(14) , Zero(15) { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff030303, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff040404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff050505, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff060606, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff070707, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff080808, 0x01010001, 0x01010101, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff090909, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff131313, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff141414, 0x10100010, 0x10101010, 0x00000000, 0x00000000, 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff151515, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff161616, 0x13130013, 0x13131313, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff171717, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff181818, 0x16160016, 0x16161616, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5d4d4b29, 0x2d2b282f, 0x001a0a1f, 0x1f0a0a00, 0x3a392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x69594f2c, 0x392f2b3b, 0x001e0e2b, 0x2b0e0e00, 0x3e3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6a5a592e, 0x3b392d3c, 0x0028182c, 0x2c181800, 0x483e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6b5b5a38, 0x3c3a2f3e, 0x0029192e, 0x2e191900, 0x49483e3b, 0xff1f1f1f, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6d5d5b39, 0x3d3b383f, 0x002a1a2f, 0x2f1a1a00, 0x4a493f3d, 0xff202020, 0x27270027, 0x27272727, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x6e5e5c3a, 0x3e3c3948, 0x002b1b38, 0x381b1b00, 0x4b4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x78685e3b, 0x493e3b4a, 0x002d1d3a, 0x3a1d1d00, 0x4d4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x79695f3c, 0x493f3b4b, 0x002e1e3b, 0x3b1e1e00, 0x4e4c4b49, 0xff232323, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7a6a693e, 0x4b493d4c, 0x0038283c, 0x3c282800, 0x584e4c4a, 0xff242424, 0x32320032, 0x32323232, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7b6b6a48, 0x4c4a3f4e, 0x0039293e, 0x3e292900, 0x59584e4b, 0xff252525, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7d6d6b49, 0x4d4b484f, 0x003a2a3f, 0x3f2a2a00, 0x5a594f4d, 0xff262626, 0x38380038, 0x38383838, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x7e6e6c4a, 0x4f4c4959, 0x003c2c49, 0x492c2c00, 0x5c5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x88786d4b, 0x584d4a59, 0x003d2d49, 0x492d2d00, 0x5d5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x89796f4d, 0x5a4f4c5b, 0x003f2f4b, 0x4b2f2f00, 0x5f5d5b59, 0xff292929, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8a7a794e, 0x5b594d5c, 0x0048384c, 0x4c383800, 0x685e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8b7b7a58, 0x5c5a4f5e, 0x0049394e, 0x4e393900, 0x69685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8d7d7b59, 0x5d5b585f, 0x004a3a4f, 0x4f3a3a00, 0x6a695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8e7e7c5a, 0x5f5c5968, 0x004b3b58, 0x583b3b00, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f887e5b, 0x685e5a6a, 0x004d3d5a, 0x5a3d3d00, 0x6d6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f897f5c, 0x695f5c6b, 0x004e3e5b, 0x5b3e3e00, 0x6e6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f8a895e, 0x6b695d6c, 0x0058485c, 0x5c484800, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f8b8a68, 0x6c6a5f6e, 0x0059495e, 0x5e494900, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f8d8b69, 0x6d6b686f, 0x005a4a5f, 0x5f4a4a00, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x8f8e8c6a, 0x6f6c6979, 0x005b4b69, 0x694b4b00, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } } }; // AVC MBEnc ModeCost and MVCost tables, index [CodingType][QP] and const uint32_t CodechalEncodeAvcEnc::ModeMvCost_Common[3][CODEC_AVC_NUM_QP][8] = { // I-Frame { { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff010101, 0x00000000, 0x00000000 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff020202, 0x00000000, 0x00000000 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff030303, 0x00000000, 0x00000000 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff040404, 0x00000000, 0x00000000 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff050505, 0x00000000, 0x00000000 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff060606, 0x00000000, 0x00000000 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff070707, 0x01010001, 0x01010101 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff080808, 0x01010001, 0x01010101 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff090909, 0x03030003, 0x03030303 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0a0a0a, 0x03030003, 0x03030303 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0b0b0b, 0x06060006, 0x06060606 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0c0c0c, 0x06060006, 0x06060606 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0d0d0d, 0x08080008, 0x08080808 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0e0e0e, 0x08080008, 0x08080808 }, { 0x1e03000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b }, { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff101010, 0x0b0b000b, 0x0b0b0b0b }, { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff111111, 0x0d0d000d, 0x0d0d0d0d }, { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff121212, 0x0d0d000d, 0x0d0d0d0d }, { 0x2e06001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff131313, 0x10100010, 0x10101010 }, { 0x3b09001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff141414, 0x10100010, 0x10101010 }, { 0x3b09001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff151515, 0x13130013, 0x13131313 }, { 0x3b09001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff161616, 0x13130013, 0x13131313 }, { 0x3e0c002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff171717, 0x16160016, 0x16161616 }, { 0x3e0c002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff181818, 0x16160016, 0x16161616 }, { 0x3e0c002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff191919, 0x1a1a001a, 0x1a1a1a1a }, { 0x490f002d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a }, { 0x4b19002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e }, { 0x4b19002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e }, { 0x4c1b0039, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1d1d1d, 0x22220022, 0x22222222 }, { 0x4e1c003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1e1e1e, 0x22220022, 0x22222222 }, { 0x581e003b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1f1f1f, 0x27270027, 0x27272727 }, { 0x591f003d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff202020, 0x27270027, 0x27272727 }, { 0x5a28003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff212121, 0x2c2c002c, 0x2c2c2c2c }, { 0x5b2a0048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff222222, 0x2c2c002c, 0x2c2c2c2c }, { 0x5c2b0049, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff232323, 0x32320032, 0x32323232 }, { 0x5e2c004a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff242424, 0x32320032, 0x32323232 }, { 0x682e004b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff252525, 0x38380038, 0x38383838 }, { 0x692f004d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff262626, 0x38380038, 0x38383838 }, { 0x6a39004e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff272727, 0x3e3e003e, 0x3e3e3e3e }, { 0x6b390058, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff282828, 0x3e3e003e, 0x3e3e3e3e }, { 0x6d3b0059, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff292929, 0x45450045, 0x45454545 }, { 0x6e3c005a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2a2a2a, 0x45450045, 0x45454545 }, { 0x783e005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d }, { 0x793f005d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d }, { 0x7a48005e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2d2d2d, 0x55550055, 0x55555555 }, { 0x7b4a0068, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2e2e2e, 0x55550055, 0x55555555 }, { 0x7c4b0069, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e }, { 0x7e4c006a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff303030, 0x5e5e005e, 0x5e5e5e5e }, { 0x884e006b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff313131, 0x68680068, 0x68686868 }, { 0x894f006d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff323232, 0x68680068, 0x68686868 }, { 0x8a59006e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff333333, 0x73730073, 0x73737373 }, }, // P-Frame { { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff010101, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff020202, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff030303, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff040404, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff050505, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff060606, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff070707, 0x01010001, 0x01010101 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff080808, 0x01010001, 0x01010101 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff090909, 0x03030003, 0x03030303 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff131313, 0x10100010, 0x10101010 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff141414, 0x10100010, 0x10101010 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff151515, 0x13130013, 0x13131313 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff161616, 0x13130013, 0x13131313 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff171717, 0x16160016, 0x16161616 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff181818, 0x16160016, 0x16161616 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a }, { 0x5b493d29, 0x281c0d2b, 0x001a001e, 0x2b1d1a05, 0x39392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a }, { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e }, { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e }, { 0x5f4c492c, 0x2c28192f, 0x001e002a, 0x38291e07, 0x3d3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 }, { 0x694e4a2e, 0x2d291b39, 0x0028002b, 0x392a2808, 0x3f3e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 }, { 0x6a584b38, 0x2f2a1c3a, 0x0029002c, 0x3a2b2909, 0x48483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 }, { 0x6b594d39, 0x382c1d3b, 0x002a002e, 0x3b2d2a0a, 0x49493f3d, 0xff202020, 0x27270027, 0x27272727 }, { 0x6c5a4e3a, 0x392d1f3c, 0x002b002f, 0x3c2e2b0b, 0x4a4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c }, { 0x6e5b583b, 0x3b2f293e, 0x002d0039, 0x3f382d0d, 0x4c4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c }, { 0x6f5c593c, 0x3c38293f, 0x002e003a, 0x48392e0e, 0x4d4c4b49, 0xff232323, 0x32320032, 0x32323232 }, { 0x795e5a3e, 0x3d392b49, 0x0038003b, 0x493a3818, 0x4f4e4c4a, 0xff242424, 0x32320032, 0x32323232 }, { 0x7a685b48, 0x3f3a2c4a, 0x0039003c, 0x4a3b3919, 0x58584e4b, 0xff252525, 0x38380038, 0x38383838 }, { 0x7b695d49, 0x483c2d4b, 0x003a003e, 0x4b3d3a1a, 0x59594f4d, 0xff262626, 0x38380038, 0x38383838 }, { 0x7d6a5e4a, 0x4a3d2f4c, 0x003c0048, 0x4d3e3c1c, 0x5b5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e }, { 0x7e6b684b, 0x4a3e384d, 0x003d0049, 0x4e483d1d, 0x5c5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e }, { 0x886d694d, 0x4c483a4f, 0x003f004a, 0x58493f1f, 0x5e5d5b59, 0xff292929, 0x45450045, 0x45454545 }, { 0x896e6a4e, 0x4d493b59, 0x0048004b, 0x594a4828, 0x5f5e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 }, { 0x8a786b58, 0x4f4a3c5a, 0x0049004c, 0x5a4b4929, 0x68685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d }, { 0x8b796d59, 0x584c3d5b, 0x004a004e, 0x5b4d4a2a, 0x69695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d }, { 0x8c7a6e5a, 0x594d3f5c, 0x004b004f, 0x5d4e4b2b, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 }, { 0x8e7b785b, 0x5b4f485e, 0x004d0059, 0x5e584d2d, 0x6c6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 }, { 0x8f7c795c, 0x5c58495f, 0x004e005a, 0x68594e2e, 0x6d6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f7e7a5e, 0x5d594b69, 0x0058005b, 0x695a5838, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f887b68, 0x5f5a4c6a, 0x0059005c, 0x6a5b5939, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 }, { 0x8f897d69, 0x685c4d6b, 0x005a005e, 0x6b5d5a3a, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 }, { 0x8f8a7e6a, 0x695d4f6c, 0x005b0068, 0x6d5e5b3b, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 }, }, // B-Frame { { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff010101, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff020202, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff030303, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff040404, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff050505, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff060606, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff070707, 0x01010001, 0x01010101 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff080808, 0x01010001, 0x01010101 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff090909, 0x03030003, 0x03030303 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff131313, 0x10100010, 0x10101010 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff141414, 0x10100010, 0x10101010 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff151515, 0x13130013, 0x13131313 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff161616, 0x13130013, 0x13131313 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff171717, 0x16160016, 0x16161616 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff181818, 0x16160016, 0x16161616 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a }, { 0x5d4d4b29, 0x2d2b282f, 0x001a0a1f, 0x1f0a0a00, 0x3a392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a }, { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e }, { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e }, { 0x69594f2c, 0x392f2b3b, 0x001e0e2b, 0x2b0e0e00, 0x3e3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 }, { 0x6a5a592e, 0x3b392d3c, 0x0028182c, 0x2c181800, 0x483e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 }, { 0x6b5b5a38, 0x3c3a2f3e, 0x0029192e, 0x2e191900, 0x49483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 }, { 0x6d5d5b39, 0x3d3b383f, 0x002a1a2f, 0x2f1a1a00, 0x4a493f3d, 0xff202020, 0x27270027, 0x27272727 }, { 0x6e5e5c3a, 0x3e3c3948, 0x002b1b38, 0x381b1b00, 0x4b4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c }, { 0x78685e3b, 0x493e3b4a, 0x002d1d3a, 0x3a1d1d00, 0x4d4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c }, { 0x79695f3c, 0x493f3b4b, 0x002e1e3b, 0x3b1e1e00, 0x4e4c4b49, 0xff232323, 0x32320032, 0x32323232 }, { 0x7a6a693e, 0x4b493d4c, 0x0038283c, 0x3c282800, 0x584e4c4a, 0xff242424, 0x32320032, 0x32323232 }, { 0x7b6b6a48, 0x4c4a3f4e, 0x0039293e, 0x3e292900, 0x59584e4b, 0xff252525, 0x38380038, 0x38383838 }, { 0x7d6d6b49, 0x4d4b484f, 0x003a2a3f, 0x3f2a2a00, 0x5a594f4d, 0xff262626, 0x38380038, 0x38383838 }, { 0x7e6e6c4a, 0x4f4c4959, 0x003c2c49, 0x492c2c00, 0x5c5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e }, { 0x88786d4b, 0x584d4a59, 0x003d2d49, 0x492d2d00, 0x5d5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e }, { 0x89796f4d, 0x5a4f4c5b, 0x003f2f4b, 0x4b2f2f00, 0x5f5d5b59, 0xff292929, 0x45450045, 0x45454545 }, { 0x8a7a794e, 0x5b594d5c, 0x0048384c, 0x4c383800, 0x685e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 }, { 0x8b7b7a58, 0x5c5a4f5e, 0x0049394e, 0x4e393900, 0x69685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d }, { 0x8d7d7b59, 0x5d5b585f, 0x004a3a4f, 0x4f3a3a00, 0x6a695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d }, { 0x8e7e7c5a, 0x5f5c5968, 0x004b3b58, 0x583b3b00, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 }, { 0x8f887e5b, 0x685e5a6a, 0x004d3d5a, 0x5a3d3d00, 0x6d6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 }, { 0x8f897f5c, 0x695f5c6b, 0x004e3e5b, 0x5b3e3e00, 0x6e6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f8a895e, 0x6b695d6c, 0x0058485c, 0x5c484800, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f8b8a68, 0x6c6a5f6e, 0x0059495e, 0x5e494900, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 }, { 0x8f8d8b69, 0x6d6b686f, 0x005a4a5f, 0x5f4a4a00, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 }, { 0x8f8e8c6a, 0x6f6c6979, 0x005b4b69, 0x694b4b00, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 }, } }; // AVC MBEnc RefCost tables, index [CodingType][QP] // QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes const uint16_t CodechalEncodeAvcEnc::RefCost_Common[3][64] = { // I-frame { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, // P-slice { 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 0x0008, 0x0008, 0x0008, 0x000C, 0x000C, 0x000C, 0x0010, 0x0010, 0x0010, 0x0014, 0x0018, 0x0018, 0x001C, 0x0020, 0x0024, 0x0028, 0x002C, 0x0034, 0x0038, 0x0040, 0x0048, 0x0050, 0x005C, 0x0064, 0x0074, 0x0080, 0x0090, 0x00A0, 0x00B4, 0x00CC, 0x00E4, 0x0100, 0x0120, 0x0144, 0x016C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, //B-slice { 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 0x0008, 0x0008, 0x0008, 0x000C, 0x000C, 0x000C, 0x0010, 0x0010, 0x0010, 0x0014, 0x0018, 0x0018, 0x001C, 0x0020, 0x0024, 0x0028, 0x002C, 0x0034, 0x0038, 0x0040, 0x0048, 0x0050, 0x005C, 0x0064, 0x0074, 0x0080, 0x0090, 0x00A0, 0x00B4, 0x00CC, 0x00E4, 0x0100, 0x0120, 0x0144, 0x016C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } }; const uint8_t CodechalEncodeAvcEnc::MaxRefIdx0_Progressive_4K[NUM_TARGET_USAGE_MODES] = { 0, 3, 3, 2, 2, 2, 0, 0 }; const uint8_t CodechalEncodeAvcEnc::MaxRefIdx0[NUM_TARGET_USAGE_MODES] = { 0, 7, 5, 2, 2, 2, 0, 0 }; const uint8_t CodechalEncodeAvcEnc::MaxBRefIdx0[NUM_TARGET_USAGE_MODES] = { 0, 3, 3, 1, 1, 1, 0, 0 }; const uint8_t CodechalEncodeAvcEnc::MaxRefIdx1[NUM_TARGET_USAGE_MODES] = { 0, 1, 1, 1, 1, 1, 0, 0 }; const uint32_t CodechalEncodeAvcEnc::SuperHME[NUM_TARGET_USAGE_MODES] = { 0, 1, 1, 1, 1, 1, 1, 1 }; const uint32_t CodechalEncodeAvcEnc::UltraHME[NUM_TARGET_USAGE_MODES] = { 0, 1, 1, 1, 1, 1, 1, 0 }; const uint32_t CodechalEncodeAvcEnc::ModeMvCost_Cm[3][52][8] = { // I-Frame { { 0x0d000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000 }, { 0x0f000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff010101, 0x00000000, 0x00000000 }, { 0x19000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff020202, 0x00000000, 0x00000000 }, { 0x1a000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff030303, 0x00000000, 0x00000000 }, { 0x1b000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff040404, 0x00000000, 0x00000000 }, { 0x1c000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff050505, 0x00000000, 0x00000000 }, { 0x1e000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff060606, 0x00000000, 0x00000000 }, { 0x28000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff070707, 0x01010001, 0x01010101 }, { 0x29000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff080808, 0x01010001, 0x01010101 }, { 0x2a00000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff090909, 0x03030003, 0x03030303 }, { 0x2b00000b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0a0a0a, 0x03030003, 0x03030303 }, { 0x2c00000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0b0b0b, 0x06060006, 0x06060606 }, { 0x2e00000e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0c0c0c, 0x06060006, 0x06060606 }, { 0x38000018, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0d0d0d, 0x08080008, 0x08080808 }, { 0x39000019, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0e0e0e, 0x08080008, 0x08080808 }, { 0x3a00001b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b }, { 0x3b00001c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff101010, 0x0b0b000b, 0x0b0b0b0b }, { 0x3c00001d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff111111, 0x0d0d000d, 0x0d0d0d0d }, { 0x3e00001f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff121212, 0x0d0d000d, 0x0d0d0d0d }, { 0x48020028, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff131313, 0x10100010, 0x10101010 }, { 0x49020029, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff141414, 0x10100010, 0x10101010 }, { 0x4a03002a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff151515, 0x13130013, 0x13131313 }, { 0x4b03002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff161616, 0x13130013, 0x13131313 }, { 0x4c04002b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff171717, 0x16160016, 0x16161616 }, { 0x4e04002c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff181818, 0x16160016, 0x16161616 }, { 0x5805002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff191919, 0x1a1a001a, 0x1a1a1a1a }, { 0x5905002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a }, { 0x5a06002e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e }, { 0x5b07002f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e }, { 0x5c080039, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1d1d1d, 0x22220022, 0x22222222 }, { 0x5e09003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1e1e1e, 0x22220022, 0x22222222 }, { 0x6828003a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff1f1f1f, 0x27270027, 0x27272727 }, { 0x6929003b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff202020, 0x27270027, 0x27272727 }, { 0x6a2a003c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff212121, 0x2c2c002c, 0x2c2c2c2c }, { 0x6b2c003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff222222, 0x2c2c002c, 0x2c2c2c2c }, { 0x6c3a003e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff232323, 0x32320032, 0x32323232 }, { 0x6e3b0048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff242424, 0x32320032, 0x32323232 }, { 0x783c0049, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff252525, 0x38380038, 0x38383838 }, { 0x793e004a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff262626, 0x38380038, 0x38383838 }, { 0x7a3e004b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff272727, 0x3e3e003e, 0x3e3e3e3e }, { 0x7b48004c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff282828, 0x3e3e003e, 0x3e3e3e3e }, { 0x7c49004e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff292929, 0x45450045, 0x45454545 }, { 0x7e4a0058, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2a2a2a, 0x45450045, 0x45454545 }, { 0x884d0059, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d }, { 0x894f005a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d }, { 0x8a58005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2d2d2d, 0x55550055, 0x55555555 }, { 0x8b59005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2e2e2e, 0x55550055, 0x55555555 }, { 0x8c5c005b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e }, { 0x8e5d005c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff303030, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f5f005d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff313131, 0x68680068, 0x68686868 }, { 0x8f68005f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff323232, 0x68680068, 0x68686868 }, { 0x8f690068, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff333333, 0x73730073, 0x73737373 } }, // P-Frame { { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff000000, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff010101, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff020202, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff030303, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff040404, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff050505, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff060606, 0x00000000, 0x00000000 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff070707, 0x01010001, 0x01010101 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff080808, 0x01010001, 0x01010101 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff090909, 0x03030003, 0x03030303 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 }, { 0x391e1a07, 0x06040208, 0x00040005, 0x09050401, 0x0f0e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d }, { 0x492e2a0e, 0x0d090519, 0x0008000b, 0x190a0802, 0x1f1e1c1a, 0xff131313, 0x10100010, 0x10101010 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff141414, 0x10100010, 0x10101010 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff151515, 0x13130013, 0x13131313 }, { 0x4d3b2f1b, 0x1a0d071d, 0x000c0018, 0x1e0f0c03, 0x2b2b291f, 0xff161616, 0x13130013, 0x13131313 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff171717, 0x16160016, 0x16161616 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff181818, 0x16160016, 0x16161616 }, { 0x593e3a1e, 0x1d190a29, 0x0018001b, 0x291a1804, 0x2f2e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a }, { 0x5b493d29, 0x281c0d2b, 0x001a001e, 0x2b1d1a05, 0x39392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a }, { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e }, { 0x5d4b3f2b, 0x2a1e0f2d, 0x001c0028, 0x2e1f1c06, 0x3b3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e }, { 0x5f4c492c, 0x2c28192f, 0x001e002a, 0x38291e07, 0x3d3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 }, { 0x694e4a2e, 0x2d291b39, 0x0028002b, 0x392a2808, 0x3f3e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 }, { 0x6a584b38, 0x2f2a1c3a, 0x0029002c, 0x3a2b2909, 0x48483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 }, { 0x6b594d39, 0x382c1d3b, 0x002a002e, 0x3b2d2a0a, 0x49493f3d, 0xff202020, 0x27270027, 0x27272727 }, { 0x6c5a4e3a, 0x392d1f3c, 0x002b002f, 0x3c2e2b0b, 0x4a4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c }, { 0x6e5b583b, 0x3b2f293e, 0x002d0039, 0x3f382d0d, 0x4c4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c }, { 0x6f5c593c, 0x3c38293f, 0x002e003a, 0x48392e0e, 0x4d4c4b49, 0xff232323, 0x32320032, 0x32323232 }, { 0x795e5a3e, 0x3d392b49, 0x0038003b, 0x493a3818, 0x4f4e4c4a, 0xff242424, 0x32320032, 0x32323232 }, { 0x7a685b48, 0x3f3a2c4a, 0x0039003c, 0x4a3b3919, 0x58584e4b, 0xff252525, 0x38380038, 0x38383838 }, { 0x7b695d49, 0x483c2d4b, 0x003a003e, 0x4b3d3a1a, 0x59594f4d, 0xff262626, 0x38380038, 0x38383838 }, { 0x7d6a5e4a, 0x4a3d2f4c, 0x003c0048, 0x4d3e3c1c, 0x5b5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e }, { 0x7e6b684b, 0x4a3e384d, 0x003d0049, 0x4e483d1d, 0x5c5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e }, { 0x886d694d, 0x4c483a4f, 0x003f004a, 0x58493f1f, 0x5e5d5b59, 0xff292929, 0x45450045, 0x45454545 }, { 0x896e6a4e, 0x4d493b59, 0x0048004b, 0x594a4828, 0x5f5e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 }, { 0x8a786b58, 0x4f4a3c5a, 0x0049004c, 0x5a4b4929, 0x68685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d }, { 0x8b796d59, 0x584c3d5b, 0x004a004e, 0x5b4d4a2a, 0x69695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d }, { 0x8c7a6e5a, 0x594d3f5c, 0x004b004f, 0x5d4e4b2b, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 }, { 0x8e7b785b, 0x5b4f485e, 0x004d0059, 0x5e584d2d, 0x6c6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 }, { 0x8f7c795c, 0x5c58495f, 0x004e005a, 0x68594e2e, 0x6d6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f7e7a5e, 0x5d594b69, 0x0058005b, 0x695a5838, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f887b68, 0x5f5a4c6a, 0x0059005c, 0x6a5b5939, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 }, { 0x8f897d69, 0x685c4d6b, 0x005a005e, 0x6b5d5a3a, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 }, { 0x8f8a7e6a, 0x695d4f6c, 0x005b0068, 0x6d5e5b3b, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 } }, // B-Frame { { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff000000, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff010101, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff020202, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff030303, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff040404, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff050505, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff060606, 0x00000000, 0x00000000 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff070707, 0x01010001, 0x01010101 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff080808, 0x01010001, 0x01010101 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff090909, 0x03030003, 0x03030303 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0a0a0a, 0x03030003, 0x03030303 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0b0b0b, 0x06060006, 0x06060606 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0c0c0c, 0x06060006, 0x06060606 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0d0d0d, 0x08080008, 0x08080808 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0e0e0e, 0x08080008, 0x08080808 }, { 0x3a2a2907, 0x0a08060c, 0x00040206, 0x06020200, 0x180e0c0a, 0xff0f0f0f, 0x0b0b000b, 0x0b0b0b0b }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff101010, 0x0b0b000b, 0x0b0b0b0b }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff111111, 0x0d0d000d, 0x0d0d0d0d }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff121212, 0x0d0d000d, 0x0d0d0d0d }, { 0x4a3a390e, 0x1b190d1c, 0x0008040c, 0x0c040400, 0x281e1c1a, 0xff131313, 0x10100010, 0x10101010 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff141414, 0x10100010, 0x10101010 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff151515, 0x13130013, 0x13131313 }, { 0x4f3f3d1b, 0x281d1a29, 0x000c0619, 0x19060600, 0x2c2b291f, 0xff161616, 0x13130013, 0x13131313 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff171717, 0x16160016, 0x16161616 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff181818, 0x16160016, 0x16161616 }, { 0x5a4a491e, 0x2b291d2c, 0x0018081c, 0x1c080800, 0x382e2c2a, 0xff191919, 0x1a1a001a, 0x1a1a1a1a }, { 0x5d4d4b29, 0x2d2b282f, 0x001a0a1f, 0x1f0a0a00, 0x3a392f2d, 0xff1a1a1a, 0x1a1a001a, 0x1a1a1a1a }, { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1b1b1b, 0x1e1e001e, 0x1e1e1e1e }, { 0x5f4f4d2b, 0x382d2a39, 0x001c0c29, 0x290c0c00, 0x3c3b392f, 0xff1c1c1c, 0x1e1e001e, 0x1e1e1e1e }, { 0x69594f2c, 0x392f2b3b, 0x001e0e2b, 0x2b0e0e00, 0x3e3c3b39, 0xff1d1d1d, 0x22220022, 0x22222222 }, { 0x6a5a592e, 0x3b392d3c, 0x0028182c, 0x2c181800, 0x483e3c3a, 0xff1e1e1e, 0x22220022, 0x22222222 }, { 0x6b5b5a38, 0x3c3a2f3e, 0x0029192e, 0x2e191900, 0x49483e3b, 0xff1f1f1f, 0x27270027, 0x27272727 }, { 0x6d5d5b39, 0x3d3b383f, 0x002a1a2f, 0x2f1a1a00, 0x4a493f3d, 0xff202020, 0x27270027, 0x27272727 }, { 0x6e5e5c3a, 0x3e3c3948, 0x002b1b38, 0x381b1b00, 0x4b4a483e, 0xff212121, 0x2c2c002c, 0x2c2c2c2c }, { 0x78685e3b, 0x493e3b4a, 0x002d1d3a, 0x3a1d1d00, 0x4d4b4a48, 0xff222222, 0x2c2c002c, 0x2c2c2c2c }, { 0x79695f3c, 0x493f3b4b, 0x002e1e3b, 0x3b1e1e00, 0x4e4c4b49, 0xff232323, 0x32320032, 0x32323232 }, { 0x7a6a693e, 0x4b493d4c, 0x0038283c, 0x3c282800, 0x584e4c4a, 0xff242424, 0x32320032, 0x32323232 }, { 0x7b6b6a48, 0x4c4a3f4e, 0x0039293e, 0x3e292900, 0x59584e4b, 0xff252525, 0x38380038, 0x38383838 }, { 0x7d6d6b49, 0x4d4b484f, 0x003a2a3f, 0x3f2a2a00, 0x5a594f4d, 0xff262626, 0x38380038, 0x38383838 }, { 0x7e6e6c4a, 0x4f4c4959, 0x003c2c49, 0x492c2c00, 0x5c5a594e, 0xff272727, 0x3e3e003e, 0x3e3e3e3e }, { 0x88786d4b, 0x584d4a59, 0x003d2d49, 0x492d2d00, 0x5d5b5958, 0xff282828, 0x3e3e003e, 0x3e3e3e3e }, { 0x89796f4d, 0x5a4f4c5b, 0x003f2f4b, 0x4b2f2f00, 0x5f5d5b59, 0xff292929, 0x45450045, 0x45454545 }, { 0x8a7a794e, 0x5b594d5c, 0x0048384c, 0x4c383800, 0x685e5c5a, 0xff2a2a2a, 0x45450045, 0x45454545 }, { 0x8b7b7a58, 0x5c5a4f5e, 0x0049394e, 0x4e393900, 0x69685e5b, 0xff2b2b2b, 0x4d4d004d, 0x4d4d4d4d }, { 0x8d7d7b59, 0x5d5b585f, 0x004a3a4f, 0x4f3a3a00, 0x6a695f5d, 0xff2c2c2c, 0x4d4d004d, 0x4d4d4d4d }, { 0x8e7e7c5a, 0x5f5c5968, 0x004b3b58, 0x583b3b00, 0x6b6a685e, 0xff2d2d2d, 0x55550055, 0x55555555 }, { 0x8f887e5b, 0x685e5a6a, 0x004d3d5a, 0x5a3d3d00, 0x6d6b6a68, 0xff2e2e2e, 0x55550055, 0x55555555 }, { 0x8f897f5c, 0x695f5c6b, 0x004e3e5b, 0x5b3e3e00, 0x6e6c6b69, 0xff2f2f2f, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f8a895e, 0x6b695d6c, 0x0058485c, 0x5c484800, 0x6f6e6c6a, 0xff303030, 0x5e5e005e, 0x5e5e5e5e }, { 0x8f8b8a68, 0x6c6a5f6e, 0x0059495e, 0x5e494900, 0x6f6f6e6b, 0xff313131, 0x68680068, 0x68686868 }, { 0x8f8d8b69, 0x6d6b686f, 0x005a4a5f, 0x5f4a4a00, 0x6f6f6f6d, 0xff323232, 0x68680068, 0x68686868 }, { 0x8f8e8c6a, 0x6f6c6979, 0x005b4b69, 0x694b4b00, 0x6f6f6f6e, 0xff333333, 0x73730073, 0x73737373 } } }; // QP is from 0 - 51, pad it to 64 since BRC needs array size to be 64 bytes const uint8_t CodechalEncodeAvcEnc::m_qpDistMaxFrameAdjustmentCm[576] = { 0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00, 0x01, 0x02, 0x03, 0xff, 0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xfe, 0xfe, 0xff, 0x00, 0x01, 0xfd, 0xfd, 0xff, 0xff, 0x00, 0xfb, 0xfd, 0xfe, 0xff, 0xff, 0xfa, 0xfb, 0xfd, 0xfe, 0xff, 0x00, 0x04, 0x1e, 0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x01, 0x01, 0x02, 0x03, 0xff, 0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff, 0xff, 0xff, 0x00, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x04, 0x1e, 0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00, 0x01, 0x01, 0x02, 0xff, 0x00, 0x00, 0x01, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff, 0xff, 0xff, 0x00, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x02, 0x14, 0x28, 0x46, 0x82, 0xa0, 0xc8, 0xff, 0x04, 0x04, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const uint32_t CodechalEncodeAvcEnc::MultiPred[NUM_TARGET_USAGE_MODES] = { 0, 3, 3, 0, 0, 0, 0, 0 }; const uint32_t CodechalEncodeAvcEnc::MRDisableQPCheck[NUM_TARGET_USAGE_MODES] = { 0, 1, 0, 0, 0, 0, 0, 0 }; // AVC MBEnc RefCost tables, index [CodingType][QP] // QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes const uint16_t CodechalEncodeAvcEnc::RefCost_MultiRefQp[NUM_PIC_TYPES][64] = { // I-frame { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, // P-slice { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, //B-slice { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } }; // 1 for P, 3 for P & B const uint32_t CodechalEncodeAvcEnc::CODECHAL_ENCODE_AVC_AllFractional_Common[NUM_TARGET_USAGE_MODES] = { 0, 3, 3, 3, 3, 3, 3, 0 }; uint16_t CodechalEncodeAvcEnc::CalcSkipVal(bool encBlockBasedSkipEn, bool transform8x8Flag, uint16_t skipVal) { if(!encBlockBasedSkipEn) { skipVal *= 3; } else if(!transform8x8Flag) { skipVal /= 2; } return skipVal; } uint32_t CodechalEncodeAvcEnc::GetMaxMvsPer2Mb(uint8_t levelIdc) { uint32_t maxMvsPer2Mb = 32; // See JVT Spec Annex A Table A-1 Level limits for below mapping switch (levelIdc) { case CODEC_AVC_LEVEL_3: maxMvsPer2Mb = 32; break; case CODEC_AVC_LEVEL_31: case CODEC_AVC_LEVEL_32: case CODEC_AVC_LEVEL_4: case CODEC_AVC_LEVEL_41: case CODEC_AVC_LEVEL_42: case CODEC_AVC_LEVEL_5: case CODEC_AVC_LEVEL_51: case CODEC_AVC_LEVEL_52: maxMvsPer2Mb = 16; break; default: break; } return maxMvsPer2Mb; } // Indicates if reference picture is a FIELD picture, if check ppRefList, the flags is always the second field flag; // because the first field flag will be overwrited by the second one. // if check the reference flag is top or bottom, using pParams->pSlcParams->RefPicList[list][index].PicFlags is better uint32_t CodechalEncodeAvcEnc::GetRefPicFieldFlag( PCODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS params, uint32_t list, uint32_t index) { CODEC_PICTURE refPic; uint32_t refPicFieldFlag; refPicFieldFlag = 0; if(params == nullptr){ CODECHAL_ENCODE_ASSERTMESSAGE("Invalid (NULL) Pointer."); return refPicFieldFlag; } CODECHAL_ENCODE_ASSERT(list == LIST_0 || list == LIST_1); CODECHAL_ENCODE_ASSERT(index < 32); refPic = params->pSlcParams->RefPicList[list][index]; if (!CodecHal_PictureIsInvalid(refPic)) { refPic = params->pPicParams->RefFrameList[refPic.FrameIdx]; if (!CodecHal_PictureIsInvalid(refPic)) { refPicFieldFlag = CodecHal_PictureIsField(params->ppRefList[refPic.FrameIdx]->RefPic); } } return refPicFieldFlag; } uint8_t CodechalEncodeAvcEnc::AVCGetQPValueFromRefList( PCODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS params, uint32_t list, uint32_t index) { uint8_t picIdx; CODEC_PICTURE picture; if(params == nullptr){ CODECHAL_ENCODE_ASSERTMESSAGE("Invalid (NULL) Pointer."); return 0; } CODECHAL_ENCODE_ASSERT(list == LIST_0 || list == LIST_1); CODECHAL_ENCODE_ASSERT(index < CODEC_AVC_MAX_NUM_REF_FRAME * 2); picture = params->pSlcParams->RefPicList[list][index]; if (!CodecHal_PictureIsInvalid(picture) && params->pPicIdx[picture.FrameIdx].bValid) { picIdx = params->pPicIdx[picture.FrameIdx].ucPicIdx; if (CodecHal_PictureIsBottomField(picture)) { return params->ppRefList[picIdx]->ucQPValue[1]; } else { return params->ppRefList[picIdx]->ucQPValue[0]; } } else { return 0; } return 0; } //------------------------------------------------------------------------------------ // Send surfaces for the AVC BRC Block Copy kernel //------------------------------------------------------------------------------------ MOS_STATUS CodechalEncodeAvcEnc::SendBrcBlockCopySurfaces( CodechalHwInterface *hwInterface, PMOS_COMMAND_BUFFER cmdBuffer, PMHW_KERNEL_STATE mbEncKernelState, PMHW_KERNEL_STATE kernelState, PMOS_RESOURCE advancedDsh) { MOS_SURFACE dshBuffer; CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; MOS_RESOURCE *dsh = nullptr; MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface); CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); CODECHAL_ENCODE_CHK_NULL_RETURN(mbEncKernelState); CODECHAL_ENCODE_CHK_NULL_RETURN(kernelState); // Set up artificial MOS_SURFACE for DSH buffers MOS_ZeroMemory(&dshBuffer, sizeof(dshBuffer)); dshBuffer.TileType = MOS_TILE_LINEAR; dshBuffer.bArraySpacing = true; dshBuffer.Format = Format_Buffer_2D; dshBuffer.dwWidth = CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH; dshBuffer.dwHeight = mbEncKernelState->m_dshRegion.GetSize() / CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH; dshBuffer.dwPitch = CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH; // Input dshBuffer.dwOffset = mbEncKernelState->m_dshRegion.GetOffset(); CODECHAL_ENCODE_CHK_NULL_RETURN(dsh = mbEncKernelState->m_dshRegion.GetResource()); dshBuffer.OsResource = *dsh; MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); surfaceCodecParams.bIs2DSurface = true; surfaceCodecParams.bMediaBlockRW = true; surfaceCodecParams.psSurface = &dshBuffer; surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_INPUT; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( hwInterface, cmdBuffer, &surfaceCodecParams, kernelState)); // Output dshBuffer.dwOffset = 0; dshBuffer.OsResource = *advancedDsh; MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); surfaceCodecParams.bIs2DSurface = true; surfaceCodecParams.bMediaBlockRW = true; surfaceCodecParams.psSurface = &dshBuffer; surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_OUTPUT; surfaceCodecParams.bRenderTarget = true; surfaceCodecParams.bIsWritable = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( hwInterface, cmdBuffer, &surfaceCodecParams, kernelState)); return eStatus; } CodechalEncodeAvcEnc::CodechalEncodeAvcEnc( CodechalHwInterface * hwInterface, CodechalDebugInterface *debugInterface, PCODECHAL_STANDARD_INFO standardInfo) : CodechalEncodeAvcBase(hwInterface, debugInterface, standardInfo) { CODECHAL_ENCODE_FUNCTION_ENTER; InitializeDataMember(); // Setup initial data bBrcInit = true; // enable codec specific user feature key reporting for AVC m_userFeatureKeyReport = true; m_kuid = IDR_CODEC_AllAVCEnc; m_swBrcMode = nullptr; m_cmKernelEnable = true; bBrcSplitEnable = true; bBrcRoiSupported = true; bHighTextureModeCostEnable = true; for (uint8_t i = 0; i < CODECHAL_ENCODE_BRC_IDX_NUM; i++) { BrcKernelStates[i] = MHW_KERNEL_STATE(); } if (m_cmKernelEnable) { m_useCmScalingKernel = 1; } CODECHAL_DEBUG_TOOL( m_mmcUserFeatureUpdated = false; ) } CodechalEncodeAvcEnc::~CodechalEncodeAvcEnc() { CODECHAL_ENCODE_FUNCTION_ENTER; if (SeiData.pSEIBuffer) { MOS_FreeMemory(SeiData.pSEIBuffer); SeiData.pSEIBuffer = nullptr; } if (pWPKernelState) { MOS_Delete(pWPKernelState); pWPKernelState = nullptr; } MOS_Delete(pSFDKernelState); pSFDKernelState = nullptr; if (m_pakEnabled) { // release skip frame copy buffer m_osInterface->pfnFreeResource(m_osInterface, &resSkipFrameBuffer); } if (m_encEnabled) { ReleaseResourcesBrc(); ReleaseResourcesMbBrc(); m_osInterface->pfnFreeResource(m_osInterface, &resVMEScratchBuffer); if (bVMEKernelDump) { m_osInterface->pfnFreeResource(m_osInterface, &resVmeKernelDumpBuffer); } // RefPicSelectList for (uint32_t i = 0; i < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; i++) { m_osInterface->pfnFreeResource( m_osInterface, &RefPicSelectList[i].sBuffer.OsResource); } MOS_DeleteArray(pMbEncKernelStates); } //WP output surface for (uint32_t i = 0; i < CODEC_AVC_NUM_WP_FRAME; i++) { m_osInterface->pfnFreeResource( m_osInterface, &WeightedPredOutputPicSelectList[i].sBuffer.OsResource); } // SFD surfaces { // SFD output buffer for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { m_osInterface->pfnFreeResource( m_osInterface, &resSFDOutputBuffer[i]); } m_osInterface->pfnFreeResource( m_osInterface, &resSFDCostTablePFrameBuffer); m_osInterface->pfnFreeResource( m_osInterface, &resSFDCostTableBFrameBuffer); } if (m_swBrcMode != nullptr) { m_osInterface->pfnFreeLibrary(m_swBrcMode); m_swBrcMode = nullptr; } // MB specific data buffer for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { m_osInterface->pfnFreeResource( m_osInterface, &resMbSpecificDataBuffer[i]); } return; } MOS_STATUS CodechalEncodeAvcEnc::Initialize(CodechalSetting * settings) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(settings); CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::Initialize(settings)); // for AVC: the Ds+Copy kernel is by default used to do CSC and copy non-aligned surface m_cscDsState->EnableCopy(); m_cscDsState->EnableColor(); MOS_USER_FEATURE_VALUE_DATA userFeatureData; #if (_DEBUG || _RELEASE_INTERNAL) /*MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_BRC_SOFTWARE_ID, &userFeatureData, m_osInterface->pOsContext); if (userFeatureData.i32Data) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnLoadLibrary(m_osInterface, CODECHAL_DBG_STRING_SWAVCBRCLIBRARY, &m_swBrcMode)); }*/ // SW BRC DLL Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_BRC_SOFTWARE_IN_USE_ID, (m_swBrcMode == nullptr) ? false : true, m_osInterface->pOsContext); #endif // (_DEBUG || _RELEASE_INTERNAL) if (!(m_codecFunction == CODECHAL_FUNCTION_PAK || m_codecFunction == CODECHAL_FUNCTION_FEI_PAK)) { MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_ME_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); m_hmeSupported = (userFeatureData.u32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_16xME_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); if (userFeatureData.i32Data == 0 || userFeatureData.i32Data == 1) { m_16xMeUserfeatureControl = true; m_16xMeSupported = (userFeatureData.i32Data) ? true : false; } else { m_16xMeUserfeatureControl = false; m_16xMeSupported = true; } // Flatness check enable m_flatnessCheckSupported = 1; // Enabled by default for AVC when supported MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_FLATNESS_CHECK_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); m_flatnessCheckSupported = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_STATIC_FRAME_DETECTION_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bStaticFrameDetectionEnable = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_SEARCH_WINDOW_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bApdatvieSearchWindowEnable = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_FORCE_TO_SKIP_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bForceToSkipEnable = (userFeatureData.u32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_SLIDING_WINDOW_SIZE_ID, &userFeatureData, m_osInterface->pOsContext); dwSlidingWindowSize = userFeatureData.u32Data; // Colorbit support (encoding multiple slices in parallel) m_colorbitSupported = 1; // Enable by default for AVC #if (_DEBUG || _RELEASE_INTERNAL) MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_COLOR_BIT_SUPPORT_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); m_colorbitSupported = (userFeatureData.i32Data) ? true : false; #endif m_groupIdSelectSupported = 0; // Disabled by default for AVC for now #if (_DEBUG || _RELEASE_INTERNAL) MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_GROUP_ID_SELECT_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); m_groupIdSelectSupported = (userFeatureData.i32Data) ? true : false; #endif m_groupId = 0; // default value for group ID = 0 #if (_DEBUG || _RELEASE_INTERNAL) MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_GROUP_ID_ID, &userFeatureData, m_osInterface->pOsContext); m_groupId = (uint8_t)userFeatureData.i32Data; #endif } // disable BRC and HME for FEI encoder if ((m_feiEnable) && (m_codecFunction != CODECHAL_FUNCTION_FEI_PRE_ENC)) { m_hmeSupported = false; m_16xMeSupported = false; m_32xMeSupported = false; } // Initialize hardware resources for the current Os/Platform CODECHAL_ENCODE_CHK_STATUS_RETURN(InitializeState()); { MotionEstimationDisableCheck(); } CODECHAL_ENCODE_CHK_STATUS_RETURN(Initialize()); // common function for all codecs needed if (CodecHalUsesRenderEngine(m_codecFunction, m_standard)) { CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelState()); } // Picture Level Commands m_hwInterface->GetMfxStateCommandsDataSize( CODECHAL_ENCODE_MODE_AVC, &m_pictureStatesSize, &m_picturePatchListSize, false); // Slice Level Commands m_hwInterface->GetMfxPrimitiveCommandsDataSize( CODECHAL_ENCODE_MODE_AVC, &m_sliceStatesSize, &m_slicePatchListSize, m_singleTaskPhaseSupported); return eStatus; } void CodechalEncodeAvcEnc::InitializeDataMember() { CODECHAL_ENCODE_FUNCTION_ENTER; // SEI MOS_ZeroMemory(&SeiData, sizeof(CodechalEncodeSeiData)); dwSEIDataOffset = false; pSeiParamBuffer = nullptr; bMbEncCurbeSetInBrcUpdate = false; bMbEncIFrameDistEnabled = false; bBrcInit = false; bBrcReset = false; bBrcEnabled = false; bMbBrcEnabled = false; bBrcRoiEnabled = false; // BRC ROI feature bROIValueInDeltaQP = false; bROISmoothEnabled = false; bMbBrcUserFeatureKeyControl = false; dBrcTargetSize = 0.0f; dwTrellis = false; bAcceleratorHeaderPackingCaps = false; //flag set by driver from driver caps dwIntraRefreshQpThreshold = false; bSquareRollingIEnabled = false; // VME Scratch Buffers MOS_ZeroMemory(&resVMEScratchBuffer, sizeof(MOS_RESOURCE)); // HSW+ bVMEScratchBuffer = false; MOS_ZeroMemory(&resVmeKernelDumpBuffer, sizeof(MOS_RESOURCE)); bVMEKernelDump = false; ulVMEKernelDumpBottomFieldOffset = 0; // MbEnc pMbEncKernelStates = nullptr; MOS_ZeroMemory(&MbEncBindingTable, sizeof(CODECHAL_ENCODE_AVC_BINDING_TABLE_MBENC)); dwNumMbEncEncKrnStates = false; MOS_ZeroMemory(RefPicSelectList, CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES * sizeof(CODEC_AVC_REF_PIC_SELECT_LIST)); ucCurrRefPicSelectIndex = 0; ulRefPicSelectBottomFieldOffset = 0; dwMbEncBlockBasedSkipEn = false; bKernelTrellis = false; // Kernel controlled Trellis Quantization bExtendedMvCostRange = false; // Extended MV Cost Range for Gen10+ // WP pWPKernelState = nullptr; MOS_ZeroMemory(WeightedPredOutputPicSelectList, CODEC_AVC_NUM_WP_FRAME * sizeof(CODEC_AVC_REF_PIC_SELECT_LIST)); // BRC Params MOS_ZeroMemory(&BrcUpdateBindingTable, sizeof(CODECHAL_ENCODE_AVC_BINDING_TABLE_BRC_UPDATE)); // PreProc MOS_ZeroMemory(&PreProcBindingTable, sizeof(CODECHAL_ENCODE_AVC_BINDING_TABLE_PREPROC)); MOS_ZeroMemory(&BrcBuffers, sizeof(EncodeBrcBuffers)); usAVBRAccuracy = 0; usAVBRConvergence = 0; dBrcInitCurrentTargetBufFullInBits = 0; dBrcInitResetInputBitsPerFrame = 0; dwBrcInitResetBufSizeInBits = false; dwBrcInitPreviousTargetBufFullInBits = false; // Below values will be set if qp control params are sent by app bMinMaxQPControlEnabled = false; // Flag to indicate if min/max QP feature is enabled or not. ucIMinQP = 0; ucIMaxQP = 0; ucPMinQP = 0; ucPMaxQP = 0; ucBMinQP = 0; ucBMaxQP = 0; bPFrameMinMaxQPControl = false; // Indicates min/max QP values for P-frames are set separately or not. bBFrameMinMaxQPControl = false; // Indicates min/max QP values for B-frames are set separately or not. dwSkipFrameBufferSize = false; // size of skip frame packed data MOS_ZeroMemory(&resSkipFrameBuffer, sizeof(MOS_RESOURCE)); // copy skip frame packed data from DDI // Mb Disable Skip Map bMbDisableSkipMapEnabled = false; psMbDisableSkipMapSurface = nullptr; // Mb Qp Data bMbQpDataEnabled = false; MOS_ZeroMemory(&sMbQpDataSurface, sizeof(MOS_SURFACE)); // Mb Specific Data bMbSpecificDataEnabled = false; MOS_ZeroMemory(&resMbSpecificDataBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_RECYCLED_BUFFER_NUM); // Static frame detection bStaticFrameDetectionEnable = false; // Static frame detection enable bApdatvieSearchWindowEnable = false; // allow search window size change when SFD enabled bPerMbSFD = false; MOS_ZeroMemory(&resSFDOutputBuffer, sizeof(MOS_RESOURCE)* CODECHAL_ENCODE_RECYCLED_BUFFER_NUM); MOS_ZeroMemory(&resSFDCostTablePFrameBuffer, sizeof(MOS_RESOURCE)); MOS_ZeroMemory(&resSFDCostTableBFrameBuffer, sizeof(MOS_RESOURCE)); pSFDKernelState = nullptr; // Generation Specific Support Flags & User Feature Key Reads bBrcDistortionBufferSupported = false; bRefPicSelectListSupported = false; ucMbBrcSupportCaps = 0; bMultiPredEnable = false; // MultiPredictor enable, 6 predictors bFTQEnable = false; // FTQEnable bCAFSupported = false; // CAFSupported bCAFEnable = false; // CAFEnable bCAFDisableHD = false; // Disable CAF for HD bSkipBiasAdjustmentSupported = false; // SkipBiasAdjustment support for P frame bAdaptiveIntraScalingEnable = false; // Enable AdaptiveIntraScaling bOldModeCostEnable = false; // Enable Old Mode Cost (HSW cost table for BDW) bMultiRefQpEnabled = false; // BDW Mutiref Qp bAdvancedDshInUse = false; // Use MbEnc Adv kernel bUseMbEncAdvKernel = false; // Use MbEnc Adv kernel bUseWeightedSurfaceForL0 = false; //Use WP Surface for L0 bUseWeightedSurfaceForL1 = false; //Use WP Surface for L1 bWeightedPredictionSupported = false; //Weighted prediction support bBrcSplitEnable = false; // starting GEN9 BRC kernel has split into frame-level and MB-level update. bDecoupleMbEncCurbeFromBRC = false; // starting GEN95 BRC kernel write to extra surface instread of MBEnc curbe. bSliceLevelReportSupported = false; // Slice Level Report support bFBRBypassEnable = false; // FBRBypassEnable bBrcRoiSupported = false; bMvDataNeededByBRC = false; // starting from G95, bHighTextureModeCostEnable = false; bRoundingInterEnable = false; bAdaptiveRoundingInterEnable = false; dwRoundingInterP = false; dwRoundingInterB = false; dwRoundingInterBRef = false; dwBrcConstantSurfaceWidth = false; dwBrcConstantSurfaceHeight = false; dwSlidingWindowSize = false; bForceToSkipEnable = false; } MOS_STATUS CodechalEncodeAvcEnc::Initialize() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::Initialize()); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InitializeState() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; MOS_USER_FEATURE_VALUE_DATA userFeatureData; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_SINGLE_TASK_PHASE_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); m_singleTaskPhaseSupported = (userFeatureData.i32Data) ? true : false; // Set interleaved scaling output to support PAFF. m_fieldScalingOutputInterleaved = true; if (m_encEnabled) { MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_MULTIPRED_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bMultiPredEnable = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_FTQ_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bFTQEnable = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_CAF_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bCAFSupported = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_CAF_DISABLE_HD_ID, &userFeatureData, m_osInterface->pOsContext); bCAFDisableHD = (userFeatureData.i32Data) ? true : false; ucMbBrcSupportCaps = 1; if (ucMbBrcSupportCaps) { // If the MBBRC user feature key does not exist, MBBRC will be set in SPS parsing MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_MB_BRC_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); if (userFeatureData.i32Data == 0 || userFeatureData.i32Data == 1) { bMbBrcUserFeatureKeyControl = true; bMbBrcEnabled = userFeatureData.i32Data ? true : false; } } MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_MULTIREF_QP_ID, &userFeatureData, m_osInterface->pOsContext); bMultiRefQpEnabled = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_32xME_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); if (userFeatureData.i32Data == 0 || userFeatureData.i32Data == 1) { m_32xMeUserfeatureControl = true; m_32xMeSupported = (userFeatureData.i32Data) ? true : false; } else { m_32xMeUserfeatureControl = false; m_32xMeSupported = true; } } MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bRoundingInterEnable = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); userFeatureData.i32Data = CODECHAL_ENCODE_AVC_INVALID_ROUNDING; userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE; MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_P_ID, &userFeatureData, m_osInterface->pOsContext); dwRoundingInterP = userFeatureData.i32Data; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); userFeatureData.i32Data = CODECHAL_ENCODE_AVC_INVALID_ROUNDING; userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE; MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_B_ID, &userFeatureData, m_osInterface->pOsContext); dwRoundingInterB = userFeatureData.i32Data; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); userFeatureData.i32Data = CODECHAL_ENCODE_AVC_INVALID_ROUNDING; userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE; MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_BREF_ID, &userFeatureData, m_osInterface->pOsContext); dwRoundingInterBRef = userFeatureData.i32Data; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); userFeatureData.i32Data = 1; userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE; MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_ROUNDING_INTER_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bAdaptiveRoundingInterEnable = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_SKIP_BIAS_ADJUSTMENT_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bSkipBiasAdjustmentSupported = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_INTRA_SCALING_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bAdaptiveIntraScalingEnable = (userFeatureData.i32Data) ? true : false; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_OLD_MODE_COST_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bOldModeCostEnable = (userFeatureData.i32Data) ? true : false; //Check if ATD has been disabled by user feature key. The TU check happens in CodecHalAvcEncode_SetPictureStructs() MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); userFeatureData.i32Data = 1; MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_ADAPTIVE_TRANSFORM_DECISION_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); m_adaptiveTransformDecisionEnabled = (userFeatureData.i32Data) ? true : false; // add user feature key to test FBR Bypass on SKL MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_FBR_BYPASS_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); bFBRBypassEnable = (userFeatureData.i32Data) ? true : false; // add user feature key to enable/disable variance computation in BRC kernel MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_AVC_BRC_VAR_COMPU_BYPASS_ID, &userFeatureData, m_osInterface->pOsContext); bBRCVarCompuBypass = (userFeatureData.i32Data) ? true : false; // add user feature key to switch on/off ARB WA of CNL AVC MBEnc hang MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_ENABLE_CNL_AVC_ENCODE_ARB_WA_ID, &userFeatureData, m_osInterface->pOsContext); if ((userFeatureData.i32Data) == 0) { MEDIA_WR_WA(m_waTable, WaArbitraryNumMbsInSlice, 0); } m_4xMeDistortionBufferSupported = true; bBrcDistortionBufferSupported = true; bRefPicSelectListSupported = true; bPerMbSFD = true; bWeightedPredictionSupported = true; m_forceBrcMbStatsEnabled = true; return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::ValidateNumReferences(PCODECHAL_ENCODE_AVC_VALIDATE_NUM_REFS_PARAMS params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(params); CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams); CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams); uint8_t numRefIdx0MinusOne = params->pAvcSliceParams->num_ref_idx_l0_active_minus1; uint8_t numRefIdx1MinusOne = params->pAvcSliceParams->num_ref_idx_l1_active_minus1; // Nothing to do here if numRefIdx = 0 and frame encoded if (numRefIdx0MinusOne == 0 && !CodecHal_PictureIsField(params->pPicParams->CurrOriginalPic)) { if (params->wPictureCodingType == P_TYPE || (params->wPictureCodingType == B_TYPE && numRefIdx1MinusOne == 0)) { return eStatus; } } uint8_t maxPNumRefIdx0MinusOne; if (params->wPictureCodingType == P_TYPE || params->wPictureCodingType == B_TYPE) { if (params->wPictureCodingType == P_TYPE) { if ((((params->wPicHeightInMB * CODECHAL_MACROBLOCK_HEIGHT) * (params->wFrameFieldHeightInMB * CODECHAL_MACROBLOCK_WIDTH)) >= 3840 * 2160) && CodecHal_PictureIsFrame(params->pPicParams->CurrOriginalPic)) { maxPNumRefIdx0MinusOne = MaxRefIdx0_Progressive_4K[params->pSeqParams->TargetUsage]; } else { maxPNumRefIdx0MinusOne = MaxRefIdx0[params->pSeqParams->TargetUsage]; } if (numRefIdx0MinusOne > maxPNumRefIdx0MinusOne) { CODECHAL_ENCODE_NORMALMESSAGE("Invalid active reference list size."); numRefIdx0MinusOne = maxPNumRefIdx0MinusOne; } numRefIdx1MinusOne = 0; } else // B_TYPE { if (numRefIdx0MinusOne > MaxBRefIdx0[params->pSeqParams->TargetUsage]) { CODECHAL_ENCODE_NORMALMESSAGE("Invalid active reference list size."); numRefIdx0MinusOne = MaxBRefIdx0[params->pSeqParams->TargetUsage]; } if (numRefIdx1MinusOne > MaxRefIdx1[params->pSeqParams->TargetUsage]) { CODECHAL_ENCODE_NORMALMESSAGE("Invalid active reference list size."); numRefIdx1MinusOne = MaxRefIdx1[params->pSeqParams->TargetUsage]; } // supports at most 1 L1 ref for frame picture if (CodecHal_PictureIsFrame(params->pPicParams->CurrOriginalPic) && numRefIdx1MinusOne > 0) { numRefIdx1MinusOne = 0; } } } // Override number of references used by VME. PAK uses value from DDI (num_ref_idx_l*_active_minus1_from_DDI) params->pAvcSliceParams->num_ref_idx_l0_active_minus1 = numRefIdx0MinusOne; params->pAvcSliceParams->num_ref_idx_l1_active_minus1 = numRefIdx1MinusOne; return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InitBrcConstantBuffer(PCODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(params); CODECHAL_ENCODE_CHK_NULL_RETURN(params->pOsInterface); MOS_LOCK_PARAMS lockFlags; MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); lockFlags.WriteOnly = 1; uint8_t* pbData = (uint8_t*)params->pOsInterface->pfnLockResource( params->pOsInterface, ¶ms->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, ¶ms->sBrcConstantDataBuffer.OsResource); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InitMbBrcConstantDataBuffer(PCODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(params); CODECHAL_ENCODE_CHK_NULL_RETURN(params->presBrcConstantDataBuffer); // 16 DWs per QP value uint32_t size = 16 * CODEC_AVC_NUM_QP; MOS_LOCK_PARAMS lockFlags; MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); lockFlags.WriteOnly = 1; // using an async lock because the wait has already occured for recycled buffers lockFlags.NoOverWrite = 1; lockFlags.Uncached = 1; uint32_t* pData = (uint32_t*)m_osInterface->pfnLockResource( m_osInterface, params->presBrcConstantDataBuffer, &lockFlags); CODECHAL_ENCODE_CHK_NULL_RETURN(pData); if (params->bPreProcEnable) { eStatus = MOS_SecureMemcpy(pData, size * sizeof(uint32_t), (void*)PreProcFtqLut_Cm_Common, size * sizeof(uint32_t)); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); m_osInterface->pfnUnlockResource( m_osInterface, params->presBrcConstantDataBuffer); return eStatus; } } else { CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams); uint8_t tableIdx = params->wPictureCodingType - 1; bool blockBasedSkipEn = params->dwMbEncBlockBasedSkipEn ? true : false; bool transform_8x8_mode_flag = params->pPicParams->transform_8x8_mode_flag ? true : false; if (tableIdx >= 3) { CODECHAL_ENCODE_ASSERTMESSAGE("Invalid input parameter."); eStatus = MOS_STATUS_INVALID_PARAMETER; m_osInterface->pfnUnlockResource( m_osInterface, params->presBrcConstantDataBuffer); return eStatus; } eStatus = MOS_SecureMemcpy(pData, size * sizeof(uint32_t), (void*)MBBrcConstantData_Cm_Common[tableIdx], size * sizeof(uint32_t)); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); m_osInterface->pfnUnlockResource( m_osInterface, params->presBrcConstantDataBuffer); return eStatus; } uint32_t* databk = pData; uint8_t qp = 0; switch (params->wPictureCodingType) { case I_TYPE: for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++) { // Writing to DW0 in each sub-array of 16 DWs if (params->bOldModeCostEnable) { *pData = (uint32_t)OldIntraModeCost_Cm_Common[qp]; } pData += 16; } break; case P_TYPE: case B_TYPE: for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++) { if (params->wPictureCodingType == P_TYPE) { // Writing to DW3 in each sub-array of 16 DWs if (params->bSkipBiasAdjustmentEnable) { *(pData + 3) = (uint32_t)MvCost_PSkipAdjustment_Cm_Common[qp]; } } // Writing to DW9 in each sub-array of 16 DWs if (params->pAvcQCParams && params->pAvcQCParams->NonFTQSkipThresholdLUTInput) { *(pData + 9) = (uint32_t)CalcSkipVal((params->dwMbEncBlockBasedSkipEn ? true : false), (transform_8x8_mode_flag ? true : false), params->pAvcQCParams->NonFTQSkipThresholdLUT[qp]); } else if (params->wPictureCodingType == P_TYPE) { *(pData + 9) = (uint32_t)SkipVal_P_Common[blockBasedSkipEn][transform_8x8_mode_flag][qp]; } else { *(pData + 9) = (uint32_t)SkipVal_B_Common[blockBasedSkipEn][transform_8x8_mode_flag][qp]; } // Writing to DW10 in each sub-array of 16 DWs if (params->bAdaptiveIntraScalingEnable) { *(pData + 10) = (uint32_t)AdaptiveIntraScalingFactor_Cm_Common[qp]; } else { *(pData + 10) = (uint32_t)IntraScalingFactor_Cm_Common[qp]; } pData += 16; } break; default: break; } pData = databk; for (qp = 0; qp < CODEC_AVC_NUM_QP; qp++) { if (params->pAvcQCParams && params->pAvcQCParams->FTQSkipThresholdLUTInput) { *(pData + 6) = ((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 16) | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 24); *(pData + 7) = ((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 8) | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 16) | (((uint32_t)params->pAvcQCParams->FTQSkipThresholdLUT[qp]) << 24); } if (params->bEnableKernelTrellis) { // Writing uint32_t 11 and uint32_t 12 with Lambda values *(pData + 11) = (uint32_t)params->Lambda[qp][0]; *(pData + 12) = (uint32_t)params->Lambda[qp][1]; } pData += 16; } } m_osInterface->pfnUnlockResource( m_osInterface, params->presBrcConstantDataBuffer); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::CalcLambdaTable( uint16_t slice_type, uint32_t* lambda) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN( m_avcSeqParam); CODECHAL_ENCODE_CHK_NULL_RETURN( m_refList); CODECHAL_ENCODE_CHK_NULL_RETURN(lambda); // Initialize Lambda Table switch (slice_type) { case I_TYPE: eStatus = MOS_SecureMemcpy((void*)lambda, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t), (void*)TQ_LAMBDA_I_FRAME, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t)); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); return eStatus; } break; case B_TYPE: eStatus = MOS_SecureMemcpy((void*)lambda, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t), (void*)TQ_LAMBDA_B_FRAME, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t)); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); return eStatus; } break; case P_TYPE: eStatus = MOS_SecureMemcpy((void*)lambda, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t), (void*)TQ_LAMBDA_P_FRAME, CODEC_AVC_NUM_QP * 2 * sizeof(uint32_t)); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); return eStatus; } break; default: eStatus = MOS_STATUS_UNKNOWN; break; } uint32_t roundingValue = 0; for (uint8_t sliceQP = 0; sliceQP < CODEC_AVC_NUM_QP; sliceQP++) { for (uint8_t col = 0; col < 2; col++) { uint32_t value = *(lambda + sliceQP * 2 + col); uint32_t intra = value >> 16; if (intra > CODECHAL_ENCODE_AVC_MAX_LAMBDA) { if (intra == 0xfffa) { intra = 0xf000 + CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_INTRA_ROUNDING; } } intra = intra << 16; uint32_t inter = value & 0xffff; if (inter > CODECHAL_ENCODE_AVC_MAX_LAMBDA) { if (inter == 0xffef) { switch (slice_type) { case P_TYPE: if ( dwRoundingInterP == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) { roundingValue = InterRoundingP_TQ[m_avcSeqParam->TargetUsage]; } else { roundingValue = dwRoundingInterP; } break; case B_TYPE: if (m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) { roundingValue = ( dwRoundingInterBRef == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) ? InterRoundingBRef_TQ[m_avcSeqParam->TargetUsage] : dwRoundingInterBRef; } else { if ( dwRoundingInterB == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) { roundingValue = InterRoundingB_TQ[m_avcSeqParam->TargetUsage]; } else { roundingValue = dwRoundingInterB; } } break; default: // do nothing break; } inter = 0xf000 + roundingValue; } } *(lambda + sliceQP * 2 + col) = intra + inter; } } return eStatus; } static uint8_t CODECHAL_ENCODE_AVC_AdaptiveInterRoundingPWithoutB[CODEC_AVC_NUM_QP] = { //QP = 0 1 2 3 4 5 6 7 8 9 10 11 12 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, //QP=[0~12] 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0, //QP=[13~25] 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[26~38] 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //QP=[39~51] }; static uint8_t CODECHAL_ENCODE_AVC_AdaptiveInterRoundingP[CODEC_AVC_NUM_QP] = { //QP = 0 1 2 3 4 5 6 7 8 9 10 11 12 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, //QP=[0~12] 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, //QP=[13~25] 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, //QP=[26~38] 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 //QP=[39~51] }; static const uint32_t CODECHAL_ENCODE_AVC_InterRoundingP[NUM_TARGET_USAGE_MODES] = { 0, 3, 3, 3, 3, 3, 3, 3 }; static const uint32_t CODECHAL_ENCODE_AVC_InterRoundingBRef[NUM_TARGET_USAGE_MODES] = { 0, 2, 2, 2, 2, 2, 2, 2 }; static uint8_t CODECHAL_ENCODE_AVC_AdaptiveInterRoundingB[CODEC_AVC_NUM_QP] = { //QP = 0 1 2 3 4 5 6 7 8 9 10 11 12 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, //QP=[0~12] 4, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, //QP=[13~25] 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[26~38] 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //QP=[39~51] }; static const uint32_t CODECHAL_ENCODE_AVC_InterRoundingB[NUM_TARGET_USAGE_MODES] = { 0, 0, 0, 0, 0, 0, 0, 0 }; MOS_STATUS CodechalEncodeAvcEnc::GetInterRounding(PMHW_VDBOX_AVC_SLICE_STATE sliceState) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState); CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcSeqParams); CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcPicParams); CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcSliceParams); auto avcSeqParams = sliceState->pEncodeAvcSeqParams; auto avcPicParams = sliceState->pEncodeAvcPicParams; auto avcSliceParams = sliceState->pEncodeAvcSliceParams; uint8_t sliceQP = avcPicParams->pic_init_qp_minus26 + 26 + avcSliceParams->slice_qp_delta; switch (Slice_Type[avcSliceParams->slice_type]) { case SLICE_P: if (dwRoundingInterP == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) { // Adaptive Rounding is only used in CQP case if (bAdaptiveRoundingInterEnable && !bBrcEnabled) { // If IPPP scenario if (avcSeqParams->GopRefDist == 1) { sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_AdaptiveInterRoundingPWithoutB[sliceQP]; } else { sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_AdaptiveInterRoundingP[sliceQP]; } } else { sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_InterRoundingP[avcSeqParams->TargetUsage]; } } else { sliceState->dwRoundingValue = dwRoundingInterP; } break; case SLICE_B: if (m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) { sliceState->dwRoundingValue = (dwRoundingInterBRef == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) ? CODECHAL_ENCODE_AVC_InterRoundingBRef[avcSeqParams->TargetUsage] : dwRoundingInterBRef; } else { if (dwRoundingInterB == CODECHAL_ENCODE_AVC_INVALID_ROUNDING) { if (bAdaptiveRoundingInterEnable && !bBrcEnabled) { sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_AdaptiveInterRoundingB[sliceQP]; } else { sliceState->dwRoundingValue = CODECHAL_ENCODE_AVC_InterRoundingB[avcSeqParams->TargetUsage]; } } else { sliceState->dwRoundingValue = dwRoundingInterB; } } break; default: // do nothing break; } return eStatus; } // This applies only for progressive pictures. For interlaced, CAF is currently not disabled. const uint32_t CodechalEncodeAvcEnc::CODECHAL_ENCODE_AVC_DisableAllFractionalCheckForHighRes_Common[NUM_TARGET_USAGE_MODES] = { 0, 0, 0, 1, 1, 1, 1, 1 }; MOS_STATUS CodechalEncodeAvcEnc::GetSkipBiasAdjustment(uint8_t sliceQP, uint16_t gopRefDist, bool* skipBiasAdjustmentEnable) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(skipBiasAdjustmentEnable); // Determine if SkipBiasAdjustment should be enabled for P picture // 1. No B frame 2. Qp >= 22 3. CQP mode *skipBiasAdjustmentEnable = bSkipBiasAdjustmentSupported && (m_pictureCodingType == P_TYPE) && (gopRefDist == 1) && (sliceQP >= CODECHAL_ENCODE_AVC_SKIP_BIAS_ADJUSTMENT_QP_THRESHOLD) && !bBrcEnabled; return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::GetHmeSupportedBasedOnTU(HmeLevel hmeLevel, bool *supported) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(supported); switch (hmeLevel) { case HME_LEVEL_4x: //HME always supported *supported = true; break; case HME_LEVEL_16x: *supported = SuperHME[m_targetUsage & 0x7] ? true : false; break; case HME_LEVEL_32x: *supported = UltraHME[m_targetUsage & 0x7] ? true : false; break; default: CODECHAL_ENCODE_ASSERTMESSAGE("Invalid hme Level"); eStatus = MOS_STATUS_INVALID_PARAMETER; break; } return eStatus; } static const bool CODECHAL_ENCODE_AVC_MBBRCEnabled_Common[NUM_TARGET_USAGE_MODES] = { false, true, true, false, false, false, false, false }; MOS_STATUS CodechalEncodeAvcEnc::GetMbBrcEnabled(uint32_t targetUsage, bool *mbBrcEnabled) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(mbBrcEnabled); *mbBrcEnabled = CODECHAL_ENCODE_AVC_MBBRCEnabled_Common[targetUsage & 0x7]; return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::GetCAFEnabled(bool *cafenable) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(cafenable); auto picParams = m_avcPicParam; auto targetUsage = m_targetUsage & 0x7; auto framePicture = CodecHal_PictureIsFrame(picParams->CurrOriginalPic); if (bCAFSupported) { switch (m_pictureCodingType) { case I_TYPE: *cafenable = false; break; case P_TYPE: *cafenable = (CODECHAL_ENCODE_AVC_AllFractional_Common[targetUsage] & 0x01) ? true : false; break; case B_TYPE: *cafenable = ((CODECHAL_ENCODE_AVC_AllFractional_Common[targetUsage] >> 1) & 0x01) ? true : false; break; default: CODECHAL_ENCODE_ASSERTMESSAGE("Invalid picture coding type"); eStatus = MOS_STATUS_INVALID_PARAMETER; break; } // For performance reason, disable CAF for picture resolution >= 720P // a. Based on Target Usage. // b. For progressive pictures only. if (*cafenable) { if ((bCAFDisableHD && CODECHAL_ENCODE_AVC_DisableAllFractionalCheckForHighRes_Common[targetUsage] && framePicture) && (m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH >= 1280) && (m_frameFieldHeightInMb * CODECHAL_MACROBLOCK_HEIGHT >= 720)) { *cafenable = false; } } } else { *cafenable = false; } return eStatus; } static const uint8_t CODECHAL_ENCODE_AVC_EnableAdaptiveTxDecision_Common[NUM_TARGET_USAGE_MODES] = { 0, 1, 1, 1, 1, 1, 1, 0 }; MOS_STATUS CodechalEncodeAvcEnc::GetATDEnabled() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; // If ATD has been disabled by user feature key, don't turn it on because it is supported by the TU. if (CODECHAL_ENCODE_AVC_EnableAdaptiveTxDecision_Common[m_targetUsage & 0x7] == 0) m_adaptiveTransformDecisionEnabled = false; return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::BrcInitResetKernel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; uint32_t kernelIdx = (bBrcInit) ? CODECHAL_ENCODE_BRC_IDX_INIT : CODECHAL_ENCODE_BRC_IDX_RESET; auto kernelState = &BrcKernelStates[kernelIdx]; PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_INIT_RESET; // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } // Setup AVC Curbe CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, false, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); CODECHAL_ENCODE_AVC_BRC_INIT_RESET_CURBE_PARAMS brcInitResetCurbeParams; brcInitResetCurbeParams.pdBrcInitCurrentTargetBufFullInBits = &dBrcInitCurrentTargetBufFullInBits; brcInitResetCurbeParams.pdwBrcInitResetBufSizeInBits = &dwBrcInitResetBufSizeInBits; brcInitResetCurbeParams.pdBrcInitResetInputBitsPerFrame = &dBrcInitResetInputBitsPerFrame; brcInitResetCurbeParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcBrcInitReset( &brcInitResetCurbeParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( encFunctionType, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_ISH_TYPE, kernelState)); ) //#if (_DEBUG || _RELEASE_INTERNAL) // if (m_swBrcMode != nullptr) // { // CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgCallAvcSwBrcImpl( // m_debugInterface, // encFunctionType, // this, // &BrcBuffers, // bBrcReset, // kernelState, // kernelState)); // return eStatus; // } //#endif MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = encFunctionType; sendKernelCmdsParams.bBrcResetRequested = bBrcInit ? false : bBrcReset; // Set BrcResetRequested to false if init is also set sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); // Add binding table CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); //Add surface states CODECHAL_ENCODE_AVC_BRC_INIT_RESET_SURFACE_PARAMS brcInitResetSurfaceParams; brcInitResetSurfaceParams.presBrcHistoryBuffer = &BrcBuffers.resBrcHistoryBuffer; brcInitResetSurfaceParams.psMeBrcDistortionBuffer = &BrcBuffers.sMeBrcDistortionBuffer; brcInitResetSurfaceParams.dwMeBrcDistortionBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset; brcInitResetSurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x; brcInitResetSurfaceParams.dwDownscaledFrameFieldHeightInMb4x = m_downscaledFrameFieldHeightInMb4x; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendBrcInitResetSurfaces( &cmdBuffer, &brcInitResetSurfaceParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_SSH_TYPE, kernelState)); ) HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); MHW_MEDIA_OBJECT_PARAMS mediaObjectParams; MediaObjectInlineData mediaObjectInlineData; MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams)); MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData)); mediaObjectParams.pInlineData = &mediaObjectInlineData; mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject( &cmdBuffer, nullptr, &mediaObjectParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( &cmdBuffer, encFunctionType, nullptr))); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InitKernelStateSFD() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; pSFDKernelState = MOS_New(MHW_KERNEL_STATE); CODECHAL_ENCODE_CHK_NULL_RETURN(pSFDKernelState); uint8_t* kernelBinary; uint32_t kernelSize; uint32_t kuid = m_useCommonKernel ? m_kuidCommon : m_kuid; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, kuid, &kernelBinary, &kernelSize)); CODECHAL_KERNEL_HEADER currKrnHeader; CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnGetKernelHeaderAndSize( kernelBinary, ENC_SFD, 0, &currKrnHeader, (uint32_t*)&kernelSize)); auto kernelStatePtr = pSFDKernelState; kernelStatePtr->KernelParams.iBTCount = CODECHAL_ENCODE_AVC_SFD_NUM_SURFACES; kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads; kernelStatePtr->KernelParams.iCurbeLength = sizeof(CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON); kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH; kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT; kernelStatePtr->KernelParams.iIdCount = 1; kernelStatePtr->KernelParams.iInlineDataLength = 0; kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData(); kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT); kernelStatePtr->KernelParams.iSize = kernelSize; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested( m_stateHeapInterface, kernelStatePtr->KernelParams.iBTCount, &kernelStatePtr->dwSshSize, &kernelStatePtr->dwBindingTableSize)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr)); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InitKernelState() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateMe()); CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateMbEnc()); if(!CodecHalIsFeiEncode(m_codecFunction)) { CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateMfeMbEnc()); CODECHAL_ENCODE_CHK_NULL_RETURN(pMbEncKernelStates); } if (CodecHalIsFeiEncode(m_codecFunction)) { CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStatePreProc()); } else { CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateBrc()); } if (bWeightedPredictionSupported) { if(m_feiEnable == false) { if (m_wpUseCommonKernel) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_wpState->InitKernelState()); } else { CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateWP()); } } else { if((m_codecFunction == CODECHAL_FUNCTION_FEI_ENC_PAK)||(m_codecFunction == CODECHAL_FUNCTION_FEI_ENC)) { if (m_wpUseCommonKernel) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_wpState->InitKernelState()); } else { CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateWP()); } } } } if ((bStaticFrameDetectionEnable) && (!bPerMbSFD) && (!m_feiEnable)) { // init Static frame detection kernel CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateSFD()); } if (m_singleTaskPhaseSupported) { if (m_codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC) { uint32_t dwScalingBtCount = MOS_ALIGN_CEIL( m_scaling4xKernelStates[0].KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); uint32_t dwMeBtCount = MOS_ALIGN_CEIL( m_meKernelStates[0].KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); uint32_t dwPreProcBtCount = MOS_ALIGN_CEIL( PreProcKernelState.KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); // in preenc stateless case, the maximum scaling pass number is 1(for current frame/field) // + 4 (4 forward ref frames/fields) + 2(2 backward ref frames/fields) m_maxBtCount = dwScalingBtCount*(1 + 4 + 2) + dwMeBtCount + dwPreProcBtCount; } else { uint32_t dwScalingBtCount = MOS_ALIGN_CEIL( m_scaling4xKernelStates[0].KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); uint32_t dwMeBtCount = MOS_ALIGN_CEIL( m_hmeKernel ? m_hmeKernel->GetBTCount() : m_meKernelStates[0].KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); uint32_t wpbtCount = 0; if(bWeightedPredictionSupported) { if (m_wpUseCommonKernel) { wpbtCount += MOS_ALIGN_CEIL( m_wpState->GetBTCount(), m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); } else { wpbtCount += MOS_ALIGN_CEIL( pWPKernelState->KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); } } uint32_t mbEncBtCount = 0; if (nullptr != pMbEncKernelStates) { mbEncBtCount = MOS_ALIGN_CEIL( pMbEncKernelStates->KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); } uint32_t brcBtCount = 0; for (uint32_t i = 0; i < CODECHAL_ENCODE_BRC_IDX_NUM; i++) { brcBtCount += MOS_ALIGN_CEIL( BrcKernelStates[i].KernelParams.iBTCount, m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment()); } uint32_t encOneBtCount = dwScalingBtCount + dwMeBtCount; encOneBtCount += (m_16xMeSupported) ? encOneBtCount : 0; encOneBtCount += (m_32xMeSupported) ? encOneBtCount : 0; uint32_t encTwoBtCount = mbEncBtCount + brcBtCount + wpbtCount; m_maxBtCount = MOS_MAX(encOneBtCount, encTwoBtCount); } } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InsertInRefPicSelectList() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto refPicSelectList = &RefPicSelectList[0]; auto picParams = m_avcPicParam; auto currEncodeRefList = m_refList[picParams->CurrReconstructedPic.FrameIdx]; uint8_t index = 0; uint8_t refFrameListIndex = 0; bool inserted = false; // Check if current PicIdx is already present in the list for (index = 0; index < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; index++) { if (refPicSelectList[index].FrameIdx == picParams->CurrReconstructedPic.FrameIdx) { ucCurrRefPicSelectIndex = index; return eStatus; } } // Save this picture in the list for future use // Use the first available index to save it for (index = 0; index < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; index++) { if (refPicSelectList[index].FrameIdx == CODECHAL_ENCODE_AVC_INVALID_PIC_ID) // Index not used { refPicSelectList[index].FrameIdx = picParams->CurrReconstructedPic.FrameIdx; ucCurrRefPicSelectIndex = index; inserted = true; break; } } if (!inserted) { // No unused index available, need to bump off an existing entry // Compare with RefFrameList sent through PicParams for (index = 0; index < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; index++) { bool foundMatch = false; for (refFrameListIndex = 0; refFrameListIndex < CODEC_AVC_MAX_NUM_REF_FRAME; refFrameListIndex++) { if (currEncodeRefList->RefList[refFrameListIndex].FrameIdx == refPicSelectList[index].FrameIdx) { // reference still present in ref frame list, cannot be replaced foundMatch = true; } } // Found an entry thats not in ref frame list anymore, safe to reuse if (foundMatch == false) { refPicSelectList[index].FrameIdx = picParams->CurrReconstructedPic.FrameIdx; ucCurrRefPicSelectIndex = index; inserted = true; break; } } if (!inserted) { CODECHAL_ENCODE_ASSERTMESSAGE("Could not find an unused entry, this should never happen."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::MbEncKernel(bool mbEncIFrameDistInUse) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; uint8_t ppsidx = m_avcSliceParams->pic_parameter_set_id; uint8_t spsidx = m_avcPicParams[ppsidx]->seq_parameter_set_id; auto refList = &m_refList[0]; auto currRefList = m_refList[m_currReconstructedPic.FrameIdx]; bool use45DegreePattern = false; bool roiEnabled = (m_avcPicParams[ppsidx]->NumROI > 0) ? true : false; uint8_t refPicListIdx = m_avcSliceParams[ppsidx].RefPicList[0][0].FrameIdx; uint8_t refFrameListIdx = m_avcPicParam[ppsidx].RefFrameList[refPicListIdx].FrameIdx; bool bDirtyRoiEnabled = (m_pictureCodingType == P_TYPE && m_avcPicParams[ppsidx]->NumDirtyROI > 0 && m_prevReconFrameIdx == refFrameListIdx); // Two flags(bMbConstDataBufferNeeded, bMbQpBufferNeeded) // would be used as there are two buffers and not all cases need both the buffers // Constant Data buffer needed for MBBRC, MBQP, ROI, RollingIntraRefresh // Please note that this surface needs to be programmed for // all usage cases(including CQP cases) because DWord13 includes mode cost for high texture MB?s cost. bool bMbConstDataBufferInUse = bMbBrcEnabled || bMbQpDataEnabled || roiEnabled || bDirtyRoiEnabled || m_avcPicParam->EnableRollingIntraRefresh || bHighTextureModeCostEnable; bool mbQpBufferInUse = bMbBrcEnabled || bBrcRoiEnabled || bMbQpDataEnabled; if (m_feiEnable) { CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcFeiPicParams); bMbConstDataBufferInUse |= m_avcFeiPicParams->bMBQp; mbQpBufferInUse |= m_avcFeiPicParams->bMBQp; } // MFE MBEnc kernel handles several frames from different streams in one submission. // All the streams use the same HW/OS/StateHeap interfaces during this submssion. // All the streams use the kernel state from the first stream. // The first stream allocates the DSH and SSH, send the binding table. // The last stream sets mfe curbe, prepare and submit the command buffer. // All the streams set their own curbe surfaces and surface states. CODECHAL_ENCODE_AVC_BINDING_TABLE_MBENC origMbEncBindingTable; if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) { auto mfeEncodeSharedState = m_mfeEncodeSharedState; if (m_mfeFirstStream) { mfeEncodeSharedState->pHwInterface = m_hwInterface; mfeEncodeSharedState->pOsInterface = m_osInterface; m_hwInterface->GetRenderInterface()->m_stateHeapInterface = m_stateHeapInterface; m_osInterface->pfnResetOsStates(m_osInterface); } else { m_hwInterface = mfeEncodeSharedState->pHwInterface; m_osInterface = mfeEncodeSharedState->pOsInterface; m_stateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface; m_renderEngineInterface->SetOsInterface(m_osInterface); } // Set maximum width/height, it is used for initializing media walker parameters // during submitting the command buffer at the last stream. if (m_picWidthInMb > mfeEncodeSharedState->dwPicWidthInMB) { mfeEncodeSharedState->dwPicWidthInMB = m_picWidthInMb; } if (m_frameFieldHeightInMb > mfeEncodeSharedState->dwPicHeightInMB) { mfeEncodeSharedState->dwPicHeightInMB = m_frameFieldHeightInMb; } uint16_t sliceHeight = m_arbitraryNumMbsInSlice ? m_frameFieldHeightInMb : m_sliceHeight; if (sliceHeight > mfeEncodeSharedState->sliceHeight) { mfeEncodeSharedState->sliceHeight = sliceHeight; } m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext); CODECHAL_DEBUG_TOOL( m_debugInterface->m_osInterface = m_osInterface;) // bookkeeping the original binding table origMbEncBindingTable = MbEncBindingTable; } PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = (mbEncIFrameDistInUse && !m_singleTaskPhaseSupported) ? CODECHAL_ENCODE_PERFTAG_CALL_INTRA_DIST : CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); CODECHAL_MEDIA_STATE_TYPE encFunctionType; if (mbEncIFrameDistInUse) { encFunctionType = CODECHAL_MEDIA_STATE_ENC_I_FRAME_DIST; } else if (bUseMbEncAdvKernel) { encFunctionType = CODECHAL_MEDIA_STATE_ENC_ADV; } else if (m_kernelMode == encodeNormalMode) { encFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL; } else if (m_kernelMode == encodePerformanceMode) { encFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE; } else { encFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY; } // Initialize DSH kernel region PMHW_KERNEL_STATE kernelState; if (mbEncIFrameDistInUse) { kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST]; } else if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) { kernelState = &mfeMbEncKernelState; } else { CodechalEncodeIdOffsetParams idOffsetParams; MOS_ZeroMemory(&idOffsetParams, sizeof(idOffsetParams)); idOffsetParams.Standard = m_standard; idOffsetParams.EncFunctionType = encFunctionType; idOffsetParams.wPictureCodingType = m_pictureCodingType; idOffsetParams.ucDmvPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag; idOffsetParams.interlacedField = CodecHal_PictureIsField(m_currOriginalPic); uint32_t krnStateIdx; CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbEncKernelStateIdx( &idOffsetParams, &krnStateIdx)); kernelState = &pMbEncKernelStates[krnStateIdx]; } // All the streams use the kernel state from the first stream. if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) { if (m_mfeFirstStream) { m_mfeEncodeSharedState->pMfeMbEncKernelState = kernelState; } else { kernelState = m_mfeEncodeSharedState->pMfeMbEncKernelState; } } // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported || (IsMfeMbEncEnabled(mbEncIFrameDistInUse) && m_mfeFirstStream)) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } // Allocate DSH and SSH for the first stream, which will be passed to other streams through the shared kernel state. if ((IsMfeMbEncEnabled(mbEncIFrameDistInUse) && m_mfeFirstStream) || (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) && !bMbEncCurbeSetInBrcUpdate)) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, false, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); } if (bMbEncCurbeSetInBrcUpdate) { if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse)) { // If BRC update was used to set up the DSH & SSH, SSH only needs to // be obtained if single task phase is enabled because the same SSH // could not be shared between BRC update and MbEnc CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, true, 0, m_singleTaskPhaseSupported, m_storeData)); } } else { // Setup AVC Curbe CODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS mbEncCurbeParams; MOS_ZeroMemory(&mbEncCurbeParams, sizeof(mbEncCurbeParams)); mbEncCurbeParams.pPicParams = m_avcPicParams[ppsidx]; mbEncCurbeParams.pSeqParams = m_avcSeqParams[spsidx]; mbEncCurbeParams.pSlcParams = m_avcSliceParams; mbEncCurbeParams.ppRefList = &(m_refList[0]); mbEncCurbeParams.pPicIdx = &(m_picIdx[0]); mbEncCurbeParams.bRoiEnabled = roiEnabled; mbEncCurbeParams.bDirtyRoiEnabled = bDirtyRoiEnabled; mbEncCurbeParams.bMbEncIFrameDistEnabled = mbEncIFrameDistInUse; mbEncCurbeParams.pdwBlockBasedSkipEn = &dwMbEncBlockBasedSkipEn; if (mbEncIFrameDistInUse) { mbEncCurbeParams.bBrcEnabled = false; mbEncCurbeParams.wPicWidthInMb = (uint16_t)m_downscaledWidthInMb4x; mbEncCurbeParams.wFieldFrameHeightInMb = (uint16_t)m_downscaledFrameFieldHeightInMb4x; mbEncCurbeParams.usSliceHeight = (m_sliceHeight + SCALE_FACTOR_4x - 1) / SCALE_FACTOR_4x; } else { mbEncCurbeParams.bBrcEnabled = bBrcEnabled; mbEncCurbeParams.wPicWidthInMb = m_picWidthInMb; mbEncCurbeParams.wFieldFrameHeightInMb = m_frameFieldHeightInMb; mbEncCurbeParams.usSliceHeight = (m_arbitraryNumMbsInSlice) ? m_frameFieldHeightInMb : m_sliceHeight; mbEncCurbeParams.bUseMbEncAdvKernel = bUseMbEncAdvKernel; } mbEncCurbeParams.pKernelState = kernelState; mbEncCurbeParams.pAvcQCParams = m_avcQCParams ; mbEncCurbeParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled; mbEncCurbeParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled; mbEncCurbeParams.bApdatvieSearchWindowSizeEnabled = bApdatvieSearchWindowEnable; mbEncCurbeParams.bSquareRollingIEnabled = bSquareRollingIEnabled; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbEnc( &mbEncCurbeParams)); } if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) { // Set MFE specific curbe in the last stream // MFE MBEnc specific curbe is different from the normal MBEnc curbe which is passed // to MFE MBEnc kernel as a surface. if (m_mfeLastStream) { CODECHAL_ENCODE_AVC_MFE_MBENC_CURBE_PARAMS mfeMbEncCurbeParams; MOS_ZeroMemory(&mfeMbEncCurbeParams, sizeof(mfeMbEncCurbeParams)); mfeMbEncCurbeParams.submitNumber = m_mfeEncodeParams.submitNumber; mfeMbEncCurbeParams.pKernelState = kernelState; mfeMbEncCurbeParams.pBindingTable = &MbEncBindingTable; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMfeMbEnc(&mfeMbEncCurbeParams)); } // Change the binding table according to the index during this submission UpdateMfeMbEncBindingTable(m_mfeEncodeParams.submitIndex); } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( encFunctionType, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_ISH_TYPE, kernelState)); ) for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) { if (m_picIdx[i].bValid) { uint8_t index = m_picIdx[i].ucPicIdx; refList[index]->sRefBuffer = m_userFlags.bUseRawPicForRef ? refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer; CodecHalGetResourceInfo(m_osInterface, &refList[index]->sRefBuffer); } } MOS_COMMAND_BUFFER cmdBuffer; MOS_ZeroMemory(&cmdBuffer,sizeof(cmdBuffer)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); // For MFE, All the commands are sent in the last stream and can not be sent in different streams // since cmdBuffer is zeroed for each stream and cmd buffer pointer is reset. if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeLastStream) { SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = encFunctionType; sendKernelCmdsParams.ucDmvPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag; sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); } // Set up MB BRC Constant Data Buffer if there is QP change within a frame if (bMbConstDataBufferInUse) { CODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS initMbBrcConstantDataBufferParams; MOS_ZeroMemory(&initMbBrcConstantDataBufferParams, sizeof(initMbBrcConstantDataBufferParams)); initMbBrcConstantDataBufferParams.pOsInterface = m_osInterface; initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer = &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx]; initMbBrcConstantDataBufferParams.dwMbEncBlockBasedSkipEn = dwMbEncBlockBasedSkipEn; initMbBrcConstantDataBufferParams.pPicParams = m_avcPicParams[ppsidx]; initMbBrcConstantDataBufferParams.wPictureCodingType = m_pictureCodingType; initMbBrcConstantDataBufferParams.bSkipBiasAdjustmentEnable = m_skipBiasAdjustmentEnable; initMbBrcConstantDataBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable; initMbBrcConstantDataBufferParams.bOldModeCostEnable = bOldModeCostEnable; initMbBrcConstantDataBufferParams.pAvcQCParams = m_avcQCParams ; initMbBrcConstantDataBufferParams.bEnableKernelTrellis = bKernelTrellis && m_trellisQuantParams.dwTqEnabled; // Kernel controlled Trellis Quantization if (bKernelTrellis && m_trellisQuantParams.dwTqEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(CalcLambdaTable( m_pictureCodingType, &initMbBrcConstantDataBufferParams.Lambda[0][0])); } CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMbBrcConstantDataBuffer(&initMbBrcConstantDataBufferParams)); // dump MbBrcLut CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer, CodechalDbgAttr::attrInput, "MbBrcLut", 16 * (CODEC_AVC_NUM_QP) * sizeof(uint32_t), 0, CODECHAL_MEDIA_STATE_ENC_QUALITY))); } // Add binding table // For MFE first stream sends binding table since the function zeros the whole SSH. // If last stream sends binding table it will clean the surface states from other streams. if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeFirstStream) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); } //Add surface states CODECHAL_ENCODE_AVC_MBENC_SURFACE_PARAMS mbEncSurfaceParams; MOS_ZeroMemory(&mbEncSurfaceParams, sizeof(mbEncSurfaceParams)); mbEncSurfaceParams.MediaStateType = encFunctionType; mbEncSurfaceParams.pAvcSlcParams = m_avcSliceParams; mbEncSurfaceParams.ppRefList = &m_refList[0]; mbEncSurfaceParams.pAvcPicIdx = &m_picIdx[0]; mbEncSurfaceParams.pCurrOriginalPic = &m_currOriginalPic; mbEncSurfaceParams.pCurrReconstructedPic = &m_currReconstructedPic; mbEncSurfaceParams.wPictureCodingType = m_pictureCodingType; mbEncSurfaceParams.psCurrPicSurface = mbEncIFrameDistInUse ? m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER) : m_rawSurfaceToEnc; if (mbEncIFrameDistInUse && CodecHal_PictureIsBottomField(m_currOriginalPic)) { mbEncSurfaceParams.dwCurrPicSurfaceOffset = m_scaledBottomFieldOffset; } mbEncSurfaceParams.dwMbCodeBottomFieldOffset = (uint32_t)m_mbcodeBottomFieldOffset; mbEncSurfaceParams.dwMvBottomFieldOffset = (uint32_t)m_mvBottomFieldOffset; mbEncSurfaceParams.ps4xMeMvDataBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer; mbEncSurfaceParams.ps4xMeDistortionBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer; mbEncSurfaceParams.dwMeMvBottomFieldOffset = m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset(): (uint32_t)m_meMvBottomFieldOffset; mbEncSurfaceParams.psMeBrcDistortionBuffer = &BrcBuffers.sMeBrcDistortionBuffer; mbEncSurfaceParams.dwMeBrcDistortionBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset; mbEncSurfaceParams.dwMeDistortionBottomFieldOffset = m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset; mbEncSurfaceParams.dwRefPicSelectBottomFieldOffset = (uint32_t)ulRefPicSelectBottomFieldOffset; mbEncSurfaceParams.dwFrameWidthInMb = (uint32_t)m_picWidthInMb; mbEncSurfaceParams.dwFrameFieldHeightInMb = (uint32_t)m_frameFieldHeightInMb; mbEncSurfaceParams.dwFrameHeightInMb = (uint32_t)m_picHeightInMb; // Interleaved input surfaces mbEncSurfaceParams.dwVerticalLineStride = m_verticalLineStride; mbEncSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset; // Vertical line stride is not used for the case of scaled surfaces saved as separate fields if (!m_fieldScalingOutputInterleaved && mbEncIFrameDistInUse) { mbEncSurfaceParams.dwVerticalLineStride = 0; mbEncSurfaceParams.dwVerticalLineStrideOffset = 0; } mbEncSurfaceParams.bHmeEnabled = m_hmeSupported; mbEncSurfaceParams.bMbEncIFrameDistInUse = mbEncIFrameDistInUse; mbEncSurfaceParams.presMbBrcConstDataBuffer = &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx]; mbEncSurfaceParams.psMbQpBuffer = bMbQpDataEnabled ? &sMbQpDataSurface : &BrcBuffers.sBrcMbQpBuffer; mbEncSurfaceParams.dwMbQpBottomFieldOffset = bMbQpDataEnabled ? 0 : BrcBuffers.dwBrcMbQpBottomFieldOffset; mbEncSurfaceParams.bUsedAsRef = m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef; mbEncSurfaceParams.presMADDataBuffer = &m_resMadDataBuffer[m_currMadBufferIdx]; mbEncSurfaceParams.bMbQpBufferInUse = mbQpBufferInUse; mbEncSurfaceParams.bMbSpecificDataEnabled = bMbSpecificDataEnabled; mbEncSurfaceParams.presMbSpecificDataBuffer = &resMbSpecificDataBuffer[m_currRecycledBufIdx]; mbEncSurfaceParams.bMbConstDataBufferInUse = bMbConstDataBufferInUse; mbEncSurfaceParams.bMADEnabled = mbEncIFrameDistInUse ? false : m_madEnabled; mbEncSurfaceParams.bUseMbEncAdvKernel = mbEncIFrameDistInUse ? false : bUseMbEncAdvKernel; mbEncSurfaceParams.presMbEncCurbeBuffer = (mbEncIFrameDistInUse && bUseMbEncAdvKernel) ? nullptr : &BrcBuffers.resMbEncAdvancedDsh; mbEncSurfaceParams.presMbEncBRCBuffer = &BrcBuffers.resMbEncBrcBuffer; if (IsMfeMbEncEnabled(mbEncIFrameDistInUse) || bDecoupleMbEncCurbeFromBRC) { mbEncSurfaceParams.dwMbEncBRCBufferSize = m_mbencBrcBufferSize; } mbEncSurfaceParams.bUseAdvancedDsh = bAdvancedDshInUse; mbEncSurfaceParams.bBrcEnabled = bBrcEnabled; mbEncSurfaceParams.bArbitraryNumMbsInSlice = m_arbitraryNumMbsInSlice; mbEncSurfaceParams.psSliceMapSurface = &m_sliceMapSurface[m_currRecycledBufIdx]; mbEncSurfaceParams.dwSliceMapBottomFieldOffset = (uint32_t)m_sliceMapBottomFieldOffset; mbEncSurfaceParams.pMbEncBindingTable = &MbEncBindingTable; mbEncSurfaceParams.pKernelState = kernelState; if (m_mbStatsSupported) { mbEncSurfaceParams.bMBVProcStatsEnabled = m_flatnessCheckEnabled || m_adaptiveTransformDecisionEnabled || bMbBrcEnabled || bMbQpDataEnabled; mbEncSurfaceParams.presMBVProcStatsBuffer = &m_resMbStatsBuffer; mbEncSurfaceParams.dwMBVProcStatsBottomFieldOffset = m_mbStatsBottomFieldOffset; } else { mbEncSurfaceParams.bFlatnessCheckEnabled = m_flatnessCheckEnabled; mbEncSurfaceParams.psFlatnessCheckSurface = &m_flatnessCheckSurface; mbEncSurfaceParams.dwFlatnessCheckBottomFieldOffset = (uint32_t)m_flatnessCheckBottomFieldOffset; } // Set up pFeiPicParams mbEncSurfaceParams.pFeiPicParams = m_avcFeiPicParams; mbEncSurfaceParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled; mbEncSurfaceParams.psMbDisableSkipMapSurface = psMbDisableSkipMapSurface; if (bUseWeightedSurfaceForL0 || bUseWeightedSurfaceForL1) { if (!m_wpUseCommonKernel) { mbEncSurfaceParams.pWeightedPredOutputPicSelectList = &WeightedPredOutputPicSelectList[0]; } mbEncSurfaceParams.bUseWeightedSurfaceForL0 = bUseWeightedSurfaceForL0; mbEncSurfaceParams.bUseWeightedSurfaceForL1 = bUseWeightedSurfaceForL1; } // Clear the MAD buffer -- the kernel requires it to be 0 as it accumulates the result if (mbEncSurfaceParams.bMADEnabled) { // set lock flag to WRITE_ONLY MOS_LOCK_PARAMS lockFlags; MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); lockFlags.WriteOnly = 1; uint8_t* pbData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, mbEncSurfaceParams.presMADDataBuffer, &lockFlags); CODECHAL_ENCODE_CHK_NULL_RETURN(pbData); MOS_ZeroMemory(pbData, CODECHAL_MAD_BUFFER_SIZE); m_osInterface->pfnUnlockResource( m_osInterface, mbEncSurfaceParams.presMADDataBuffer); CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_resMadDataBuffer[m_currMadBufferIdx], CodechalDbgAttr::attrOutput, "MADRead", CODECHAL_MAD_BUFFER_SIZE, 0, encFunctionType))); } // static frame detection buffer mbEncSurfaceParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled; mbEncSurfaceParams.presSFDOutputBuffer = &resSFDOutputBuffer[0]; if (m_pictureCodingType == P_TYPE) { mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTablePFrameBuffer; } else if (m_pictureCodingType == B_TYPE) { mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTableBFrameBuffer; } CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcMbEncSurfaces(&cmdBuffer, &mbEncSurfaceParams)); // For MFE, only one walker processes frame in parallel through color bits. if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeLastStream) { uint32_t dwResolutionX = mbEncIFrameDistInUse ? m_downscaledWidthInMb4x : (uint32_t)m_picWidthInMb; uint32_t dwResolutionY = mbEncIFrameDistInUse ? m_downscaledFrameFieldHeightInMb4x : (uint32_t)m_frameFieldHeightInMb; CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams; MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams)); walkerCodecParams.WalkerMode = m_walkerMode; walkerCodecParams.bUseScoreboard = m_useHwScoreboard; walkerCodecParams.wPictureCodingType = m_pictureCodingType; walkerCodecParams.bMbEncIFrameDistInUse = mbEncIFrameDistInUse; walkerCodecParams.bMbaff = m_mbaffEnabled; walkerCodecParams.bDirectSpatialMVPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag; if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) { walkerCodecParams.bColorbitSupported = true; walkerCodecParams.dwNumSlices = m_mfeEncodeParams.submitNumber; // MFE use color bit to handle frames in parallel walkerCodecParams.WalkerDegree = CODECHAL_26_DEGREE; // MFE use 26 degree dependency walkerCodecParams.dwResolutionX = m_mfeEncodeSharedState->dwPicWidthInMB; walkerCodecParams.dwResolutionY = m_mfeEncodeSharedState->dwPicHeightInMB; walkerCodecParams.usSliceHeight = m_mfeEncodeSharedState->sliceHeight; } else { walkerCodecParams.bColorbitSupported = (m_colorbitSupported && !m_arbitraryNumMbsInSlice) ? m_cmKernelEnable : false; walkerCodecParams.dwResolutionX = dwResolutionX; walkerCodecParams.dwResolutionY = dwResolutionY; walkerCodecParams.dwNumSlices = m_numSlices; walkerCodecParams.usSliceHeight = m_sliceHeight; } walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported; walkerCodecParams.ucGroupId = m_groupId; MHW_WALKER_PARAMS walkerParams; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams( m_hwInterface, &walkerParams, &walkerCodecParams)); HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd( &cmdBuffer, &walkerParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); // Add dump for MBEnc surface state heap here CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_SSH_TYPE, kernelState)); ) CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( &cmdBuffer, encFunctionType, nullptr))); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if ((!m_singleTaskPhaseSupported || m_lastTaskInPhase)) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } } CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.sBrcMbQpBuffer.OsResource, CodechalDbgAttr::attrInput, "MbQp", BrcBuffers.sBrcMbQpBuffer.dwPitch*BrcBuffers.sBrcMbQpBuffer.dwHeight, BrcBuffers.dwBrcMbQpBottomFieldOffset, CODECHAL_MEDIA_STATE_ENC_NORMAL))); currRefList->ucMADBufferIdx = m_currMadBufferIdx; currRefList->bMADEnabled = m_madEnabled; if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) { m_stateHeapInterface = m_origStateHeapInterface; m_hwInterface = m_origHwInterface; m_osInterface = m_origOsInterface; m_renderEngineInterface->SetOsInterface(m_origOsInterface); MbEncBindingTable = origMbEncBindingTable; CODECHAL_DEBUG_TOOL( m_debugInterface->m_osInterface = m_osInterface;) } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::BrcFrameUpdateKernel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; if (m_lastTaskInPhase) { perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE; } else { perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE; } perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); auto kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_FrameBRC_UPDATE]; uint8_t ppsidx = m_avcSliceParams->pic_parameter_set_id; uint8_t refPicListIdx = m_avcSliceParams[ppsidx].RefPicList[0][0].FrameIdx; uint8_t refFrameListIdx = m_avcPicParam[ppsidx].RefFrameList[refPicListIdx].FrameIdx; bool bDirtyRoiEnabled = (m_pictureCodingType == P_TYPE && m_avcPicParams[ppsidx]->NumDirtyROI > 0 && m_prevReconFrameIdx == refFrameListIdx); // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_UPDATE; CODECHAL_MEDIA_STATE_TYPE mbEncFunctionType; if (bUseMbEncAdvKernel) { mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_ADV; } else if (m_kernelMode == encodeNormalMode) { mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL; } else if (m_kernelMode == encodePerformanceMode) { mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE; } else { mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY; } uint32_t krnStateIdx; CodechalEncodeIdOffsetParams idOffsetParams; MOS_ZeroMemory(&idOffsetParams, sizeof(idOffsetParams)); idOffsetParams.Standard = m_standard; idOffsetParams.EncFunctionType = mbEncFunctionType; idOffsetParams.wPictureCodingType = m_pictureCodingType; idOffsetParams.ucDmvPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag; idOffsetParams.interlacedField = CodecHal_PictureIsField(m_currOriginalPic); CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbEncKernelStateIdx( &idOffsetParams, &krnStateIdx)); auto mbEncKernelState = &pMbEncKernelStates[krnStateIdx]; auto brcImageStatesReadBuffer = &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx]; // No need to setup MBEnc Curbe for Gen95+ platforms. if (!bDecoupleMbEncCurbeFromBRC) { // Mfe use MBEnc Curbe buffer instead of DSH if (IsMfeMbEncEnabled(false)) { BrcBuffers.pMbEncKernelStateInUse = nullptr; } else { BrcBuffers.pMbEncKernelStateInUse = mbEncKernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, mbEncKernelState, false, 0, !m_singleTaskPhaseSupported, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = mbEncKernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); } CODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS mbEncCurbeParams; MOS_ZeroMemory(&mbEncCurbeParams, sizeof(mbEncCurbeParams)); mbEncCurbeParams.pPicParams = m_avcPicParam; mbEncCurbeParams.pSeqParams = m_avcSeqParam; mbEncCurbeParams.pSlcParams = m_avcSliceParams; mbEncCurbeParams.ppRefList = &(m_refList[0]); mbEncCurbeParams.pPicIdx = &(m_picIdx[0]); mbEncCurbeParams.pdwBlockBasedSkipEn = &dwMbEncBlockBasedSkipEn; mbEncCurbeParams.wPicWidthInMb = m_picWidthInMb; mbEncCurbeParams.wFieldFrameHeightInMb = m_frameFieldHeightInMb; mbEncCurbeParams.usSliceHeight = (m_arbitraryNumMbsInSlice) ? m_frameFieldHeightInMb : m_sliceHeight; mbEncCurbeParams.bRoiEnabled = (m_avcPicParams[m_avcSliceParams->pic_parameter_set_id]->NumROI > 0) ? true : false; mbEncCurbeParams.bDirtyRoiEnabled = bDirtyRoiEnabled; mbEncCurbeParams.bBrcEnabled = true; mbEncCurbeParams.pKernelState = mbEncKernelState; mbEncCurbeParams.pAvcQCParams = m_avcQCParams ; mbEncCurbeParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled; mbEncCurbeParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled; mbEncCurbeParams.bApdatvieSearchWindowSizeEnabled = bApdatvieSearchWindowEnable; mbEncCurbeParams.bSquareRollingIEnabled = bSquareRollingIEnabled; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbEnc(&mbEncCurbeParams)); // BrcCopy is not needed if MbEnc Adv kenrel is used. if (!bUseMbEncAdvKernel && bAdvancedDshInUse) { CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcCopyKernel()); } } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, (m_swBrcMode != nullptr), m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); // Setup BRC Update Curbe CODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS brcUpdateCurbeParams; MOS_ZeroMemory(&brcUpdateCurbeParams, sizeof(brcUpdateCurbeParams)); // set skipped frame params to be used in pfnSetCurbeAvcFrameBrcUpdate() if (m_numSkipFrames > 0) { // CP case: one or more frames with skip flag = 2 received and copied brcUpdateCurbeParams.dwNumSkipFrames = m_numSkipFrames; brcUpdateCurbeParams.dwSizeSkipFrames = m_sizeSkipFrames; // this should not happen since skip flag == 1 means non-CP user case // but we accumulate the num/size of skipped frame per BRC if (FRAME_SKIP_NORMAL == m_skipFrameFlag) { brcUpdateCurbeParams.dwNumSkipFrames += m_avcPicParam->NumSkipFrames; brcUpdateCurbeParams.dwSizeSkipFrames += m_avcPicParam->SizeSkipFrames; } } else if (FRAME_SKIP_NORMAL == m_skipFrameFlag) { // non-CP case: use the num/size of skipped frames passed in by MSDK brcUpdateCurbeParams.dwNumSkipFrames = m_avcPicParam->NumSkipFrames; brcUpdateCurbeParams.dwSizeSkipFrames = m_avcPicParam->SizeSkipFrames; } else brcUpdateCurbeParams.dwNumSkipFrames = 0; // Setting min/max QP to zero indicates to the kernel that no QP control is desired if (m_pictureCodingType == I_TYPE) { brcUpdateCurbeParams.ucMinQP = ucIMinQP; brcUpdateCurbeParams.ucMaxQP = ucIMaxQP; } else if (m_pictureCodingType == P_TYPE) { brcUpdateCurbeParams.ucMinQP = ucPMinQP; brcUpdateCurbeParams.ucMaxQP = ucPMaxQP; } else { brcUpdateCurbeParams.ucMinQP = ucBMinQP; brcUpdateCurbeParams.ucMaxQP = ucBMaxQP; } // reset skip frame statistics m_numSkipFrames = 0; m_sizeSkipFrames = 0; bMbEncCurbeSetInBrcUpdate = !bDecoupleMbEncCurbeFromBRC; brcUpdateCurbeParams.pdBrcInitCurrentTargetBufFullInBits = &dBrcInitCurrentTargetBufFullInBits; brcUpdateCurbeParams.pKernelState = kernelState; brcUpdateCurbeParams.ucEnableROI = (uint8_t)bBrcRoiEnabled; brcUpdateCurbeParams.dwIntraRefreshQpThreshold = dwIntraRefreshQpThreshold; brcUpdateCurbeParams.bSquareRollingIEnabled = bSquareRollingIEnabled; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcFrameBrcUpdate( &brcUpdateCurbeParams)); CODECHAL_DEBUG_TOOL( if (!bDecoupleMbEncCurbeFromBRC && !IsMfeMbEncEnabled(false)) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( mbEncFunctionType, MHW_DSH_TYPE, mbEncKernelState)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( encFunctionType, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_ISH_TYPE, kernelState)); ) auto trellisQuantParams = &m_trellisQuantParams; #if (_DEBUG || _RELEASE_INTERNAL) if (m_swBrcMode != nullptr) { CODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS initBrcConstantBufferParams; // Check if the constant data surface is present initBrcConstantBufferParams.pOsInterface = m_osInterface; initBrcConstantBufferParams.pAvcSlcParams = m_avcSliceParams; initBrcConstantBufferParams.pAvcPicIdx = &m_picIdx[0]; initBrcConstantBufferParams.sBrcConstantDataBuffer = BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx]; initBrcConstantBufferParams.dwMbEncBlockBasedSkipEn = dwMbEncBlockBasedSkipEn; initBrcConstantBufferParams.pPicParams = m_avcPicParam; initBrcConstantBufferParams.wPictureCodingType = m_pictureCodingType; initBrcConstantBufferParams.bSkipBiasAdjustmentEnable = m_skipBiasAdjustmentEnable; initBrcConstantBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable; initBrcConstantBufferParams.bOldModeCostEnable = bOldModeCostEnable; initBrcConstantBufferParams.pAvcQCParams = m_avcQCParams ; CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&initBrcConstantBufferParams)); MHW_VDBOX_AVC_IMG_PARAMS imageStateParams; imageStateParams.pEncodeAvcPicParams = m_avcPicParam; imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam; imageStateParams.wPicWidthInMb = m_picWidthInMb; imageStateParams.wPicHeightInMb = m_picHeightInMb; imageStateParams.ppRefList = &(m_refList[0]); imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled; imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding; imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level); imageStateParams.ucKernelMode = m_kernelMode; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgBrcBuffer( brcImageStatesReadBuffer, &imageStateParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx], CodechalDbgAttr::attrInput, "ImgStateRead", BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(), 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].OsResource, CodechalDbgAttr::attrInput, "ConstData", BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwPitch * BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwHeight, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); // PAK statistics buffer is only dumped for BrcUpdate kernel input CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcPakStatisticBuffer[0], CodechalDbgAttr::attrInput, "PakStats", m_brcPakStatisticsSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.sMeBrcDistortionBuffer.OsResource, CodechalDbgAttr::attrInput, "BrcDist", BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight, BrcBuffers.dwMeBrcDistortionBottomFieldOffset, CODECHAL_MEDIA_STATE_BRC_UPDATE)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcHistoryBuffer, CodechalDbgAttr::attrInput, "HistoryRead", m_brcHistoryBufferSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); if (BrcBuffers.pMbEncKernelStateInUse) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( CODECHAL_MEDIA_STATE_BRC_UPDATE, BrcBuffers.pMbEncKernelStateInUse)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_resMbStatsBuffer, CodechalDbgAttr::attrInput, "MBStatsSurf", m_hwInterface->m_avcMbStatBufferSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); // CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgCallAvcSwBrcImpl( // m_debugInterface, // encFunctionType, // this, // &BrcBuffers, // false, // kernelState, // mbEncKernelState)); return eStatus; } #endif MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = encFunctionType; sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); CODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS initBrcConstantBufferParams; // Check if the constant data surface is present initBrcConstantBufferParams.pOsInterface = m_osInterface; initBrcConstantBufferParams.pAvcSlcParams = m_avcSliceParams; initBrcConstantBufferParams.pAvcPicIdx = &m_picIdx[0]; initBrcConstantBufferParams.sBrcConstantDataBuffer = BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx]; initBrcConstantBufferParams.dwMbEncBlockBasedSkipEn = dwMbEncBlockBasedSkipEn; initBrcConstantBufferParams.pPicParams = m_avcPicParam; initBrcConstantBufferParams.wPictureCodingType = m_pictureCodingType; initBrcConstantBufferParams.bSkipBiasAdjustmentEnable = m_skipBiasAdjustmentEnable; initBrcConstantBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable; initBrcConstantBufferParams.bOldModeCostEnable = bOldModeCostEnable; initBrcConstantBufferParams.pAvcQCParams = m_avcQCParams ; CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&initBrcConstantBufferParams)); MHW_VDBOX_AVC_IMG_PARAMS imageStateParams; imageStateParams.pEncodeAvcPicParams = m_avcPicParam; imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam; imageStateParams.wPicWidthInMb = m_picWidthInMb; imageStateParams.wPicHeightInMb = m_picHeightInMb; imageStateParams.ppRefList = &(m_refList[0]); imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled; imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding; imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level); imageStateParams.ucKernelMode = m_kernelMode; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgBrcBuffer( brcImageStatesReadBuffer, &imageStateParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam( nullptr, nullptr)); ) // Add binding table CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); //Add surface state CODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS brcUpdateSurfaceParams; MOS_ZeroMemory(&brcUpdateSurfaceParams, sizeof(brcUpdateSurfaceParams)); brcUpdateSurfaceParams.MbEncMediaStateType = mbEncFunctionType; brcUpdateSurfaceParams.pBrcBuffers = &BrcBuffers; brcUpdateSurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x; brcUpdateSurfaceParams.dwDownscaledFrameFieldHeightInMb4x = m_downscaledFrameFieldHeightInMb4x; brcUpdateSurfaceParams.bMbBrcEnabled = bMbBrcEnabled; brcUpdateSurfaceParams.bUseAdvancedDsh = bAdvancedDshInUse; brcUpdateSurfaceParams.dwBrcPakStatisticsSize = m_brcPakStatisticsSize; brcUpdateSurfaceParams.dwBrcHistoryBufferSize = m_brcHistoryBufferSize; brcUpdateSurfaceParams.presMbEncCurbeBuffer = &BrcBuffers.resMbEncAdvancedDsh; brcUpdateSurfaceParams.ucCurrRecycledBufIdx = m_currRecycledBufIdx; brcUpdateSurfaceParams.pBrcUpdateBindingTable = &BrcUpdateBindingTable; brcUpdateSurfaceParams.pKernelState = kernelState; brcUpdateSurfaceParams.presMbEncBRCBuffer = &BrcBuffers.resMbEncBrcBuffer; if (bDecoupleMbEncCurbeFromBRC || IsMfeMbEncEnabled(false)) { brcUpdateSurfaceParams.dwMbEncBRCBufferSize = m_mbencBrcBufferSize; } brcUpdateSurfaceParams.presMbStatBuffer = &m_resMbStatsBuffer; //Starting from GEN9 PMOS_SURFACE buffer4xMeMvData = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer; CODECHAL_ENCODE_CHK_NULL_RETURN(buffer4xMeMvData); uint32_t dwMvBufferHeightBack = buffer4xMeMvData->dwHeight; // save 4x ME output MV buffer height if (bMvDataNeededByBRC) //starting from G95 { brcUpdateSurfaceParams.psMvDataBuffer = buffer4xMeMvData; brcUpdateSurfaceParams.dwMvBottomFieldOffset = (uint32_t)m_mvBottomFieldOffset; // BRC kernel only needs the MV data for reference 0 brcUpdateSurfaceParams.psMvDataBuffer->dwHeight = m_downscaledFrameFieldHeightInMb4x * 4; } CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcBrcFrameUpdateSurfaces( &cmdBuffer, &brcUpdateSurfaceParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_SSH_TYPE, kernelState)); ) if (bMvDataNeededByBRC) //starting from G95 { // restore back 4x ME mv buffer height buffer4xMeMvData->dwHeight = dwMvBufferHeightBack; } HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); MHW_MEDIA_OBJECT_PARAMS mediaObjectParams; MediaObjectInlineData mediaObjectInlineData; MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams)); MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData)); mediaObjectParams.pInlineData = &mediaObjectInlineData; mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject( &cmdBuffer, nullptr, &mediaObjectParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( &cmdBuffer, encFunctionType, nullptr)); if (m_swBrcMode == nullptr) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx], CodechalDbgAttr::attrInput, "ImgStateRead", BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(), 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].OsResource, CodechalDbgAttr::attrInput, "ConstData", BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwPitch * BrcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwHeight, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); // PAK statistics buffer is only dumped for BrcUpdate kernel input CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcPakStatisticBuffer[0], CodechalDbgAttr::attrInput, "PakStats", m_brcPakStatisticsSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.sMeBrcDistortionBuffer.OsResource, CodechalDbgAttr::attrInput, "BrcDist", BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight, BrcBuffers.dwMeBrcDistortionBottomFieldOffset, CODECHAL_MEDIA_STATE_BRC_UPDATE)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcHistoryBuffer, CodechalDbgAttr::attrInput, "HistoryRead", m_brcHistoryBufferSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); if (BrcBuffers.pMbEncKernelStateInUse) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( CODECHAL_MEDIA_STATE_BRC_UPDATE, BrcBuffers.pMbEncKernelStateInUse)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_resMbStatsBuffer, CodechalDbgAttr::attrInput, "MBStatsSurf", m_hwInterface->m_avcMbStatBufferSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); } ) CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcHistoryBuffer, CodechalDbgAttr::attrOutput, "HistoryWrite", m_brcHistoryBufferSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE));) return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::BrcCopyKernel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(BrcBuffers.pMbEncKernelStateInUse); PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_BRC_COPY; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_BLOCK_COPY; auto kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_BLOCKCOPY]; auto mbEncKernelState = BrcBuffers.pMbEncKernelStateInUse; uint32_t blockCopyHeight = mbEncKernelState->m_dshRegion.GetSize() / CODECHAL_ENCODE_AVC_BRC_COPY_BLOCK_WIDTH; // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, false, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); if (kernelState->KernelParams.iCurbeLength > 0) { CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_CURBE_PARAMS brcBlockCopyCurbeParams; brcBlockCopyCurbeParams.pKernelState = kernelState; brcBlockCopyCurbeParams.dwBufferOffset = 0x00; brcBlockCopyCurbeParams.dwBlockHeight = blockCopyHeight; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcBrcBlockCopy( &brcBlockCopyCurbeParams)); } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( encFunctionType, kernelState)); ) MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = encFunctionType; sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); // Add binding table CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); //Add surface states for Brc Copy CODECHAL_ENCODE_CHK_STATUS_RETURN(SendBrcBlockCopySurfaces( m_hwInterface, &cmdBuffer, mbEncKernelState, kernelState, &BrcBuffers.resMbEncAdvancedDsh)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_SSH_TYPE, kernelState)); ) MHW_MEDIA_OBJECT_PARAMS mediaObjectParams; MediaObjectInlineData mediaObjectInlineData; MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams)); MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData)); mediaObjectParams.pInlineData = &mediaObjectInlineData; mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData); uint32_t blockHeight = CODECHAL_ENCODE_AVC_BRC_COPY_NUM_ROWS_PER_VME_SEND_MSG * CODECHAL_ENCODE_AVC_BRC_COPY_NUM_SEND_MSGS_PER_KERNEL; uint32_t remainingRows = blockCopyHeight; for (uint32_t i = 0; i < blockCopyHeight; i++) { if (remainingRows < blockHeight) { blockHeight = remainingRows; } mediaObjectInlineData.DW0.blockHeight = blockHeight; mediaObjectInlineData.DW0.bufferOffset = i; HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject( &cmdBuffer, nullptr, &mediaObjectParams)); remainingRows -= blockHeight; } CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::BrcMbUpdateKernel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); auto kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_MbBRC_UPDATE]; // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_MB_BRC_UPDATE; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, false, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); // Setup MbBRC Curbe CODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS brcUpdateCurbeParams; MOS_ZeroMemory(&brcUpdateCurbeParams, sizeof(brcUpdateCurbeParams)); brcUpdateCurbeParams.ucEnableROI = (uint8_t)bBrcRoiEnabled; brcUpdateCurbeParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbBrcUpdate( &brcUpdateCurbeParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( encFunctionType, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_ISH_TYPE, kernelState)); ) // Setup ROI Surface if (bBrcRoiSupported && bBrcRoiEnabled) { SetupROISurface(); } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcHistoryBuffer, CodechalDbgAttr::attrInput, "HistoryRead", m_brcHistoryBufferSize, 0, CODECHAL_MEDIA_STATE_MB_BRC_UPDATE));) MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = encFunctionType; sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); // Add binding table CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); //Add surface state CODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS brcUpdateSurfaceParams; MOS_ZeroMemory(&brcUpdateSurfaceParams, sizeof(brcUpdateSurfaceParams)); brcUpdateSurfaceParams.pBrcBuffers = &BrcBuffers; brcUpdateSurfaceParams.bMbBrcEnabled = bMbBrcEnabled; brcUpdateSurfaceParams.bBrcRoiEnabled = bBrcRoiEnabled; brcUpdateSurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x; brcUpdateSurfaceParams.dwDownscaledFrameFieldHeightInMb4x = m_downscaledFrameFieldHeightInMb4x; brcUpdateSurfaceParams.psRoiSurface = &BrcBuffers.sBrcRoiSurface; brcUpdateSurfaceParams.presMbStatBuffer = &m_resMbStatsBuffer; brcUpdateSurfaceParams.dwBrcPakStatisticsSize = m_brcPakStatisticsSize; brcUpdateSurfaceParams.dwBrcHistoryBufferSize = m_brcHistoryBufferSize; brcUpdateSurfaceParams.ucCurrRecycledBufIdx = m_currRecycledBufIdx; brcUpdateSurfaceParams.pBrcUpdateBindingTable = &BrcUpdateBindingTable; brcUpdateSurfaceParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcBrcMbUpdateSurfaces( &cmdBuffer, &brcUpdateSurfaceParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_SSH_TYPE, kernelState)); ) // set-up media walker CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams; MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams)); walkerCodecParams.WalkerMode = m_walkerMode; walkerCodecParams.dwResolutionX = MOS_ROUNDUP_SHIFT(m_picWidthInMb, 2); walkerCodecParams.dwResolutionY = MOS_ROUNDUP_SHIFT(m_picHeightInMb, 2); walkerCodecParams.bNoDependency = true; walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported; MHW_WALKER_PARAMS walkerParams; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams( m_hwInterface, &walkerParams, &walkerCodecParams)); HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd( &cmdBuffer, &walkerParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( &cmdBuffer, encFunctionType, nullptr)); ) CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::WPKernel(bool useRefPicList1, uint32_t index) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; if (Mos_ResourceIsNull(&WeightedPredOutputPicSelectList[0].sBuffer.OsResource)) { // initiate allocation parameters MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferNV12; MOS_ZeroMemory(&allocParamsForBufferNV12, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBufferNV12.Type = MOS_GFXRES_2D; allocParamsForBufferNV12.TileType = MOS_TILE_Y; allocParamsForBufferNV12.Format = Format_NV12; // WP allocation auto refPicSelect = WeightedPredOutputPicSelectList; for (uint32_t i = 0; i < CODEC_AVC_NUM_WP_FRAME; i++) { MOS_ZeroMemory(&refPicSelect[i].sBuffer, sizeof(MOS_SURFACE)); refPicSelect[i].FrameIdx = CODECHAL_ENCODE_AVC_INVALID_PIC_ID; refPicSelect[i].sBuffer.dwWidth = m_frameWidth; refPicSelect[i].sBuffer.dwHeight = m_frameHeight; allocParamsForBufferNV12.dwWidth = refPicSelect[i].sBuffer.dwWidth; allocParamsForBufferNV12.dwHeight = refPicSelect[i].sBuffer.dwHeight; allocParamsForBufferNV12.pBufName = "WP Scaled output Buffer"; CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferNV12, &refPicSelect[i].sBuffer.OsResource), "Failed to allocate WP Scaled output Buffer."); CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo( m_osInterface, &refPicSelect[i].sBuffer)); } } auto refList = &m_refList[0]; auto currRefList = m_refList[m_currReconstructedPic.FrameIdx]; PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_WP_KERNEL; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_ENC_WP; auto kernelState = pWPKernelState; // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } // Set up the DSH/SSH as normal CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, false, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); // Setup AVC Curbe CODECHAL_ENCODE_AVC_WP_CURBE_PARAMS wpcurbeParams; MOS_ZeroMemory(&wpcurbeParams, sizeof(wpcurbeParams)); wpcurbeParams.RefPicListIdx = (useRefPicList1) ? LIST_1 : LIST_0; wpcurbeParams.WPIdx = index; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcWP( &wpcurbeParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( encFunctionType, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_ISH_TYPE, kernelState)); ) MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = encFunctionType; sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); // Add binding table CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); uint8_t picIndex = 0; uint8_t wpindex; uint8_t refVDirection; uint32_t refVerticalLineStride; uint32_t refVerticalLineStrideOffset; auto refPic = m_avcSliceParams->RefPicList[useRefPicList1][index]; if (!CodecHal_PictureIsInvalid(refPic) && m_picIdx[refPic.FrameIdx].bValid) { picIndex = m_picIdx[refPic.FrameIdx].ucPicIdx; refList[picIndex]->sRefBuffer = m_userFlags.bUseRawPicForRef ? refList[picIndex]->sRefRawBuffer : refList[picIndex]->sRefReconBuffer; bool currFieldPicture = CodecHal_PictureIsField(m_currOriginalPic); bool refBottomField = (CodecHal_PictureIsBottomField(refPic)); // Program the surface based on current picture's field/frame mode if (currFieldPicture) // if current picture is field { if (refBottomField) { refVDirection = CODECHAL_VDIRECTION_BOT_FIELD; refVerticalLineStride = CODECHAL_VLINESTRIDE_FIELD; refVerticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_BOT_FIELD; } else { refVDirection = CODECHAL_VDIRECTION_TOP_FIELD; refVerticalLineStride = CODECHAL_VLINESTRIDE_FIELD; refVerticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD; } } else // if current picture is frame { refVDirection = CODECHAL_VDIRECTION_FRAME; refVerticalLineStride = CODECHAL_VLINESTRIDE_FRAME; refVerticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD; } (useRefPicList1) ? bUseWeightedSurfaceForL1 = true : bUseWeightedSurfaceForL0 = true; } else { (useRefPicList1) ? bUseWeightedSurfaceForL1 = false : bUseWeightedSurfaceForL0 = false; return eStatus; } CodecHalGetResourceInfo(m_osInterface, &refList[picIndex]->sRefBuffer); //Add surface states CODECHAL_ENCODE_AVC_WP_SURFACE_PARAMS wpsurfaceParams; MOS_ZeroMemory(&wpsurfaceParams, sizeof(wpsurfaceParams)); wpsurfaceParams.psInputRefBuffer = &refList[picIndex]->sRefBuffer; if (useRefPicList1) { wpindex = CODEC_AVC_WP_OUTPUT_L1_START + index; } else { wpindex = CODEC_AVC_WP_OUTPUT_L0_START + index; } wpsurfaceParams.psOutputScaledBuffer = &(WeightedPredOutputPicSelectList[wpindex].sBuffer); wpsurfaceParams.ucVDirection = refVDirection; wpsurfaceParams.dwVerticalLineStride = refVerticalLineStride; wpsurfaceParams.dwVerticalLineStrideOffset = refVerticalLineStrideOffset; wpsurfaceParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcWPSurfaces(&cmdBuffer, &wpsurfaceParams)); if (m_hwWalker) { uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth); uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight); CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams; MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams)); walkerCodecParams.WalkerMode = m_walkerMode; walkerCodecParams.bUseScoreboard = m_useHwScoreboard; walkerCodecParams.dwResolutionX = resolutionX; walkerCodecParams.dwResolutionY = resolutionY; walkerCodecParams.wPictureCodingType = m_pictureCodingType; walkerCodecParams.bMbaff = m_mbaffEnabled; walkerCodecParams.dwNumSlices = m_numSlices; walkerCodecParams.usSliceHeight = m_sliceHeight; walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported; walkerCodecParams.ucGroupId = m_groupId; walkerCodecParams.bNoDependency = true; /* Enforce no dependency dispatch order for Scaling kernel, */ MHW_WALKER_PARAMS walkerParams; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams( m_hwInterface, &walkerParams, &walkerCodecParams)); HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd( &cmdBuffer, &walkerParams)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); // Add dump for WP surface state heap here CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_SSH_TYPE, kernelState)); ) CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( &cmdBuffer, encFunctionType, nullptr))); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if ((!m_singleTaskPhaseSupported || m_lastTaskInPhase)) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } currRefList->ucMADBufferIdx = m_currMadBufferIdx; currRefList->bMADEnabled = m_madEnabled; return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SFDKernel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); // set function type and kernel state pointer auto encFunctionType = CODECHAL_MEDIA_STATE_STATIC_FRAME_DETECTION; auto kernelState = pSFDKernelState; // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, false, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); // set-up SFD Curbe CODECHAL_ENCODE_AVC_SFD_CURBE_PARAMS sfdcurbeParams; MOS_ZeroMemory(&sfdcurbeParams, sizeof(sfdcurbeParams)); sfdcurbeParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcSFD( &sfdcurbeParams)); // dump DSH/Curbe/ISH CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( encFunctionType, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_ISH_TYPE, kernelState)); ) MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = encFunctionType; sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); // Add binding table CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); // Add surface states CODECHAL_ENCODE_AVC_SFD_SURFACE_PARAMS sfdsurfaceParams; MOS_ZeroMemory(&sfdsurfaceParams, sizeof(sfdsurfaceParams)); sfdsurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x; sfdsurfaceParams.dwDownscaledHeightInMb4x = m_downscaledFrameFieldHeightInMb4x; sfdsurfaceParams.psMeMvDataSurface = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer; sfdsurfaceParams.dwMeMvBottomFieldOffset = m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset() : (uint32_t)m_meMvBottomFieldOffset; sfdsurfaceParams.psMeDistortionSurface = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer; sfdsurfaceParams.dwMeDistortionBottomFieldOffset = m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset; sfdsurfaceParams.presOutputBuffer = &resSFDOutputBuffer[0]; sfdsurfaceParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcSFDSurfaces( &cmdBuffer, &sfdsurfaceParams)); // dump SSH CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( encFunctionType, MHW_SSH_TYPE, kernelState)); ) HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); MHW_MEDIA_OBJECT_PARAMS mediaObjectParams; MediaObjectInlineData mediaObjectInlineData; MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams)); MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData)); mediaObjectParams.pInlineData = &mediaObjectInlineData; mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject( &cmdBuffer, nullptr, &mediaObjectParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( &cmdBuffer, encFunctionType, nullptr)); ) CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SetCurbeAvcSFD(PCODECHAL_ENCODE_AVC_SFD_CURBE_PARAMS params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(params); CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON curbe; MOS_ZeroMemory(&curbe, sizeof(curbe)); curbe.DW0.EnableIntraCostScalingForStaticFrame = 1; curbe.DW0.EnableAdaptiveMvStreamIn = 0; curbe.DW0.StreamInType = 7; curbe.DW0.SliceType = (m_pictureCodingType + 1) % 3; curbe.DW0.BRCModeEnable = (bBrcEnabled != 0); curbe.DW0.VDEncModeDisable = true; curbe.DW1.HMEStreamInRefCost = 5; curbe.DW1.NumOfRefs = m_avcSliceParams->num_ref_idx_l0_active_minus1; curbe.DW1.QPValue = m_avcPicParam->QpY + m_avcSliceParams->slice_qp_delta; // SFD kernel requires to round-down to 4-MB aligned curbe.DW2.FrameHeightInMBs = (m_oriFrameHeight / CODECHAL_MACROBLOCK_HEIGHT >> 2) << 2; curbe.DW2.FrameWidthInMBs = (m_oriFrameWidth / CODECHAL_MACROBLOCK_WIDTH >> 2) << 2; curbe.DW3.LargeMvThresh = 128; uint32_t totalMb = curbe.DW2.FrameWidthInMBs * curbe.DW2.FrameHeightInMBs; curbe.DW4.TotalLargeMvThreshold = totalMb / 100; curbe.DW5.ZMVThreshold = 4; curbe.DW6.TotalZMVThreshold = totalMb * m_avcPicParam->dwZMvThreshold / 100; curbe.DW7.MinDistThreshold = 10; if (P_TYPE == m_pictureCodingType) { CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(curbe.CostTable, CODEC_AVC_NUM_QP * sizeof(uint8_t), m_codechalEncodeAvcSfdCostTablePFrame, CODEC_AVC_NUM_QP * sizeof(uint8_t)), "Failed to copy P-frame SFD cost table"); } else if (B_TYPE == m_pictureCodingType) { CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(curbe.CostTable, CODEC_AVC_NUM_QP * sizeof(uint8_t), m_codechalEncodeAvcSfdCostTableBFrame, CODEC_AVC_NUM_QP * sizeof(uint8_t)), "Failed to copy B-frame SFD cost table"); } curbe.DW21.ActualHeightInMB = curbe.DW2.FrameHeightInMBs; curbe.DW21.ActualWidthInMB = curbe.DW2.FrameWidthInMBs; curbe.DW26.MVDataSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON; curbe.DW27.InterDistortionSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON; curbe.DW28.OutputDataSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON; CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData( &curbe, params->pKernelState->dwCurbeOffset, sizeof(curbe))); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SetSequenceStructs() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto seqParams = m_avcSeqParam; if (m_targetUsageOverride) { seqParams->TargetUsage = m_targetUsageOverride; } if (m_feiEnable) { // FEI kernel is based on normal mode TU = TARGETUSAGE_RT_SPEED(4) seqParams->TargetUsage = TARGETUSAGE_RT_SPEED; } CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetSequenceStructs()); // If 16xMe is supported then check if it is supported in the TU settings if (!m_16xMeUserfeatureControl && m_16xMeSupported) { CODECHAL_ENCODE_CHK_STATUS_RETURN(GetHmeSupportedBasedOnTU(HME_LEVEL_16x, &m_16xMeSupported)); } // If 32xMe is supported then check if it is supported in the TU settings if (!m_32xMeUserfeatureControl && m_32xMeSupported) { CODECHAL_ENCODE_CHK_STATUS_RETURN(GetHmeSupportedBasedOnTU(HME_LEVEL_32x, &m_32xMeSupported)); } if (m_firstFrame) { m_oriFrameHeight = seqParams->FrameHeight; m_oriFrameWidth = seqParams->FrameWidth; } // check if there is a dynamic resolution change if ((m_oriFrameHeight && (m_oriFrameHeight != seqParams->FrameHeight)) || (m_oriFrameWidth && (m_oriFrameWidth != seqParams->FrameWidth))) { m_resolutionChanged = true; m_oriFrameHeight = seqParams->FrameHeight; m_oriFrameWidth = seqParams->FrameWidth; // Need to call BRCInit instead of BRCReset for dynamic resolution change bBrcInit = true; } else { m_resolutionChanged = false; } usAVBRAccuracy = CODECHAL_ENCODE_AVC_DEFAULT_AVBR_ACCURACY; usAVBRConvergence = CODECHAL_ENCODE_AVC_DEFAULT_AVBR_CONVERGENCE; bBrcEnabled = CodecHalIsRateControlBrc(seqParams->RateControlMethod, CODECHAL_AVC); if (m_osInterface->osCpInterface->IsHMEnabled()) { // use MbEnc Adv kernel when DSH protection is disabled and Brc is enabled if (bBrcEnabled) { bAdvancedDshInUse = true; bUseMbEncAdvKernel = true; } } if (ucMbBrcSupportCaps && bBrcEnabled) { // control MBBRC if the user feature key does not exist if (!bMbBrcUserFeatureKeyControl) { if (seqParams->RateControlMethod == RATECONTROL_ICQ || seqParams->RateControlMethod == RATECONTROL_QVBR) { // If the rate control method is ICQ or QVBR then enable MBBRC by default for all TUs and ignore the app input bMbBrcEnabled = true; CODECHAL_ENCODE_NORMALMESSAGE("MBBRC enabled with rate control = %d", seqParams->RateControlMethod); } else if (seqParams->RateControlMethod == RATECONTROL_VCM) { // If the rate control method is VCM then disable MBBRC by default for all TUs and ignore the app input bMbBrcEnabled = false; } else { switch (seqParams->MBBRC) { case mbBrcInternal: // Enable or disable MBBRC based on TU CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbBrcEnabled(seqParams->TargetUsage, &bMbBrcEnabled)); break; case mbBrcDisabled: bMbBrcEnabled = false; break; case mbBrcEnabled: bMbBrcEnabled = true; break; } } } } dwTrellis = seqParams->Trellis; bROIValueInDeltaQP = seqParams->ROIValueInDeltaQP; // Simple check for BRC parameters; if error, disable BRC and continue encoding if (bBrcEnabled && ((((!seqParams->InitVBVBufferFullnessInBit || !seqParams->VBVBufferSizeInBit || !seqParams->MaxBitRate) && (seqParams->RateControlMethod != RATECONTROL_AVBR)) || !seqParams->TargetBitRate || !seqParams->FramesPer100Sec) && seqParams->RateControlMethod != RATECONTROL_ICQ)) { CODECHAL_ENCODE_ASSERTMESSAGE("Fatal error in AVC Encoding BRC parameters."); CODECHAL_ENCODE_ASSERTMESSAGE("RateControlMethod = %d, InitVBVBufferFullnessInBit = %d, VBVBufferSizeInBit = %d, MaxBitRate = %d, TargetBitRate = %d, FramesPer100Sec = %d", seqParams->RateControlMethod, seqParams->InitVBVBufferFullnessInBit, seqParams->VBVBufferSizeInBit, seqParams->MaxBitRate, seqParams->TargetBitRate, seqParams->FramesPer100Sec); bBrcEnabled = false; } // Mb Qp data is only enabled for CQP if (bBrcEnabled) { bMbQpDataEnabled = false; } // BRC Init or Reset if (seqParams->bInitBRC) { bBrcInit = seqParams->bInitBRC; } else { bBrcReset = seqParams->bResetBRC; } if (bBrcReset && (!bBrcEnabled || seqParams->RateControlMethod == RATECONTROL_ICQ || !bBrcDistortionBufferSupported)) { CODECHAL_ENCODE_ASSERTMESSAGE("BRC Reset cannot be trigerred on SNB or in CQP/CBR/ICQ modes - invalid BRC parameters."); bBrcReset = 0; } if (seqParams->RateControlMethod == RATECONTROL_ICQ) { if (seqParams->ICQQualityFactor < CODECHAL_ENCODE_AVC_MIN_ICQ_QUALITYFACTOR || seqParams->ICQQualityFactor > CODECHAL_ENCODE_AVC_MAX_ICQ_QUALITYFACTOR) { CODECHAL_ENCODE_ASSERTMESSAGE("Invalid ICQ Quality Factor input\n"); eStatus = MOS_STATUS_INVALID_PARAMETER; return eStatus; } } if (bBrcEnabled && !bPerMbSFD) { bStaticFrameDetectionEnable = false; } // if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer m_gopIsIdrFrameOnly = (seqParams->GopPicSize == 1 && seqParams->GopRefDist == 0); // Set sliding window size to one second by default, up to 60 if (dwSlidingWindowSize == 0) { dwSlidingWindowSize = MOS_MIN((uint32_t)(seqParams->FramesPer100Sec / 100), 60); } if (seqParams->FramesPer100Sec == 0) { return MOS_STATUS_INVALID_PARAMETER; } m_maxNumSlicesAllowed = CodecHalAvcEncode_GetMaxNumSlicesAllowed( (CODEC_AVC_PROFILE_IDC)(seqParams->Profile), (CODEC_AVC_LEVEL_IDC)(seqParams->Level), seqParams->FramesPer100Sec); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SetPictureStructs() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto picParams = m_avcPicParam; auto seqParams = m_avcSeqParam; auto avcRefList = &m_refList[0]; auto avcPicIdx = &m_picIdx[0]; uint8_t prevRefIdx = m_currReconstructedPic.FrameIdx; CODECHAL_ENCODE_CHK_NULL_RETURN(picParams); uint8_t currRefIdx = picParams->CurrReconstructedPic.FrameIdx; int16_t prevFrameNum = m_frameNum; int16_t currFrameNum = picParams->frame_num; if (m_firstFrame) { m_oriFieldCodingFlag = picParams->FieldCodingFlag; } if (Mos_ResourceIsNull(&m_reconSurface.OsResource) && (!picParams->UserFlags.bUseRawPicForRef || !(m_codecFunction == CODECHAL_FUNCTION_ENC || m_codecFunction == CODECHAL_FUNCTION_FEI_ENC))) { return MOS_STATUS_INVALID_PARAMETER; } // Sync initialize if ((m_firstFrame) || (!bBrcEnabled && picParams->UserFlags.bUseRawPicForRef) || // No need to wait for previous PAK if reconstructed pic is not used as reference (but RAW pic is used for ref) (!bBrcEnabled && (picParams->CodingType == I_TYPE)) || // No need to wait for I-Frames (!bBrcEnabled && (currFrameNum == prevFrameNum) && CodecHal_PictureIsFrame(picParams->CurrOriginalPic)) || // No need to wait if current and previous pics have same frame numbers (Same reference list is used for two pictures with same frame numbers) (!bBrcEnabled && !avcRefList[prevRefIdx]->bUsedAsRef && CodecHal_PictureIsField(picParams->CurrOriginalPic))) { m_waitForPak = false; } else { m_waitForPak = true; } if ((bBrcEnabled || picParams->RefPicFlag)) { m_signalEnc = true; } else { m_signalEnc = false; } CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetPictureStructs()); // use MbEnc Adv kenrel if rolling I or DirtyROI is enabled if (picParams->EnableRollingIntraRefresh || (picParams->NumDirtyROI > 0)) { bAdvancedDshInUse = bBrcEnabled; bUseMbEncAdvKernel = true; } bMbEncIFrameDistEnabled = bBrcDistortionBufferSupported && bBrcEnabled && (m_pictureCodingType == I_TYPE); m_mfxInterface->SetBrcNumPakPasses(GetNumBrcPakPasses(picParams->BRCPrecision)); if (bBrcEnabled) { // For ICQ mode, ignore BRCPrecision sent by the app and set the number of passes internally if (seqParams->RateControlMethod == RATECONTROL_ICQ) { m_numPasses = CODECHAL_ENCODE_AVC_ICQ_NUM_OF_PASSES - 1; // 1 original plus extra to handle IPCM MBs } // If min/max QP control is on, set single PAK pass. else if (bMinMaxQPControlEnabled) { m_numPasses = CODECHAL_ENCODE_BRC_SINGLE_PASS - 1; // single PAK pass, no IPCM (-1 because of the loop condition) } else { m_numPasses = (uint8_t)(m_mfxInterface->GetBrcNumPakPasses() - 1); // 1 original plus extra to handle BRC } // Call BrcInitReset kernel for field/frame mode change if ((m_oriFieldCodingFlag != picParams->FieldCodingFlag) && (!m_firstFrame)) { bBrcReset = true; m_oriFieldCodingFlag = picParams->FieldCodingFlag; } // check if BRC ROI feature enabled bBrcRoiEnabled = (seqParams->RateControlMethod != RATECONTROL_CQP) && picParams->NumROI; // allocated resource for MB-level BRC if ((bMbBrcEnabled = (bMbBrcEnabled || bBrcRoiEnabled))) { CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesMbBrc()); } } else { // legacy AVC : 1 original plus extra to handle IPCM MBs m_numPasses = (CODECHAL_ENCODE_AVC_CQP_NUM_OF_PASSES - 1); if (picParams->bEnableQpAdjustment) { bMbBrcEnabled = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesMbBrc()); } } //add for multiple Pass Pak if (CodecHalIsFeiEncode(m_codecFunction)) { CodecEncodeAvcFeiPicParams *feiPicParams; feiPicParams = (CodecEncodeAvcFeiPicParams *)m_encodeParams.pFeiPicParams; CODECHAL_ENCODE_CHK_NULL_RETURN(feiPicParams); if (feiPicParams->dwMaxFrameSize != 0) { m_numPasses = (uint8_t)feiPicParams->dwNumPasses; //-1+1 for additional one IPCM pass } } else if (CodecHalUsesPakEngine(m_codecFunction) && picParams->dwMaxFrameSize != 0) { m_numPasses = (uint8_t)picParams->dwNumPasses; //-1+1 for additional one IPCM pass } if (seqParams->RateControlMethod == RATECONTROL_VCM && m_pictureCodingType == B_TYPE) { CODECHAL_ENCODE_ASSERTMESSAGE("VCM BRC mode does not support B-frames\n"); eStatus = MOS_STATUS_INVALID_PARAMETER; return eStatus; } if (seqParams->RateControlMethod == RATECONTROL_VCM && (picParams->FieldCodingFlag || picParams->FieldFrameCodingFlag)) { CODECHAL_ENCODE_ASSERTMESSAGE("VCM BRC mode does not support interlaced\n"); eStatus = MOS_STATUS_INVALID_PARAMETER; return eStatus; } if (bRefPicSelectListSupported && m_encEnabled && m_refList[currRefIdx]->bUsedAsRef) { CODECHAL_ENCODE_CHK_STATUS_RETURN(InsertInRefPicSelectList()); avcRefList[currRefIdx]->pRefPicSelectListEntry = &RefPicSelectList[ucCurrRefPicSelectIndex]; } else { avcRefList[currRefIdx]->pRefPicSelectListEntry = nullptr; } // Force RepartitionCheck CODECHAL_ENCODE_AVC_RPC forceRepartitionCheck = (CODECHAL_ENCODE_AVC_RPC)picParams->ForceRepartitionCheck; switch (forceRepartitionCheck) { case CODECHAL_ENCODE_RPC_FOLLOW_DRIVER: CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCAFEnabled(&bCAFEnable)); break; case CODECHAL_ENCODE_RPC_FORCE_ENABLE: bCAFEnable = 1; break; case CODECHAL_ENCODE_RPC_FORCE_DISABLE: bCAFEnable = 0; break; default: CODECHAL_ENCODE_ASSERTMESSAGE("Invalid ForceRepartitionCheck Flag"); eStatus = MOS_STATUS_INVALID_PARAMETER; break; } CODECHAL_ENCODE_CHK_STATUS_RETURN(GetATDEnabled()); // Flatness check is enabled only if scaling will be performed and CAF is enabled. Always enable Flatness for I_type to improve quality. m_flatnessCheckEnabled = m_flatnessCheckSupported ? ((bCAFEnable || ((m_pictureCodingType == I_TYPE))) && (m_hmeSupported || bBrcEnabled)) : 0; //ATD enabled or BRC enabled for dual pipe AVC on KBL if (m_adaptiveTransformDecisionEnabled || (bBrcEnabled && m_forceBrcMbStatsEnabled)) { m_mbStatsEnabled = true; } else { m_mbStatsEnabled = false; } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SetSliceStructs() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto slcParams = m_avcSliceParams; auto seqParams = m_avcSeqParam; auto picParams = m_avcPicParam; if (m_pictureCodingType != I_TYPE) { CODECHAL_ENCODE_AVC_VALIDATE_NUM_REFS_PARAMS validateNumRefsParams; validateNumRefsParams.pSeqParams = seqParams; validateNumRefsParams.pPicParams = picParams; validateNumRefsParams.pAvcSliceParams = slcParams; validateNumRefsParams.wPictureCodingType = m_pictureCodingType; validateNumRefsParams.wPicHeightInMB = m_picHeightInMb; validateNumRefsParams.wFrameFieldHeightInMB = m_frameFieldHeightInMb; validateNumRefsParams.bFirstFieldIPic = m_firstFieldIdrPic; validateNumRefsParams.bVDEncEnabled = false; validateNumRefsParams.bPAKonly = (m_codecFunction == CODECHAL_FUNCTION_FEI_PAK) ? true : false; CODECHAL_ENCODE_CHK_STATUS_RETURN(ValidateNumReferences(&validateNumRefsParams)); } else { slcParams->num_ref_idx_l0_active_minus1 = 0; slcParams->num_ref_idx_l1_active_minus1 = 0; } CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetSliceStructs()); if (eStatus == MOS_STATUS_INVALID_PARAMETER) { CODECHAL_ENCODE_ASSERTMESSAGE("Invalid slice parameters."); } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SendBrcInitResetSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_BRC_INIT_RESET_SURFACE_PARAMS params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); CODECHAL_ENCODE_CHK_NULL_RETURN(params); CODECHAL_ENCODE_CHK_NULL_RETURN(params->presBrcHistoryBuffer); uint32_t kernelIdx = (bBrcInit) ? CODECHAL_ENCODE_BRC_IDX_INIT : CODECHAL_ENCODE_BRC_IDX_RESET; auto kernelState = &BrcKernelStates[kernelIdx]; // BRC history buffer CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; uint32_t size = MOS_BYTES_TO_DWORDS(m_brcHistoryBufferSize); MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); surfaceCodecParams.bIsWritable = true; surfaceCodecParams.presBuffer = params->presBrcHistoryBuffer; surfaceCodecParams.dwSize = size; surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE].Value; surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_HISTORY; surfaceCodecParams.bIsWritable = true; surfaceCodecParams.bRenderTarget = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceCodecParams, kernelState)); // AVC_ME BRC Distortion data buffer - output params->psMeBrcDistortionBuffer->dwWidth = MOS_ALIGN_CEIL((params->dwDownscaledWidthInMb4x * 8), 64); params->psMeBrcDistortionBuffer->dwHeight = MOS_ALIGN_CEIL((params->dwDownscaledFrameFieldHeightInMb4x * 4), 8); MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); surfaceCodecParams.bIs2DSurface = true; surfaceCodecParams.bMediaBlockRW = true; surfaceCodecParams.bIsWritable = true; surfaceCodecParams.psSurface = params->psMeBrcDistortionBuffer; surfaceCodecParams.dwOffset = params->dwMeBrcDistortionBottomFieldOffset; surfaceCodecParams.dwSize = size; surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value; surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_DISTORTION; surfaceCodecParams.bIsWritable = true; surfaceCodecParams.bRenderTarget = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceCodecParams, kernelState)); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SendAvcSFDSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_SFD_SURFACE_PARAMS params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); CODECHAL_ENCODE_CHK_NULL_RETURN(params); auto kernelState = params->pKernelState; CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; // HME MV Data surface CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeMvDataSurface); MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); surfaceCodecParams.bIs2DSurface = true; surfaceCodecParams.bMediaBlockRW = true; surfaceCodecParams.psSurface = params->psMeMvDataSurface; surfaceCodecParams.dwOffset = params->dwMeMvBottomFieldOffset; surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceCodecParams, kernelState)); // HME distortion surface CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeDistortionSurface); MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); surfaceCodecParams.bIs2DSurface = true; surfaceCodecParams.bMediaBlockRW = true; surfaceCodecParams.psSurface = params->psMeDistortionSurface; surfaceCodecParams.dwOffset = params->dwMeDistortionBottomFieldOffset; surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value; surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceCodecParams, kernelState)); // output buffer CODECHAL_ENCODE_CHK_NULL_RETURN(params->presOutputBuffer); MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); surfaceCodecParams.presBuffer = params->presOutputBuffer; surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE_COMMON); surfaceCodecParams.dwOffset = 0; surfaceCodecParams.bRenderTarget = true; surfaceCodecParams.bIsWritable = true; surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value; surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceCodecParams, kernelState)); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InitializePicture(const EncoderParams& params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto ppsidx = ((PCODEC_AVC_ENCODE_SLICE_PARAMS)(params.pSliceParams))->pic_parameter_set_id; auto spsidx = ((PCODEC_AVC_ENCODE_PIC_PARAMS)(params.pPicParams))->seq_parameter_set_id; m_madEnabled = params.bMADEnabled; m_avcSeqParams[spsidx] = (PCODEC_AVC_ENCODE_SEQUENCE_PARAMS)(params.pSeqParams); if (ppsidx >= CODEC_AVC_MAX_PPS_NUM) { return MOS_STATUS_INVALID_PARAMETER; } m_avcPicParams[ppsidx] = (PCODEC_AVC_ENCODE_PIC_PARAMS)(params.pPicParams); m_avcQCParams = (PCODECHAL_ENCODE_AVC_QUALITY_CTRL_PARAMS)params.pAVCQCParams; m_avcRoundingParams = (PCODECHAL_ENCODE_AVC_ROUNDING_PARAMS)params.pAVCRoundingParams; m_avcSeqParam = m_avcSeqParams[spsidx]; m_avcPicParam = m_avcPicParams[ppsidx]; m_avcVuiParams = (PCODECHAL_ENCODE_AVC_VUI_PARAMS)params.pVuiParams; m_avcSliceParams = (PCODEC_AVC_ENCODE_SLICE_PARAMS)params.pSliceParams; m_avcFeiPicParams = (CodecEncodeAvcFeiPicParams *)params.pFeiPicParams; m_avcIQMatrixParams = (PCODEC_AVC_IQ_MATRIX_PARAMS)params.pIQMatrixBuffer; m_avcIQWeightScaleLists = (PCODEC_AVC_ENCODE_IQ_WEIGTHSCALE_LISTS)params.pIQWeightScaleLists; m_nalUnitParams = params.ppNALUnitParams; m_sliceStructCaps = params.uiSlcStructCaps; m_skipFrameFlag = m_avcPicParam->SkipFrameFlag; // Picture and slice header packing flag from DDI caps bAcceleratorHeaderPackingCaps = params.bAcceleratorHeaderPackingCaps; CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcIQMatrixParams); // so far this only applies to AVC // can move to MotionEstimationDisableCheck() if the logic applies to other codecs later if ((!m_feiEnable) && (m_avcQCParams )) { // disable 4x/16x/32 HME if DDI wants to do so, enabling logic is not affected if (m_avcQCParams ->HMEDisable) { m_hmeSupported = false; m_16xMeSupported = false; m_32xMeSupported = false; } else if (m_avcQCParams ->SuperHMEDisable) { m_16xMeSupported = false; m_32xMeSupported = false; } else if (m_avcQCParams ->UltraHMEDisable) { m_32xMeSupported = false; } } // Mb Qp data bMbQpDataEnabled = params.bMbQpDataEnabled; if (bMbQpDataEnabled) { sMbQpDataSurface = *(params.psMbQpDataSurface); } // Mb Disable Skip Map bMbDisableSkipMapEnabled = params.bMbDisableSkipMapEnabled; if (bMbDisableSkipMapEnabled) { psMbDisableSkipMapSurface = params.psMbDisableSkipMapSurface; } // Sei for AVC if (params.pSeiData != nullptr) { if (params.pSeiData->dwSEIBufSize > 0) // sei is present { if (params.pSeiData->dwSEIBufSize > SeiData.dwSEIBufSize) { // Destroy and re-allocate if (SeiData.pSEIBuffer) { MOS_FreeMemory(SeiData.pSEIBuffer); SeiData.pSEIBuffer = nullptr; } SeiData.dwSEIBufSize = params.pSeiData->dwSEIBufSize; SeiData.pSEIBuffer = (uint8_t *)MOS_AllocAndZeroMemory(SeiData.dwSEIBufSize); CODECHAL_ENCODE_CHK_NULL_RETURN(SeiData.pSEIBuffer); } pSeiParamBuffer = params.pSeiParamBuffer; dwSEIDataOffset = params.dwSEIDataOffset; SeiData.newSEIData = params.pSeiData->newSEIData; SeiData.dwSEIDataSize = params.pSeiData->dwSEIDataSize; eStatus = MOS_SecureMemcpy(SeiData.pSEIBuffer, SeiData.dwSEIDataSize, (pSeiParamBuffer + dwSEIDataOffset), SeiData.dwSEIDataSize); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); return eStatus; } } m_extraPictureStatesSize = SeiData.dwSEIDataSize; } m_deblockingEnabled = 0; for (uint32_t i = 0; i < m_numSlices; i++) { if (m_avcSliceParams[i].disable_deblocking_filter_idc != 1) { m_deblockingEnabled = 1; break; } } if (m_newSeq) { CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs()); } CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs()); CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceStructs()); // MB control data bMbSpecificDataEnabled = false; // Reset this flag at start of each frame encode. if (params.pMbCtrlBuffer) { bMbSpecificDataEnabled = true; MOS_LOCK_PARAMS lockFlagsWriteOnly; MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(lockFlagsWriteOnly)); lockFlagsWriteOnly.WriteOnly = true; PCODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS mbSpecificData = nullptr; CODECHAL_ENCODE_CHK_NULL_RETURN(mbSpecificData = \ (PCODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS)m_osInterface->pfnLockResource( m_osInterface, &resMbSpecificDataBuffer[m_currRecycledBufIdx], &lockFlagsWriteOnly)); uint32_t frameFieldMbNum = m_picWidthInMb * m_frameFieldHeightInMb; for (unsigned idx = 0; idx < frameFieldMbNum; ++idx) { mbSpecificData[idx].DW0.ForceToIntra = params.pMbCtrlBuffer[idx].MBParams.bForceIntra; } m_osInterface->pfnUnlockResource(m_osInterface, &resMbSpecificDataBuffer[m_currRecycledBufIdx]); } // Scaling occurs when either HME or BRC is enabled, and for Interlaced only called on first field m_scalingEnabled = (m_hmeSupported || bBrcEnabled) && m_firstField; m_useRawForRef = m_userFlags.bUseRawPicForRef; //Allocate and Generate the slice map surface if (m_arbitraryNumMbsInSlice) { /********** Allocate slice map surface **********/ if (Mos_ResourceIsNull(&m_sliceMapSurface[m_currRecycledBufIdx].OsResource)) // Allocate only if not allocated before { for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { MOS_ZeroMemory(&m_sliceMapSurface[i], sizeof(MOS_SURFACE)); m_sliceMapSurface[i].TileType = MOS_TILE_LINEAR; m_sliceMapSurface[i].bArraySpacing = true; m_sliceMapSurface[i].Format = Format_Buffer_2D; m_sliceMapSurface[i].dwWidth = (m_picWidthInMb + 1) * sizeof(uint32_t); m_sliceMapSurface[i].dwHeight = 2 * m_frameFieldHeightInMb; m_sliceMapSurface[i].dwPitch = MOS_ALIGN_CEIL(m_sliceMapSurface[i].dwWidth, 64); MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D; MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBuffer2D.Type = MOS_GFXRES_2D; allocParamsForBuffer2D.TileType = (MOS_TILE_TYPE)m_sliceMapSurface[i].TileType; allocParamsForBuffer2D.Format = m_sliceMapSurface[i].Format; allocParamsForBuffer2D.dwWidth = m_sliceMapSurface[i].dwPitch; allocParamsForBuffer2D.dwHeight = m_sliceMapSurface[i].dwHeight; allocParamsForBuffer2D.pBufName = "Slice Map Surface"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBuffer2D, &m_sliceMapSurface[i].OsResource); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate slice map Surface."); return eStatus; } } } else // If sSliceMapSurface was already allocated, reassign width and height, in case there was a dynamic resolution change. Pitch doesn't need to be udpated. { m_sliceMapSurface[m_currRecycledBufIdx].dwWidth = (m_picWidthInMb + 1) * sizeof(uint32_t); m_sliceMapSurface[m_currRecycledBufIdx].dwHeight = 2 * m_frameFieldHeightInMb; } /********** Generate slice map surface **********/ uint8_t* data = nullptr; MOS_LOCK_PARAMS lockFlagsWriteOnly; MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(lockFlagsWriteOnly)); lockFlagsWriteOnly.WriteOnly = true; // lock the internal lockable buffer. CODECHAL_ENCODE_CHK_NULL_RETURN(data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &m_sliceMapSurface[m_currRecycledBufIdx].OsResource, &lockFlagsWriteOnly)); CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeGenerateSliceMap(data, m_avcSliceParams)); // Unlock the internal lockable buffer m_osInterface->pfnUnlockResource(m_osInterface, &m_sliceMapSurface[m_currRecycledBufIdx].OsResource); } CODECHAL_DEBUG_TOOL( m_debugInterface->m_currPic = m_avcPicParam->CurrOriginalPic; m_debugInterface->m_bufferDumpFrameNum = m_storeData; m_debugInterface->m_frameType = m_pictureCodingType; if (m_newSeq) { CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams( m_avcSeqParam, m_avcIQMatrixParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateConstParam()); } if (m_newVuiData) { CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpVuiParams( m_avcVuiParams)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams( m_avcPicParam, m_avcIQMatrixParams)); if (m_feiEnable) { CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpFeiPicParams( m_avcFeiPicParams)); } for (uint32_t i = 0; i < m_numSlices; i++) { CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSliceParams( &m_avcSliceParams[i], m_avcPicParam)); CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateDdiParam( m_avcSeqParam, m_avcPicParam, &m_avcSliceParams[i])); }) ulRefPicSelectBottomFieldOffset = 0; BrcBuffers.dwMeBrcDistortionBottomFieldOffset = 0; BrcBuffers.dwBrcMbQpBottomFieldOffset = 0; if (CodecHal_PictureIsField(m_currOriginalPic)) { if (CodecHal_PictureIsBottomField(m_currOriginalPic)) { if (bVMEKernelDump) { ulVMEKernelDumpBottomFieldOffset = m_frameFieldHeightInMb * m_picWidthInMb * 64; } ulRefPicSelectBottomFieldOffset = MOS_ALIGN_CEIL((m_picWidthInMb * 8), 64) * m_frameFieldHeightInMb; BrcBuffers.dwMeBrcDistortionBottomFieldOffset = BrcBuffers.sMeBrcDistortionBuffer.dwPitch * MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4), 8); BrcBuffers.dwBrcMbQpBottomFieldOffset = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 4), 64) * MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4), 8); } } // Set min/max QP values in AVC State based on frame type if atleast one of them is non-zero if (m_avcPicParam->ucMinimumQP || m_avcPicParam->ucMaximumQP) { bMinMaxQPControlEnabled = true; if (m_avcPicParam->CodingType == I_TYPE) { ucIMaxQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51); // Clamp to the max QP to [1, 51] . Zero is not used by our Kernel. ucIMinQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), ucIMaxQP); // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP if (!bPFrameMinMaxQPControl) { ucPMinQP = ucIMinQP; ucPMaxQP = ucIMaxQP; } if (!bBFrameMinMaxQPControl) { ucBMinQP = ucIMinQP; ucBMaxQP = ucIMaxQP; } } else if (m_avcPicParam->CodingType == P_TYPE) { bPFrameMinMaxQPControl = true; ucPMaxQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51); // Clamp to the max QP to [1, 51]. Zero is not used by our Kernel. ucPMinQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), ucPMaxQP); // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP if (!bBFrameMinMaxQPControl) { ucBMinQP = ucPMinQP; ucBMaxQP = ucPMaxQP; } } else // B_TYPE { bBFrameMinMaxQPControl = true; ucBMaxQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51); // Clamp to the max QP to [1, 51] . Zero is not used by our Kernel. ucBMinQP = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), ucBMaxQP); // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP } // Zero out the QP values, so we don't update the AVCState settings until new values are sent in MiscParamsRC m_avcPicParam->ucMinimumQP = 0; m_avcPicParam->ucMaximumQP = 0; } if (!(m_codecFunction == CODECHAL_FUNCTION_ENC || m_codecFunction == CODECHAL_FUNCTION_FEI_ENC) && !m_userFlags.bDisableAcceleratorHeaderPacking && bAcceleratorHeaderPackingCaps) { CODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS packPicHeaderParams; packPicHeaderParams.pBsBuffer = &m_bsBuffer; packPicHeaderParams.pPicParams = m_avcPicParam; packPicHeaderParams.pSeqParams = m_avcSeqParam; packPicHeaderParams.pAvcVuiParams = m_avcVuiParams; packPicHeaderParams.pAvcIQMatrixParams = m_avcIQMatrixParams; packPicHeaderParams.ppNALUnitParams = m_nalUnitParams; packPicHeaderParams.pSeiData = &SeiData; packPicHeaderParams.dwFrameHeight = m_frameHeight; packPicHeaderParams.dwOriFrameHeight = m_oriFrameHeight; packPicHeaderParams.wPictureCodingType = m_avcPicParam->CodingType; packPicHeaderParams.bNewSeq = m_newSeq; packPicHeaderParams.pbNewPPSHeader = &m_newPpsHeader; packPicHeaderParams.pbNewSeqHeader = &m_newSeqHeader; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_PackPictureHeader(&packPicHeaderParams)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(SetStatusReportParams(m_refList[m_currReconstructedPic.FrameIdx])); m_bitstreamUpperBound = m_encodeParams.dwBitstreamSize; uint8_t sliceQP = m_avcPicParam->pic_init_qp_minus26 + 26 + m_avcSliceParams->slice_qp_delta; CODECHAL_ENCODE_CHK_STATUS_RETURN(GetSkipBiasAdjustment(sliceQP, m_avcSeqParam->GopRefDist, &m_skipBiasAdjustmentEnable)); // Determine if Trellis Quantization should be enabled MOS_ZeroMemory(&m_trellisQuantParams, sizeof(m_trellisQuantParams)); // Trellis must remain switched off if it is explicitly disabled or picture is encoded with CAVLC if (!(dwTrellis & trellisDisabled) && m_avcPicParam->entropy_coding_mode_flag) { if (dwTrellis == trellisInternal) { CODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS tqInputParams; tqInputParams.ucQP = sliceQP; tqInputParams.ucTargetUsage = m_avcSeqParam->TargetUsage; tqInputParams.wPictureCodingType = m_pictureCodingType; tqInputParams.bBrcEnabled = bBrcEnabled; tqInputParams.bVdEncEnabled = false; CODECHAL_ENCODE_CHK_STATUS_RETURN(GetTrellisQuantization( &tqInputParams, &m_trellisQuantParams)); } else if ((m_pictureCodingType == I_TYPE && (dwTrellis & trellisEnabledI)) || (m_pictureCodingType == P_TYPE && (dwTrellis & trellisEnabledP)) || (m_pictureCodingType == B_TYPE && (dwTrellis & trellisEnabledB))) { m_trellisQuantParams.dwTqEnabled = true; m_trellisQuantParams.dwTqRounding = CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_ROUNDING; } } InitMfe(); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::ExecuteKernelFunctions() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto slcParams = m_avcSliceParams; auto sliceType = Slice_Type[slcParams->slice_type]; CODECHAL_DEBUG_TOOL( //CodecHal_DbgMapSurfaceFormatToDumpFormat(m_rawSurfaceToEnc->Format, &u32DumpType); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( m_rawSurfaceToEnc, CodechalDbgAttr::attrEncodeRawInputSurface, "SrcSurf")); ) CODECHAL_ENCODE_CHK_NULL_RETURN(m_cscDsState); // Scaling, BRC Init/Reset and HME are included in the same task phase m_lastEncPhase = false; m_firstTaskInPhase = true; // BRC init/reset needs to be called before HME since it will reset the Brc Distortion surface if (bBrcEnabled && (bBrcInit || bBrcReset)) { bool cscEnabled = m_cscDsState->RequireCsc() && m_firstField; m_lastTaskInPhase = !(cscEnabled || m_scalingEnabled || m_16xMeSupported || m_hmeEnabled); CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcInitResetKernel()); } UpdateSSDSliceCount(); if (m_firstField) { // Csc, Downscaling, and/or 10-bit to 8-bit conversion CodechalEncodeCscDs::KernelParams cscScalingKernelParams; MOS_ZeroMemory(&cscScalingKernelParams, sizeof(cscScalingKernelParams)); cscScalingKernelParams.bLastTaskInPhaseCSC = cscScalingKernelParams.bLastTaskInPhase4xDS = !(m_16xMeSupported || m_hmeEnabled); cscScalingKernelParams.bLastTaskInPhase16xDS = !(m_32xMeSupported || m_hmeEnabled); cscScalingKernelParams.bLastTaskInPhase32xDS = !m_hmeEnabled; cscScalingKernelParams.inputColorSpace = m_avcSeqParam->InputColorSpace; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->KernelFunctions(&cscScalingKernelParams)); } // SFD should be called only when HME enabled auto staticFrameDetectionInUse = bStaticFrameDetectionEnable && m_hmeEnabled; staticFrameDetectionInUse = !bPerMbSFD && staticFrameDetectionInUse; if (m_hmeEnabled) { if (m_16xMeEnabled) { m_lastTaskInPhase = false; if (m_32xMeEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodeMeKernel(&BrcBuffers, HME_LEVEL_32x)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodeMeKernel(&BrcBuffers, HME_LEVEL_16x)); } m_lastTaskInPhase = !staticFrameDetectionInUse; CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodeMeKernel(&BrcBuffers, HME_LEVEL_4x)); } // call SFD kernel after HME in same command buffer if (staticFrameDetectionInUse) { m_lastTaskInPhase = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(SFDKernel()); } // Scaling and HME are not dependent on the output from PAK if (m_waitForPak && m_semaphoreObjCount && !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse)) { // Wait on PAK auto syncParams = g_cInitSyncParams; syncParams.GpuContext = m_renderContext; syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; syncParams.uiSemaphoreCount = m_semaphoreObjCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); m_semaphoreObjCount = 0; //reset } // Dump BrcDist 4X_ME buffer here because it will be overwritten in BrcFrameUpdateKernel CODECHAL_DEBUG_TOOL( if (m_hmeEnabled && bBrcDistortionBufferSupported) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.sMeBrcDistortionBuffer.OsResource, CodechalDbgAttr::attrOutput, "BrcDist", BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight, BrcBuffers.dwMeBrcDistortionBottomFieldOffset, CODECHAL_MEDIA_STATE_4X_ME)); }) // BRC and MbEnc are included in the same task phase m_lastEncPhase = true; m_firstTaskInPhase = true; if (bBrcEnabled) { if (bMbEncIFrameDistEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(MbEncKernel(true)); } // Separate the MBEnc kernel and BrcUpdate Kernel if (IsMfeMbEncEnabled(false)) { m_lastTaskInPhase = true; } CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcFrameUpdateKernel()); if (bBrcSplitEnable && bMbBrcEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcMbUpdateKernel()); } // Reset buffer ID used for BRC kernel performance reports m_osInterface->pfnResetPerfBufferID(m_osInterface); } bUseWeightedSurfaceForL0 = false; bUseWeightedSurfaceForL1 = false; if (bWeightedPredictionSupported && ((((sliceType == SLICE_P) || (sliceType == SLICE_SP)) && (m_avcPicParam->weighted_pred_flag)) || (((sliceType == SLICE_B)) && (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE))) ) { uint8_t i; // Weighted Prediction to be applied for L0 for (i=0; i<(slcParams->num_ref_idx_l0_active_minus1+1); i++) { if((slcParams->luma_weight_flag[LIST_0] & (1 << i)) && (i < CODEC_AVC_MAX_FORWARD_WP_FRAME)) { //Weighted Prediction for ith forward reference frame CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(false, i)); } } if (((sliceType == SLICE_B)) && (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE)) { for (i=0; i<(slcParams->num_ref_idx_l1_active_minus1+1); i++) { // Weighted Pred to be applied for L1 if((slcParams->luma_weight_flag[LIST_1] & 1 << i) && (i < CODEC_AVC_MAX_BACKWARD_WP_FRAME)) { //Weighted Prediction for ith backward reference frame CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(true, i)); } } } } #if (_DEBUG || _RELEASE_INTERNAL) MOS_USER_FEATURE_VALUE_WRITE_DATA userFeatureWriteData; // Weighted prediction for L0 Reporting userFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__; userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL0; userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L0_IN_USE_ID; MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext); // Weighted prediction for L1 Reporting userFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__; userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL1; userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L1_IN_USE_ID; MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext); #endif // _DEBUG || _RELEASE_INTERNAL m_lastTaskInPhase = true; if (IsMfeMbEncEnabled(false)) { // Submit MBEnc kernel in the last stream if (m_mfeLastStream) { m_lastEncPhase = true; m_firstTaskInPhase = true; m_lastTaskInPhase = true; } else { m_firstTaskInPhase = false; m_lastTaskInPhase = false; } } CODECHAL_ENCODE_CHK_STATUS_RETURN(MbEncKernel(false)); // Reset buffer ID used for MbEnc kernel performance reports m_osInterface->pfnResetPerfBufferID(m_osInterface); if (!Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse)) { auto syncParams = g_cInitSyncParams; syncParams.GpuContext = m_renderContext; syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); } if (m_madEnabled) { m_currMadBufferIdx = (m_currMadBufferIdx + 1) % CODECHAL_ENCODE_MAX_NUM_MAD_BUFFERS; } // Reset after BRC Init has been processed bBrcInit = false; m_setRequestedEUSlices = false; CODECHAL_DEBUG_TOOL(DumpEncodeKernelOutput()); if (bBrcEnabled) { bMbEncCurbeSetInBrcUpdate = false; } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::DumpEncodeKernelOutput() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto staticFrameDetectionInUse = bStaticFrameDetectionEnable && m_hmeEnabled; staticFrameDetectionInUse = !bPerMbSFD && staticFrameDetectionInUse; CODECHAL_DEBUG_TOOL( if (m_hmeEnabled) { CODECHAL_ME_OUTPUT_PARAMS meOutputParams; MOS_ZeroMemory(&meOutputParams, sizeof(meOutputParams)); meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer; meOutputParams.psMeDistortionBuffer = m_4xMeDistortionBufferSupported ? (m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer) : nullptr; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &meOutputParams.psMeMvBuffer->OsResource, CodechalDbgAttr::attrOutput, "MvData", meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch, m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset() : (uint32_t)m_meMvBottomFieldOffset, CODECHAL_MEDIA_STATE_4X_ME)); if (meOutputParams.psMeDistortionBuffer) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &meOutputParams.psMeDistortionBuffer->OsResource, CodechalDbgAttr::attrOutput, "MeDist", meOutputParams.psMeDistortionBuffer->dwHeight *meOutputParams.psMeDistortionBuffer->dwPitch, m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset, CODECHAL_MEDIA_STATE_4X_ME)); } if (m_16xMeEnabled) { meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me16xMvDataBuffer) : &m_16xMeMvDataBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN( m_debugInterface->DumpBuffer( &meOutputParams.psMeMvBuffer->OsResource, CodechalDbgAttr::attrOutput, "MvData", meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch, m_hmeKernel ? m_hmeKernel->Get16xMeMvBottomFieldOffset() : (uint32_t)m_meMv16xBottomFieldOffset, CODECHAL_MEDIA_STATE_16X_ME)); if (m_32xMeEnabled) { meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me32xMvDataBuffer) : &m_32xMeMvDataBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN( m_debugInterface->DumpBuffer( &meOutputParams.psMeMvBuffer->OsResource, CodechalDbgAttr::attrOutput, "MvData", meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch, m_hmeKernel ? m_hmeKernel->Get32xMeMvBottomFieldOffset() : (uint32_t)m_meMv32xBottomFieldOffset, CODECHAL_MEDIA_STATE_32X_ME)); } } } if (staticFrameDetectionInUse) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &resSFDOutputBuffer[0], CodechalDbgAttr::attrOutput, "Out", CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE_COMMON, 0, CODECHAL_MEDIA_STATE_STATIC_FRAME_DETECTION)); } if (bBrcEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcImageStatesWriteBuffer, CodechalDbgAttr::attrOutput, "ImgStateWrite", BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(), 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); if (!Mos_ResourceIsNull(&BrcBuffers.sBrcMbQpBuffer.OsResource)) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.sBrcMbQpBuffer.OsResource, CodechalDbgAttr::attrOutput, "MbQp", BrcBuffers.sBrcMbQpBuffer.dwPitch*BrcBuffers.sBrcMbQpBuffer.dwHeight, BrcBuffers.dwBrcMbQpBottomFieldOffset, CODECHAL_MEDIA_STATE_MB_BRC_UPDATE)); } if (bMbBrcEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resBrcHistoryBuffer, CodechalDbgAttr::attrOutput, "HistoryWrite", m_brcHistoryBufferSize, 0, CODECHAL_MEDIA_STATE_MB_BRC_UPDATE)); } if (BrcBuffers.pMbEncKernelStateInUse) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( CODECHAL_MEDIA_STATE_BRC_UPDATE, BrcBuffers.pMbEncKernelStateInUse)); } if (m_mbencBrcBufferSize > 0) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &BrcBuffers.resMbEncBrcBuffer, CodechalDbgAttr::attrOutput, "MbEncBRCWrite", m_mbencBrcBufferSize, 0, CODECHAL_MEDIA_STATE_BRC_UPDATE)); } } if (m_mbStatsSupported) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_resMbStatsBuffer, CodechalDbgAttr::attrOutput, "MBStatsSurf", m_picWidthInMb * m_frameFieldHeightInMb * 16 * sizeof(uint32_t), CodecHal_PictureIsBottomField(m_currOriginalPic) ? m_mbStatsBottomFieldOffset : 0, CODECHAL_MEDIA_STATE_4X_SCALING)); } else if (m_flatnessCheckEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_flatnessCheckSurface.OsResource, CodechalDbgAttr::attrOutput, "FlatnessChkSurf", ((CodecHal_PictureIsField(m_currOriginalPic)) ? m_flatnessCheckSurface.dwHeight/2 : m_flatnessCheckSurface.dwHeight) * m_flatnessCheckSurface.dwPitch, CodecHal_PictureIsBottomField(m_currOriginalPic)?(m_flatnessCheckSurface.dwPitch * m_flatnessCheckSurface.dwHeight >> 1):0, CODECHAL_MEDIA_STATE_4X_SCALING)); } if (bMbQpDataEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &resMbSpecificDataBuffer[m_currRecycledBufIdx], CodechalDbgAttr::attrInput, "MbSpecificData", m_picWidthInMb*m_frameFieldHeightInMb*16, 0, CODECHAL_MEDIA_STATE_ENC_QUALITY)); } uint8_t index; CODEC_PICTURE refPic; if (bUseWeightedSurfaceForL0) { refPic = m_avcSliceParams->RefPicList[LIST_0][0]; index = m_picIdx[refPic.FrameIdx].ucPicIdx; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( &m_refList[index]->sRefBuffer, CodechalDbgAttr::attrReferenceSurfaces, "WP_In_L0")); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( &WeightedPredOutputPicSelectList[CODEC_WP_OUTPUT_L0_START + 0].sBuffer, CodechalDbgAttr::attrReferenceSurfaces, "WP_Out_L0")); } if (bUseWeightedSurfaceForL1) { refPic = m_avcSliceParams->RefPicList[LIST_1][0]; index = m_picIdx[refPic.FrameIdx].ucPicIdx; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( &m_refList[index]->sRefBuffer, CodechalDbgAttr::attrReferenceSurfaces, "WP_In_L1")); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( &WeightedPredOutputPicSelectList[CODEC_WP_OUTPUT_L1_START + 0].sBuffer, CodechalDbgAttr::attrReferenceSurfaces, "WP_In_L1")); } if (m_feiEnable) { if(m_avcFeiPicParams->bMBQp){ CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_avcFeiPicParams->resMBQp, CodechalDbgAttr::attrInput, "MbQp", m_picWidthInMb * m_frameFieldHeightInMb + 3, 0, CODECHAL_MEDIA_STATE_ENC_QUALITY)); } if (m_avcFeiPicParams->MVPredictorEnable){ CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_avcFeiPicParams->resMVPredictor, CodechalDbgAttr::attrInput, "MvPredictor", m_picWidthInMb * m_frameFieldHeightInMb *40, 0, CODECHAL_MEDIA_STATE_ENC_QUALITY)); } } if (m_arbitraryNumMbsInSlice) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_sliceMapSurface[m_currRecycledBufIdx].OsResource, CodechalDbgAttr::attrInput, "SliceMapSurf", m_sliceMapSurface[m_currRecycledBufIdx].dwPitch * m_frameFieldHeightInMb, 0, CODECHAL_MEDIA_STATE_ENC_QUALITY)); } auto refList = &m_refList[0]; auto currRefList = m_refList[m_currReconstructedPic.FrameIdx]; // Dump MBEnc output buffer "MbCodebuffer" CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &currRefList->resRefMbCodeBuffer, CodechalDbgAttr::attrOutput, "EncMbCode", m_picWidthInMb * m_frameFieldHeightInMb * 64, CodecHal_PictureIsBottomField(currRefList->RefPic) ? m_frameFieldHeightInMb * m_picWidthInMb * 64 : 0, CODECHAL_MEDIA_STATE_ENC_NORMAL)); // Dump MBEnc output buffer "MVdatabuffer" if (m_mvDataSize) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &currRefList->resRefMvDataBuffer, CodechalDbgAttr::attrOutput, "MbData", m_picWidthInMb * m_frameFieldHeightInMb * (32 * 4), CodecHal_PictureIsBottomField(currRefList->RefPic) ? MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), 0x1000) : 0, CODECHAL_MEDIA_STATE_ENC_NORMAL)); } ) return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::ExecutePictureLevel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcPicParam); CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcSliceParams); MHW_BATCH_BUFFER batchBuffer; MOS_ZeroMemory(&batchBuffer, sizeof(batchBuffer)); batchBuffer.OsResource = BrcBuffers.resBrcImageStatesWriteBuffer; batchBuffer.dwOffset = m_currPass * BRC_IMG_STATE_SIZE_PER_PASS; batchBuffer.bSecondLevel = true; CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS encodePictureLevelParams; MOS_ZeroMemory(&encodePictureLevelParams, sizeof(encodePictureLevelParams)); encodePictureLevelParams.psPreDeblockSurface = &m_reconSurface; encodePictureLevelParams.psPostDeblockSurface = &m_reconSurface; encodePictureLevelParams.bBrcEnabled = bBrcEnabled; encodePictureLevelParams.pImgStateBatchBuffer = &batchBuffer; encodePictureLevelParams.presBrcHistoryBuffer = &BrcBuffers.resBrcHistoryBuffer; bool deblockingEnabled = m_deblockingEnabled; bool suppressReconPic = ((!m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) && m_suppressReconPicSupported); encodePictureLevelParams.bDeblockerStreamOutEnable = 0; encodePictureLevelParams.bPreDeblockOutEnable = !deblockingEnabled && !suppressReconPic; encodePictureLevelParams.bPostDeblockOutEnable = deblockingEnabled && !suppressReconPic; CODECHAL_ENCODE_CHK_STATUS_RETURN(GenericEncodePictureLevel(&encodePictureLevelParams)); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::ExecuteSliceLevel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface->osCpInterface); auto cpInterface = m_hwInterface->GetCpInterface(); auto avcSlcParams = m_avcSliceParams; auto avcPicParams = m_avcPicParams[avcSlcParams->pic_parameter_set_id]; auto avcSeqParams = m_avcSeqParams[avcPicParams->seq_parameter_set_id]; auto slcData = m_slcData; // For use with the single task phase implementation if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE) { uint32_t numSlc = (m_frameFieldHeightInMb + m_sliceHeight - 1) / m_sliceHeight; if (numSlc != m_numSlices) { return MOS_STATUS_INVALID_PARAMETER; } } bool useBatchBufferForPakSlices = false; if (m_singleTaskPhaseSupported && m_singleTaskPhaseSupportedInPak) { if (m_currPass == 0) { // The same buffer is used for all slices for all passes. uint32_t batchBufferForPakSlicesSize = (m_numPasses + 1) * m_numSlices * m_pakSliceSize; if (batchBufferForPakSlicesSize > (uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iSize) { if (m_batchBufferForPakSlices[m_currRecycledBufIdx].iSize) { CODECHAL_ENCODE_CHK_STATUS_RETURN(ReleaseBatchBufferForPakSlices(m_currRecycledBufIdx)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBatchBufferForPakSlices( m_numSlices, m_numPasses, m_currRecycledBufIdx)); } } CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_LockBb( m_osInterface, &m_batchBufferForPakSlices[m_currRecycledBufIdx])); useBatchBufferForPakSlices = true; } MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); if (m_osInterface->osCpInterface->IsCpEnabled()) { MHW_CP_SLICE_INFO_PARAMS sliceInfoParam; sliceInfoParam.bLastPass = (m_currPass == m_numPasses) ? true : false; CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->SetMfxProtectionState(false, &cmdBuffer, nullptr, &sliceInfoParam)); CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->UpdateParams(false)); } avcSlcParams = m_avcSliceParams; CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS packSlcHeaderParams; packSlcHeaderParams.pBsBuffer = &m_bsBuffer; packSlcHeaderParams.pPicParams = avcPicParams; packSlcHeaderParams.pSeqParams = m_avcSeqParam; packSlcHeaderParams.ppRefList = &(m_refList[0]); packSlcHeaderParams.CurrPic = m_currOriginalPic; packSlcHeaderParams.CurrReconPic = m_currReconstructedPic; packSlcHeaderParams.UserFlags = m_userFlags; packSlcHeaderParams.NalUnitType = m_nalUnitType; packSlcHeaderParams.wPictureCodingType = m_pictureCodingType; packSlcHeaderParams.bVdencEnabled = false; MHW_VDBOX_AVC_SLICE_STATE sliceState; MOS_ZeroMemory(&sliceState, sizeof(sliceState)); sliceState.presDataBuffer = &m_resMbCodeSurface; sliceState.pAvcPicIdx = &(m_picIdx[0]); sliceState.pEncodeAvcSeqParams = m_avcSeqParam; sliceState.pEncodeAvcPicParams = avcPicParams; sliceState.pBsBuffer = &m_bsBuffer; sliceState.ppNalUnitParams = m_nalUnitParams; sliceState.bBrcEnabled = bBrcEnabled; // Disable Panic mode when min/max QP control is on. kernel may disable it, but disable in driver also. if (avcSeqParams->bForcePanicModeControl == 1) { sliceState.bRCPanicEnable = (!avcSeqParams->bPanicModeDisable) && (!bMinMaxQPControlEnabled); } else { sliceState.bRCPanicEnable = m_panicEnable && (!bMinMaxQPControlEnabled); } sliceState.bAcceleratorHeaderPackingCaps = m_encodeParams.bAcceleratorHeaderPackingCaps; sliceState.wFrameFieldHeightInMB = m_frameFieldHeightInMb; MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams; for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++) { if (m_currPass == 0) { packSlcHeaderParams.pAvcSliceParams = &avcSlcParams[slcCount]; if (bAcceleratorHeaderPackingCaps) { slcData[slcCount].SliceOffset = m_bsBuffer.SliceOffset; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_PackSliceHeader(&packSlcHeaderParams)); slcData[slcCount].BitSize = m_bsBuffer.BitSize; } if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE) { slcData[slcCount].CmdOffset = slcCount * m_sliceHeight * m_picWidthInMb * 16 * 4; } else { slcData[slcCount].CmdOffset = packSlcHeaderParams.pAvcSliceParams->first_mb_in_slice * 16 * 4; } } sliceState.pEncodeAvcSliceParams = &avcSlcParams[slcCount]; sliceState.dwDataBufferOffset = m_slcData[slcCount].CmdOffset + m_mbcodeBottomFieldOffset; sliceState.dwOffset = slcData[slcCount].SliceOffset; sliceState.dwLength = slcData[slcCount].BitSize; sliceState.uiSkipEmulationCheckCount = slcData[slcCount].SkipEmulationByteCount; sliceState.dwSliceIndex = (uint32_t)slcCount; sliceState.bFirstPass = (m_currPass == 0); sliceState.bLastPass = (m_currPass == m_numPasses); sliceState.bInsertBeforeSliceHeaders = (slcCount == 0); sliceState.bVdencInUse = false; // App handles tail insertion for VDEnc dynamic slice in non-cp case sliceState.bVdencNoTailInsertion = false; uint32_t batchBufferForPakSlicesStartOffset = (uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iCurrent; if (useBatchBufferForPakSlices) { sliceState.pBatchBufferForPakSlices = &m_batchBufferForPakSlices[m_currRecycledBufIdx]; sliceState.bSingleTaskPhaseSupported = true; sliceState.dwBatchBufferForPakSlicesStartOffset = batchBufferForPakSlicesStartOffset; } if (m_avcRoundingParams != nullptr && m_avcRoundingParams->bEnableCustomRoudingIntra) { sliceState.dwRoundingIntraValue = m_avcRoundingParams->dwRoundingIntra; } else { sliceState.dwRoundingIntraValue = 5; } if (m_avcRoundingParams != nullptr && m_avcRoundingParams->bEnableCustomRoudingInter) { sliceState.bRoundingInterEnable = true; sliceState.dwRoundingValue = m_avcRoundingParams->dwRoundingInter; } else { sliceState.bRoundingInterEnable = bRoundingInterEnable; CODECHAL_ENCODE_CHK_STATUS_RETURN(GetInterRounding(&sliceState)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSlice(&cmdBuffer, &sliceState)); // Add dumps for 2nd level batch buffer if (sliceState.bSingleTaskPhaseSupported) { CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState.pBatchBufferForPakSlices); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch( sliceState.pBatchBufferForPakSlices, CODECHAL_MEDIA_STATE_ENC_NORMAL, nullptr)); ) } } if (useBatchBufferForPakSlices) { CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_UnlockBb( m_osInterface, &m_batchBufferForPakSlices[m_currRecycledBufIdx], m_lastTaskInPhase)); } // Insert end of sequence/stream if set if (m_lastPicInStream || m_lastPicInSeq) { MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams; MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams)); pakInsertObjectParams.bLastPicInSeq = m_lastPicInSeq; pakInsertObjectParams.bLastPicInStream = m_lastPicInStream; pakInsertObjectParams.dwBitSize = 32; // use dwBitSize for SrcDataEndingBitInclusion if (m_lastPicInSeq) { pakInsertObjectParams.dwLastPicInSeqData = (uint32_t)((1 << 16) | CODECHAL_ENCODE_AVC_NAL_UT_EOSEQ << 24); } if (m_lastPicInStream) { pakInsertObjectParams.dwLastPicInStreamData = (uint32_t)((1 << 16) | CODECHAL_ENCODE_AVC_NAL_UT_EOSTREAM << 24); } pakInsertObjectParams.bHeaderLengthExcludeFrmSize = true; if (pakInsertObjectParams.bEmulationByteBitsInsert) { //Does not matter here, but keeping for consistency CODECHAL_ENCODE_ASSERTMESSAGE("The emulation prevention bytes are not inserted by the app and are requested to be inserted by HW."); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr, &pakInsertObjectParams)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(&cmdBuffer)); // BRC PAK statistics different for each pass if (bBrcEnabled) { uint32_t offset = (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) + m_encodeStatusBuf.dwNumPassesOffset + // Num passes offset sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource EncodeReadBrcPakStatsParams readBrcPakStatsParams; readBrcPakStatsParams.pHwInterface = m_hwInterface; readBrcPakStatsParams.presBrcPakStatisticBuffer = &BrcBuffers.resBrcPakStatisticBuffer[0]; readBrcPakStatsParams.presStatusBuffer = &m_encodeStatusBuf.resStatusBuffer; readBrcPakStatsParams.dwStatusBufNumPassesOffset = offset; readBrcPakStatsParams.ucPass = m_currPass; readBrcPakStatsParams.VideoContext = m_videoContext; CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadBrcPakStatistics(&cmdBuffer, &readBrcPakStatsParams)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } std::string pakPassName = "PAK_PASS" + std::to_string(static_cast(m_currPass)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( &cmdBuffer, CODECHAL_NUM_MEDIA_STATES, pakPassName.data())); //CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands( // m_debugInterface, // &cmdBuffer)); ) m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); // For VDEnc SHME and CSC need to wait workload finish on render engine if ((m_currPass == 0) && !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse)) { auto syncParams = g_cInitSyncParams; syncParams.GpuContext = m_videoContext; syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); } bool renderingFlags = m_videoContextUsesNullHw; if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(SubmitCommandBuffer(&cmdBuffer, renderingFlags)); CODECHAL_DEBUG_TOOL( if (!m_mmcUserFeatureUpdated) { CODECHAL_UPDATE_ENCODE_MMC_USER_FEATURE(m_reconSurface, m_osInterface->pOsContext); m_mmcUserFeatureUpdated = true; }) if (m_sliceSizeStreamoutSupported) { CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_pakSliceSizeStreamoutBuffer, CodechalDbgAttr::attrOutput, "SliceSizeStreamout", CODECHAL_ENCODE_SLICESIZE_BUF_SIZE, 0, CODECHAL_NUM_MEDIA_STATES))); } if ((m_currPass == m_numPasses) && m_signalEnc && !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse)) { // Check if the signal obj count exceeds max value if (m_semaphoreObjCount == MOS_MIN(m_semaphoreMaxCount, MOS_MAX_OBJECT_SIGNALED)) { auto syncParams = g_cInitSyncParams; syncParams.GpuContext = m_renderContext; syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); m_semaphoreObjCount--; } // signal semaphore auto syncParams = g_cInitSyncParams; syncParams.GpuContext = m_videoContext; syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); m_semaphoreObjCount++; } } // Reset parameters for next PAK execution if (m_currPass == m_numPasses) { if (!m_singleTaskPhaseSupported) { m_osInterface->pfnResetPerfBufferID(m_osInterface); } m_newPpsHeader = 0; m_newSeqHeader = 0; } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateSliceStateParam( bAdaptiveRoundingInterEnable, &sliceState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpFrameParFile()); ) return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::UserFeatureKeyReport() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::UserFeatureKeyReport()); CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcSeqParam); // AVC Encode BRC Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_BRC_ENABLE_ID, bBrcEnabled, m_osInterface->pOsContext); // AVC HME Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_ME_IN_USE_ID, m_hmeSupported, m_osInterface->pOsContext); // AVC SuperHME Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_16xME_IN_USE_ID, m_16xMeSupported, m_osInterface->pOsContext); // AVC UltraHME Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_32xME_IN_USE_ID, m_32xMeSupported, m_osInterface->pOsContext); // AVC RateControl Method Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_RATECONTROL_METHOD_ID, m_avcSeqParam->RateControlMethod, m_osInterface->pOsContext); // AVC Adaptive Transform Decision Enable Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ADAPTIVE_TRANSFORM_DECISION_ENABLE_ID, m_adaptiveTransformDecisionEnabled, m_osInterface->pOsContext); // FBR Bypass Enable Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_FBR_BYPASS_ENABLE_ID, bFBRBypassEnable, m_osInterface->pOsContext); // Static frame detection Enable Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_STATIC_FRAME_DETECTION_ENABLE_ID, bStaticFrameDetectionEnable, m_osInterface->pOsContext); // Adaptive Search Windows Enable Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_SEARCH_WINDOW_ENABLE_ID, bApdatvieSearchWindowEnable, m_osInterface->pOsContext); // AVC FTQ Reporting #if (_DEBUG || _RELEASE_INTERNAL) CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_FTQ_IN_USE_ID, bFTQEnable, m_osInterface->pOsContext); // AVC CAF Reporting CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_CAF_IN_USE_ID, bCAFEnable, m_osInterface->pOsContext); #endif // _DEBUG || _RELEASE_INTERNAL return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::EncodeGenerateSliceMap(uint8_t* data, PCODEC_AVC_ENCODE_SLICE_PARAMS avcSliceParams) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(data); CODECHAL_ENCODE_CHK_NULL_RETURN(avcSliceParams); auto sliceMapRow = (uint32_t*)(data + m_sliceMapBottomFieldOffset); auto sliceMap = sliceMapRow; uint32_t sliceMapPitch = m_sliceMapSurface[m_currRecycledBufIdx].dwPitch / sizeof(uint32_t); uint32_t count = 0; for (uint32_t j = 0; j < m_numSlices; j++) { for (uint32_t i = 0; i < avcSliceParams->NumMbsForSlice; i++) { *sliceMap++ = j; if ((count > 0) && ((count % m_picWidthInMb == 0))) { sliceMapRow += sliceMapPitch; sliceMap = sliceMapRow; *sliceMap++ = j; } count++; } avcSliceParams++; } *sliceMap++ = 0xFFFFFFFF; // Set last uint32_t to -1. return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::AllocateResources() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CodechalEncodeAvcBase::AllocateResources(); uint32_t fieldNumMBs = m_picWidthInMb * ((m_picHeightInMb + 1) >> 1); // Field/frame info not ready here, need to round up to even Height for field mode uint32_t picWidthHeightInMB = fieldNumMBs * 2; uint32_t fieldHeightInMB = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(((m_frameHeight + 1) >> 1)); // initiate allocation parameters and lock flags MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; allocParamsForBufferLinear.Format = Format_Buffer; MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D; MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBuffer2D.Type = MOS_GFXRES_2D; allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR; allocParamsForBuffer2D.Format = Format_Buffer_2D; MOS_LOCK_PARAMS lockFlagsWriteOnly; MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); lockFlagsWriteOnly.WriteOnly = 1; if (m_pakEnabled) { // Allocate skip frame copy buffer allocParamsForBufferLinear.dwBytes = dwSkipFrameBufferSize = CODECHAL_PAGE_SIZE; allocParamsForBufferLinear.pBufName = "Skip Frame Copy Buffer"; CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &resSkipFrameBuffer), "Failed to allocate Skip Frame Copy Buffer\n"); } // Allocate SEI buffer SeiData.pSEIBuffer = (uint8_t *)MOS_AllocAndZeroMemory(CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE); if (SeiData.pSEIBuffer == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate SEI Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } SeiData.dwSEIBufSize = CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE; // Resources required by legacy AVC ENC if (m_encEnabled) { CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesBrc()); bVMEScratchBuffer = (MbEncBindingTable.dwAvcMBEncDebugScratch != CODECHAL_INVALID_BINDING_TABLE_IDX); if (bVMEScratchBuffer) { // VME Scratch buffer (HSW), 256 bytes (8 GRFs) per MB uint32_t size = m_picWidthInMb * m_picHeightInMb * 256; allocParamsForBufferLinear.dwBytes = size; allocParamsForBufferLinear.pBufName = "VME Scratch Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &resVMEScratchBuffer); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VME Scratch Buffer."); return eStatus; } uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(resVMEScratchBuffer), &lockFlagsWriteOnly); CODECHAL_ENCODE_CHK_NULL_RETURN(data); MOS_ZeroMemory(data, size); m_osInterface->pfnUnlockResource( m_osInterface, &resVMEScratchBuffer); } // allocate VME Kernel Dump buffer if (bVMEKernelDump) { allocParamsForBufferLinear.dwBytes = picWidthHeightInMB; allocParamsForBufferLinear.pBufName = "VME Kernel Dump Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &resVmeKernelDumpBuffer); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VME Kernel Dump Buffer."); return eStatus; } } if (bRefPicSelectListSupported) { auto refPicSelect = RefPicSelectList; for (uint32_t i = 0; i < CODECHAL_ENCODE_AVC_REF_PIC_SELECT_ENTRIES; i++, refPicSelect++) { MOS_ZeroMemory(&refPicSelect->sBuffer, sizeof(MOS_SURFACE)); refPicSelect->FrameIdx = CODECHAL_ENCODE_AVC_INVALID_PIC_ID; refPicSelect->sBuffer.TileType = MOS_TILE_LINEAR; refPicSelect->sBuffer.bArraySpacing = true; refPicSelect->sBuffer.Format = Format_Buffer_2D; refPicSelect->sBuffer.dwWidth = MOS_ALIGN_CEIL((m_picWidthInMb * 8), 64); refPicSelect->sBuffer.dwHeight = MOS_ALIGN_CEIL(2 * fieldHeightInMB, 8); refPicSelect->sBuffer.dwPitch = MOS_ALIGN_CEIL((m_picWidthInMb * 8), 64); allocParamsForBuffer2D.dwWidth = refPicSelect->sBuffer.dwWidth; allocParamsForBuffer2D.dwHeight = refPicSelect->sBuffer.dwHeight; allocParamsForBuffer2D.pBufName = "RefPicSelectList Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBuffer2D, &refPicSelect->sBuffer.OsResource); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate RefPicSelectList Buffer."); return eStatus; } } } } if (bStaticFrameDetectionEnable) { // SFD output buffer allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE_COMMON, CODECHAL_CACHELINE_SIZE); allocParamsForBufferLinear.pBufName = "Static frame detection output buffer"; CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &resSFDOutputBuffer[0]), "Failed to allocate static frame detection output buffer\n"); // SFD P-frame cost table buffer allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON, CODECHAL_CACHELINE_SIZE); allocParamsForBufferLinear.pBufName = "SFD P-frame cost table buffer"; CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &resSFDCostTablePFrameBuffer), "Failed to allocate SFD P-frame cost table buffer\n"); CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &resSFDCostTableBFrameBuffer), "Failed to allocate SFD B-frame cost table buffer\n"); // copy SFD P-frame cost table uint8_t* data; if (nullptr == (data = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &resSFDCostTablePFrameBuffer, &lockFlagsWriteOnly))) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock SFD P-frame cost table Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(data, CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t), m_codechalEncodeAvcSfdCostTablePFrame, CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t)), "Failed to copy SFD P-frame cost table"); m_osInterface->pfnUnlockResource(m_osInterface, &resSFDCostTablePFrameBuffer); // copy SFD B-frame cost table if (nullptr == (data = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &resSFDCostTableBFrameBuffer, &lockFlagsWriteOnly))) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock SFD B-frame cost table Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(data, CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t), m_codechalEncodeAvcSfdCostTableBFrame, CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE_COMMON * sizeof(uint8_t)), "Failed to copy SFD B-frame cost table"); m_osInterface->pfnUnlockResource(m_osInterface, &resSFDCostTableBFrameBuffer); } // allocate MB specific data buffer allocParamsForBufferLinear.dwBytes = picWidthHeightInMB * sizeof(CODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS); allocParamsForBufferLinear.pBufName = "MB Specific Data Buffer"; for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &resMbSpecificDataBuffer[i]); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate MB Specific Data Buffer."); return eStatus; } } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::AllocateResourcesBrc() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; // initiate allocation parameters and lock flags MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; allocParamsForBufferLinear.Format = Format_Buffer; MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D; MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBuffer2D.Type = MOS_GFXRES_2D; allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR; allocParamsForBuffer2D.Format = Format_Buffer_2D; MOS_LOCK_PARAMS lockFlagsWriteOnly; MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); lockFlagsWriteOnly.WriteOnly = 1; // BRC history buffer uint32_t size = m_brcHistoryBufferSize; allocParamsForBufferLinear.dwBytes = size; allocParamsForBufferLinear.pBufName = "BRC History Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &BrcBuffers.resBrcHistoryBuffer); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC History Buffer."); return eStatus; } uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.resBrcHistoryBuffer), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC History Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resBrcHistoryBuffer); // PAK Statistics buffer size = m_brcPakStatisticsSize; allocParamsForBufferLinear.dwBytes = size; allocParamsForBufferLinear.pBufName = "BRC PAK Statistics Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &BrcBuffers.resBrcPakStatisticBuffer[0]); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC PAK Statistics Buffer."); return eStatus; } pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.resBrcPakStatisticBuffer[0]), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC PAK Statistics Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resBrcPakStatisticBuffer[0]); // PAK IMG_STATEs buffer // Use BRC_MAXIMUM_NUM_PASSES here since actual number of passes is determined later using PicParams.BRCPrecision size = BRC_IMG_STATE_SIZE_PER_PASS * CODECHAL_ENCODE_BRC_MAXIMUM_NUM_PASSES; allocParamsForBufferLinear.dwBytes = size; allocParamsForBufferLinear.pBufName = "PAK IMG State Read Buffer"; for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &BrcBuffers.resBrcImageStatesReadBuffer[i]); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC IMG State Read Buffer."); return eStatus; } pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.resBrcImageStatesReadBuffer[i]), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC IMG State Read Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resBrcImageStatesReadBuffer[i]); } allocParamsForBufferLinear.pBufName = "PAK IMG State Write Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &BrcBuffers.resBrcImageStatesWriteBuffer); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC IMG State Write Buffer."); return eStatus; } pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.resBrcImageStatesWriteBuffer), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC IMG State Write Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resBrcImageStatesWriteBuffer); // Check if the constant data surface is present for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { //BRC Constant Data Surfaces MOS_ZeroMemory(&BrcBuffers.sBrcConstantDataBuffer[i], sizeof(MOS_SURFACE)); BrcBuffers.sBrcConstantDataBuffer[i].TileType = MOS_TILE_LINEAR; BrcBuffers.sBrcConstantDataBuffer[i].bArraySpacing = true; BrcBuffers.sBrcConstantDataBuffer[i].Format = Format_Buffer_2D; BrcBuffers.sBrcConstantDataBuffer[i].dwWidth = dwBrcConstantSurfaceWidth; BrcBuffers.sBrcConstantDataBuffer[i].dwHeight = dwBrcConstantSurfaceHeight; BrcBuffers.sBrcConstantDataBuffer[i].dwPitch = dwBrcConstantSurfaceWidth; allocParamsForBuffer2D.dwWidth = MOS_ALIGN_CEIL(dwBrcConstantSurfaceWidth, 64); allocParamsForBuffer2D.dwHeight = dwBrcConstantSurfaceHeight; allocParamsForBuffer2D.pBufName = "BRC Constant Data Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBuffer2D, &BrcBuffers.sBrcConstantDataBuffer[i].OsResource); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC Constant Data Buffer."); return eStatus; } } uint32_t width, height, downscaledFieldHeightInMB4x; if (bBrcDistortionBufferSupported) { // BRC Distortion Surface downscaledFieldHeightInMB4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS((m_frameHeight + 1) >> 3); width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 3), 64); height = MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x << 2), 8) << 1; allocParamsForBuffer2D.dwWidth = width; allocParamsForBuffer2D.dwHeight = height; allocParamsForBuffer2D.pBufName = "BRC Distortion Surface Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBuffer2D, &BrcBuffers.sMeBrcDistortionBuffer.OsResource); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate ME BRC Distortion Buffer."); return eStatus; } BrcBuffers.sMeBrcDistortionBuffer.TileType = MOS_TILE_LINEAR; BrcBuffers.sMeBrcDistortionBuffer.bArraySpacing = true; BrcBuffers.sMeBrcDistortionBuffer.Format = Format_Buffer_2D; BrcBuffers.sMeBrcDistortionBuffer.dwWidth = width; BrcBuffers.sMeBrcDistortionBuffer.dwHeight = height; BrcBuffers.sMeBrcDistortionBuffer.dwPitch = (uint32_t)BrcBuffers.sMeBrcDistortionBuffer.OsResource.pGmmResInfo->GetRenderPitch(); pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.sMeBrcDistortionBuffer.OsResource), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock ME BRC Distortion Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } size = BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight; MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource( m_osInterface, &BrcBuffers.sMeBrcDistortionBuffer.OsResource); } // MbBrcConstDataBuffer // 16 DWs per QP value size = 16 * (CODEC_AVC_NUM_QP) * sizeof(uint32_t); allocParamsForBufferLinear.dwBytes = size; allocParamsForBufferLinear.pBufName = "MB BRC Constant Data Buffer"; for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &BrcBuffers.resMbBrcConstDataBuffer[i]); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate MB BRC Constant Data Buffer."); return eStatus; } pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.resMbBrcConstDataBuffer[i]), &lockFlagsWriteOnly); CODECHAL_ENCODE_CHK_NULL_RETURN(pData); MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource( m_osInterface, &BrcBuffers.resMbBrcConstDataBuffer[i]); } // Use a separate surface MbEnc DSH data if(!CodecHalIsFeiEncode(m_codecFunction)) { size = m_renderEngineInterface->m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData() + MOS_ALIGN_CEIL(pMbEncKernelStates->KernelParams.iCurbeLength, m_renderEngineInterface->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment()); allocParamsForBufferLinear.dwBytes = size; allocParamsForBufferLinear.pBufName = "MbEnc Curbe Buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &BrcBuffers.resMbEncAdvancedDsh); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate MbEnc Curbe Buffer."); return eStatus; } pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &BrcBuffers.resMbEncAdvancedDsh, &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock MbEnc Curbe Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource( m_osInterface, &BrcBuffers.resMbEncAdvancedDsh); } // MbEnc BRC buffer - buffer written by BRC and used by MbEnc if (bDecoupleMbEncCurbeFromBRC) { size = m_mbencBrcBufferSize; allocParamsForBufferLinear.dwBytes = size; allocParamsForBufferLinear.pBufName = "MbEnc BRC buffer"; eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBufferLinear, &BrcBuffers.resMbEncBrcBuffer); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate MbEnc BRC buffer."); return eStatus; } pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.resMbEncBrcBuffer), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock MbEnc BRC buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.resMbEncBrcBuffer); } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::AllocateResourcesMbBrc() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; // initiate allocation paramters and lock flags MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D; MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS)); allocParamsForBuffer2D.Type = MOS_GFXRES_2D; allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR; allocParamsForBuffer2D.Format = Format_Buffer_2D; MOS_LOCK_PARAMS lockFlagsWriteOnly; MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); lockFlagsWriteOnly.WriteOnly = 1; uint32_t downscaledFieldHeightInMB4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS((m_frameHeight + 1) >> 3); // Mb QP Surface if (Mos_ResourceIsNull(&BrcBuffers.sBrcMbQpBuffer.OsResource)) { uint32_t width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 2), 64); uint32_t height = MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x << 2), 8) << 1; uint32_t size = width * height; MOS_ZeroMemory(&BrcBuffers.sBrcMbQpBuffer, sizeof(MOS_SURFACE)); BrcBuffers.sBrcMbQpBuffer.TileType = MOS_TILE_LINEAR; BrcBuffers.sBrcMbQpBuffer.bArraySpacing = true; BrcBuffers.sBrcMbQpBuffer.Format = Format_Buffer_2D; BrcBuffers.sBrcMbQpBuffer.dwWidth = allocParamsForBuffer2D.dwWidth = width; BrcBuffers.sBrcMbQpBuffer.dwHeight = allocParamsForBuffer2D.dwHeight = height; BrcBuffers.sBrcMbQpBuffer.dwPitch = width; allocParamsForBuffer2D.pBufName = "BRC MB QP Buffer"; CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBuffer2D, &BrcBuffers.sBrcMbQpBuffer.OsResource), "Failed to allocate BRC MB QP surface."); uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.sBrcMbQpBuffer.OsResource), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC MB QP Buffer."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource( m_osInterface, &BrcBuffers.sBrcMbQpBuffer.OsResource); } // BRC ROI Surface if (Mos_ResourceIsNull(&BrcBuffers.sBrcRoiSurface.OsResource) && bBrcRoiEnabled) { uint32_t width = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x << 4), 64); uint32_t height = MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x << 2), 8) << 1; MOS_ZeroMemory(&BrcBuffers.sBrcRoiSurface, sizeof(MOS_SURFACE)); allocParamsForBuffer2D.dwWidth = width; allocParamsForBuffer2D.dwHeight = height; allocParamsForBuffer2D.pBufName = "BRC ROI Surface"; CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( m_osInterface, &allocParamsForBuffer2D, &BrcBuffers.sBrcRoiSurface.OsResource), "Failed to allocate BRC ROI surface."); BrcBuffers.sBrcRoiSurface.TileType = MOS_TILE_LINEAR; BrcBuffers.sBrcRoiSurface.bArraySpacing = true; BrcBuffers.sBrcRoiSurface.Format = Format_Buffer_2D; BrcBuffers.sBrcRoiSurface.dwWidth = width; BrcBuffers.sBrcRoiSurface.dwHeight = height; BrcBuffers.sBrcRoiSurface.dwPitch = (uint32_t)BrcBuffers.sBrcRoiSurface.OsResource.pGmmResInfo->GetRenderPitch(); uint8_t* pData = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &(BrcBuffers.sBrcRoiSurface.OsResource), &lockFlagsWriteOnly); if (pData == nullptr) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC ROI surface."); eStatus = MOS_STATUS_UNKNOWN; return eStatus; } uint32_t size = BrcBuffers.sBrcRoiSurface.dwPitch * BrcBuffers.sBrcRoiSurface.dwHeight; MOS_ZeroMemory(pData, size); m_osInterface->pfnUnlockResource( m_osInterface, &BrcBuffers.sBrcRoiSurface.OsResource); } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::ReleaseResourcesBrc() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.resBrcHistoryBuffer); m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.resBrcPakStatisticBuffer[0]); for (int i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) { m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.resBrcImageStatesReadBuffer[i]); m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.sBrcConstantDataBuffer[i].OsResource); m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.resMbBrcConstDataBuffer[i]); } m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.resBrcImageStatesWriteBuffer); m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.sMeBrcDistortionBuffer.OsResource); m_osInterface->pfnFreeResource(m_osInterface, &BrcBuffers.resMbEncAdvancedDsh); m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.resMbEncBrcBuffer); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::ReleaseResourcesMbBrc() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.sBrcMbQpBuffer.OsResource); m_osInterface->pfnFreeResource( m_osInterface, &BrcBuffers.sBrcRoiSurface.OsResource); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::GenericEncodeMeKernel(EncodeBrcBuffers* brcBuffers, HmeLevel hmeLevel) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); // Each ME kernel buffer counts as a separate perf task m_osInterface->pfnResetPerfBufferID(m_osInterface); CODECHAL_MEDIA_STATE_TYPE EncFunctionType = (hmeLevel == HME_LEVEL_32x) ? CODECHAL_MEDIA_STATE_32X_ME : (hmeLevel == HME_LEVEL_16x) ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME; uint32_t krnStateIdx = ((m_pictureCodingType == P_TYPE) ? CODECHAL_ENCODE_ME_IDX_P : CODECHAL_ENCODE_ME_IDX_B); auto kernelState = &m_meKernelStates[krnStateIdx]; // If Single Task Phase is not enabled, use BT count for the kernel state. if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) { uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( m_stateHeapInterface, dwMaxBtCount)); m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount); CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( m_stateHeapInterface, kernelState, false, 0, false, m_storeData)); MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; MOS_ZeroMemory(&idParams, sizeof(idParams)); idParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( m_stateHeapInterface, 1, &idParams)); // Setup AVC Curbe MeCurbeParams meParams; MOS_ZeroMemory(&meParams, sizeof(meParams)); meParams.hmeLvl = hmeLevel; meParams.pKernelState = kernelState; if (!m_useCommonKernel) { CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeMe( &meParams)); } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( EncFunctionType, MHW_DSH_TYPE, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( EncFunctionType, kernelState)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( EncFunctionType, MHW_ISH_TYPE, kernelState)); ) MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); sendKernelCmdsParams.EncFunctionType = EncFunctionType; sendKernelCmdsParams.pKernelState = kernelState; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); // Add binding table CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( m_stateHeapInterface, kernelState)); //Add surface states MeSurfaceParams meSurfaceParams; MOS_ZeroMemory(&meSurfaceParams, sizeof(meSurfaceParams)); meSurfaceParams.dwNumRefIdxL0ActiveMinus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1; meSurfaceParams.dwNumRefIdxL1ActiveMinus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1; meSurfaceParams.pL0RefFrameList = &(m_avcSliceParams->RefPicList[LIST_0][0]); meSurfaceParams.pL1RefFrameList = &(m_avcSliceParams->RefPicList[LIST_1][0]); meSurfaceParams.ppRefList = &m_refList[0]; meSurfaceParams.pPicIdx = &m_picIdx[0]; meSurfaceParams.pCurrOriginalPic = &m_currOriginalPic; meSurfaceParams.ps4xMeMvDataBuffer = &m_4xMeMvDataBuffer; meSurfaceParams.dw4xMeMvBottomFieldOffset = (uint32_t)m_meMvBottomFieldOffset; meSurfaceParams.ps16xMeMvDataBuffer = &m_16xMeMvDataBuffer; meSurfaceParams.dw16xMeMvBottomFieldOffset = (uint32_t)m_meMv16xBottomFieldOffset; meSurfaceParams.ps32xMeMvDataBuffer = &m_32xMeMvDataBuffer; meSurfaceParams.dw32xMeMvBottomFieldOffset = (uint32_t)m_meMv32xBottomFieldOffset; meSurfaceParams.dw4xScaledBottomFieldOffset = (uint32_t)m_scaledBottomFieldOffset; meSurfaceParams.dw16xScaledBottomFieldOffset = (uint32_t)m_scaled16xBottomFieldOffset; meSurfaceParams.dw32xScaledBottomFieldOffset = (uint32_t)m_scaled32xBottomFieldOffset; meSurfaceParams.psMeDistortionBuffer = &m_4xMeDistortionBuffer; meSurfaceParams.dwMeDistortionBottomFieldOffset = (uint32_t)m_meDistortionBottomFieldOffset; meSurfaceParams.psMeBrcDistortionBuffer = &brcBuffers->sMeBrcDistortionBuffer; meSurfaceParams.dwMeBrcDistortionBottomFieldOffset = brcBuffers->dwMeBrcDistortionBottomFieldOffset; meSurfaceParams.dwDownscaledWidthInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledWidthInMb32x : (hmeLevel == HME_LEVEL_16x) ? m_downscaledWidthInMb16x : m_downscaledWidthInMb4x; meSurfaceParams.dwDownscaledHeightInMb = (hmeLevel == HME_LEVEL_32x) ? m_downscaledFrameFieldHeightInMb32x : (hmeLevel == HME_LEVEL_16x) ? m_downscaledFrameFieldHeightInMb16x : m_downscaledFrameFieldHeightInMb4x; meSurfaceParams.dwVerticalLineStride = m_verticalLineStride; meSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset; meSurfaceParams.b32xMeInUse = (hmeLevel == HME_LEVEL_32x) ? true : false; meSurfaceParams.b16xMeInUse = (hmeLevel == HME_LEVEL_16x) ? true : false; meSurfaceParams.b32xMeEnabled = m_32xMeEnabled; meSurfaceParams.b16xMeEnabled = m_16xMeEnabled; meSurfaceParams.pMeBindingTable = &m_meBindingTable; meSurfaceParams.pKernelState = kernelState; if (!m_useCommonKernel) { CODECHAL_ENCODE_CHK_STATUS_RETURN(SendMeSurfaces(&cmdBuffer, &meSurfaceParams)); } // Dump SSH for ME kernel CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( EncFunctionType, MHW_SSH_TYPE, kernelState))); /* zero out the mv data memory and me distortion buffer for the driver ULT kernel only writes out this data used for current frame, in some cases the the data used for previous frames would be left in the buffer (for example, the L1 mv for B frame would still show in the P frame mv data buffer */ /* Zeroing out the buffers has perf impact, so zero it out only when dumps are actually enabled */ CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface); uint8_t* data; uint32_t size; bool driverMeDumpEnabled; driverMeDumpEnabled = m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel4xMe)|| m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel16xMe)|| m_debugInterface->DumpIsEnabled(CodechalDbgKernel::kernel32xMe); if (driverMeDumpEnabled) { MOS_LOCK_PARAMS lockFlags; MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); lockFlags.WriteOnly = 1; switch (hmeLevel) { case HME_LEVEL_32x: data = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &m_32xMeMvDataBuffer.OsResource, &lockFlags); CODECHAL_ENCODE_CHK_NULL_RETURN(data); size = MOS_ALIGN_CEIL((m_downscaledWidthInMb32x * 32), 64) * (m_downscaledHeightInMb32x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER); MOS_ZeroMemory(data, size); m_osInterface->pfnUnlockResource( m_osInterface, &m_32xMeMvDataBuffer.OsResource); break; case HME_LEVEL_16x: data = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &m_16xMeMvDataBuffer.OsResource, &lockFlags); CODECHAL_ENCODE_CHK_NULL_RETURN(data); size = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) * (m_downscaledHeightInMb16x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER); MOS_ZeroMemory(data, size); m_osInterface->pfnUnlockResource( m_osInterface, &m_16xMeMvDataBuffer.OsResource); break; case HME_LEVEL_4x: data = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &m_4xMeMvDataBuffer.OsResource, &lockFlags); CODECHAL_ENCODE_CHK_NULL_RETURN(data); size = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) * (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER); MOS_ZeroMemory(data, size); m_osInterface->pfnUnlockResource( m_osInterface, &m_4xMeMvDataBuffer.OsResource); break; default: eStatus = MOS_STATUS_INVALID_PARAMETER; return eStatus; } // zeroing out ME dist buffer if (m_4xMeDistortionBufferSupported) { data = (uint8_t*)m_osInterface->pfnLockResource( m_osInterface, &m_4xMeDistortionBuffer.OsResource, &lockFlags); CODECHAL_ENCODE_CHK_NULL_RETURN(data); size = m_4xMeDistortionBuffer.dwHeight * m_4xMeDistortionBuffer.dwPitch; MOS_ZeroMemory(data, size); m_osInterface->pfnUnlockResource( m_osInterface, &m_4xMeDistortionBuffer.OsResource); } } ); uint32_t uiScalingFactor = (hmeLevel == HME_LEVEL_32x) ? SCALE_FACTOR_32x : (hmeLevel == HME_LEVEL_16x) ? SCALE_FACTOR_16x : SCALE_FACTOR_4x; uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / uiScalingFactor); uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / uiScalingFactor); CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams; MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams)); walkerCodecParams.WalkerMode = m_walkerMode; walkerCodecParams.dwResolutionX = resolutionX; walkerCodecParams.dwResolutionY = resolutionY; walkerCodecParams.bNoDependency = true; walkerCodecParams.bMbaff = m_mbaffEnabled; walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported; walkerCodecParams.ucGroupId = m_groupId; MHW_WALKER_PARAMS walkerParams; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams( m_hwInterface, &walkerParams, &walkerCodecParams)); HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__)); HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters()); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd( &cmdBuffer, &walkerParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, EncFunctionType)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( m_stateHeapInterface, kernelState)); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( m_stateHeapInterface)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); } CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( & cmdBuffer, EncFunctionType, nullptr))); m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) { HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); m_lastTaskInPhase = false; } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::InitKernelStateMe() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; uint8_t* kernelBinary; uint32_t kernelSize; uint32_t kuid = m_useCommonKernel ? m_kuidCommon : m_kuid; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, kuid, &kernelBinary, &kernelSize)); for (auto krnStateIdx = 0; krnStateIdx < 2; krnStateIdx++) { CODECHAL_KERNEL_HEADER currKrnHeader; auto kernelStatePtr = &m_meKernelStates[krnStateIdx]; auto encOperation = ENC_ME; CODECHAL_ENCODE_CHK_STATUS_RETURN(this->pfnGetKernelHeaderAndSize( kernelBinary, encOperation, krnStateIdx, &currKrnHeader, (uint32_t*)&kernelSize)); kernelStatePtr->KernelParams.iBTCount = CODECHAL_ENCODE_AVC_ME_NUM_SURFACES_CM; kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads; kernelStatePtr->KernelParams.iCurbeLength = sizeof(CODECHAL_ENCODE_AVC_ME_CURBE); kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH; kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT; kernelStatePtr->KernelParams.iIdCount = 1; kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData(); kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT); kernelStatePtr->KernelParams.iSize = kernelSize; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested( m_stateHeapInterface, kernelStatePtr->KernelParams.iBTCount, &kernelStatePtr->dwSshSize, &kernelStatePtr->dwBindingTableSize)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr)); if (m_noMeKernelForPFrame) { m_meKernelStates[1] = m_meKernelStates[0]; break; } } // Until a better way can be found, maintain old binding table structures auto bindingTable = &m_meBindingTable; bindingTable->dwMEMVDataSurface = CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE_CM; bindingTable->dw16xMEMVDataSurface = CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE_CM; bindingTable->dw32xMEMVDataSurface = CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE_CM; bindingTable->dwMEDist = CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE_CM; bindingTable->dwMEBRCDist = CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION_CM; bindingTable->dwMECurrForFwdRef = CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF_CM; bindingTable->dwMEFwdRefPicIdx[0] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX0_CM; bindingTable->dwMEFwdRefPicIdx[1] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX1_CM; bindingTable->dwMEFwdRefPicIdx[2] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX2_CM; bindingTable->dwMEFwdRefPicIdx[3] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX3_CM; bindingTable->dwMEFwdRefPicIdx[4] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX4_CM; bindingTable->dwMEFwdRefPicIdx[5] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX5_CM; bindingTable->dwMEFwdRefPicIdx[6] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX6_CM; bindingTable->dwMEFwdRefPicIdx[7] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX7_CM; bindingTable->dwMECurrForBwdRef = CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF_CM; bindingTable->dwMEBwdRefPicIdx[0] = CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX0_CM; bindingTable->dwMEBwdRefPicIdx[1] = CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX1_CM; return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SetCurbeMe(MeCurbeParams* params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_ASSERT(m_avcSeqParam->TargetUsage <= NUM_TARGET_USAGE_MODES); auto slcParams = m_avcSliceParams; auto framePicture = CodecHal_PictureIsFrame(m_avcPicParam->CurrOriginalPic); auto qpPrimeY = (m_avcPicParam->pic_init_qp_minus26 + 26) + m_avcSliceParams->slice_qp_delta; auto mvShiftFactor = 0; auto prevMvReadPosFactor = 0; bool useMvFromPrevStep, writeDistortions; uint32_t scaleFactor; switch (params->hmeLvl) { case HME_LEVEL_32x: useMvFromPrevStep = CODECHAL_ENCODE_AVC_HME_FIRST_STEP; writeDistortions = false; scaleFactor = SCALE_FACTOR_32x; mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_32x; break; case HME_LEVEL_16x: useMvFromPrevStep = (m_32xMeEnabled) ? CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP : CODECHAL_ENCODE_AVC_HME_FIRST_STEP; writeDistortions = false; scaleFactor = SCALE_FACTOR_16x; mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_16x; prevMvReadPosFactor = CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_16x; break; case HME_LEVEL_4x: useMvFromPrevStep = (m_16xMeEnabled) ? CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP : CODECHAL_ENCODE_AVC_HME_FIRST_STEP; writeDistortions = true; scaleFactor = SCALE_FACTOR_4x; mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_4x; prevMvReadPosFactor = CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_4x; break; default: eStatus = MOS_STATUS_INVALID_PARAMETER; return eStatus; break; } CODECHAL_ENCODE_AVC_ME_CURBE cmd; CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy( &cmd, sizeof(CODECHAL_ENCODE_AVC_ME_CURBE), g_cInit_CODECHAL_ENCODE_AVC_ME_CURBE, sizeof(CODECHAL_ENCODE_AVC_ME_CURBE))); if (m_avcPicParam->bEnableSubPelMode) { cmd.DW3.SubPelMode = m_avcPicParam->SubPelMode; } else { cmd.DW3.SubPelMode = 3; } if (m_fieldScalingOutputInterleaved) { cmd.DW3.SrcAccess = cmd.DW3.RefAccess = CodecHal_PictureIsField(m_avcPicParam->CurrOriginalPic) ? 1 : 0; cmd.DW7.SrcFieldPolarity = CodecHal_PictureIsBottomField(m_avcPicParam->CurrOriginalPic) ? 1 : 0; } cmd.DW4.PictureHeightMinus1 = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scaleFactor) - 1; cmd.DW4.PictureWidth = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth / scaleFactor); cmd.DW5.QpPrimeY = qpPrimeY; cmd.DW6.WriteDistortions = writeDistortions; cmd.DW6.UseMvFromPrevStep = useMvFromPrevStep; cmd.DW6.SuperCombineDist = m_superCombineDistGeneric[m_avcSeqParam->TargetUsage]; cmd.DW6.MaxVmvR = (framePicture) ? CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level) * 4 : (CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level) >> 1) * 4; if (m_pictureCodingType == B_TYPE) { // This field is irrelevant since we are not using the bi-direct search. // set it to 32 cmd.DW1.BiWeight = 32; cmd.DW13.NumRefIdxL1MinusOne = m_avcSliceParams->num_ref_idx_l1_active_minus1; } if (m_pictureCodingType == P_TYPE || m_pictureCodingType == B_TYPE) { cmd.DW13.NumRefIdxL0MinusOne = m_avcSliceParams->num_ref_idx_l0_active_minus1; } cmd.DW13.RefStreaminCost = 5; // This flag is to indicate the ROI source type instead of indicating ROI is enabled or not cmd.DW13.ROIEnable = 0; if (!framePicture) { if (m_pictureCodingType != I_TYPE) { cmd.DW14.List0RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_0); cmd.DW14.List0RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_1); cmd.DW14.List0RefID2FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_2); cmd.DW14.List0RefID3FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_3); cmd.DW14.List0RefID4FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_4); cmd.DW14.List0RefID5FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_5); cmd.DW14.List0RefID6FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_6); cmd.DW14.List0RefID7FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_7); } if (m_pictureCodingType == B_TYPE) { cmd.DW14.List1RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_0); cmd.DW14.List1RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_1); } } cmd.DW15.MvShiftFactor = mvShiftFactor; cmd.DW15.PrevMvReadPosFactor = prevMvReadPosFactor; // r3 & r4 uint8_t meMethod, tableIdx, tu = 0; tu = m_avcSeqParam->TargetUsage; if (m_pictureCodingType == B_TYPE) { meMethod = m_bmeMethodTable ? // use the ME table dependent on prototype or codec standard m_bmeMethodTable[tu] : m_bMeMethodGeneric[tu]; } else { meMethod = m_meMethodTable ? // use the ME table dependent on prototype or codec standard m_meMethodTable[tu] : m_meMethodGeneric[tu]; } tableIdx = (m_pictureCodingType == B_TYPE) ? 1 : 0; eStatus = MOS_SecureMemcpy(&(cmd.SPDelta), 14 * sizeof(uint32_t), m_encodeSearchPath[tableIdx][meMethod], 14 * sizeof(uint32_t)); if (eStatus != MOS_STATUS_SUCCESS) { CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); return eStatus; } // r5 cmd.DW32._4xMeMvOutputDataSurfIndex = CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE_CM; cmd.DW33._16xOr32xMeMvInputDataSurfIndex = (params->hmeLvl == HME_LEVEL_32x) ? CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE_CM : CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE_CM; cmd.DW34._4xMeOutputDistSurfIndex = CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE_CM; cmd.DW35._4xMeOutputBrcDistSurfIndex = CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION_CM; cmd.DW36.VMEFwdInterPredictionSurfIndex = CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF_CM; cmd.DW37.VMEBwdInterPredictionSurfIndex = CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF_CM; CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData( &cmd, params->pKernelState->dwCurbeOffset, sizeof(cmd))); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateHmeParam( m_16xMeEnabled, m_32xMeEnabled, meMethod, &cmd)); ) return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SendMeSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, MeSurfaceParams* params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); CODECHAL_ENCODE_CHK_NULL_RETURN(params); CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); CODECHAL_ENCODE_CHK_NULL_RETURN(params->pCurrOriginalPic); CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps4xMeMvDataBuffer); CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeDistortionBuffer); CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeBrcDistortionBuffer); CODECHAL_MEDIA_STATE_TYPE encMediaStateType; encMediaStateType = (params->b32xMeInUse) ? CODECHAL_MEDIA_STATE_32X_ME : params->b16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME; CODECHAL_ENCODE_CHK_NULL_RETURN(params->pMeBindingTable); auto meBindingTable = params->pMeBindingTable; auto currFieldPicture = CodecHal_PictureIsField(*(params->pCurrOriginalPic)) ? 1 : 0; auto currBottomField = CodecHal_PictureIsBottomField(*(params->pCurrOriginalPic)) ? 1 : 0; uint8_t ucCurrVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); PMOS_SURFACE currScaledSurface = nullptr, meMvDataBuffer = nullptr; uint32_t meMvBottomFieldOffset = 0, currScaledBottomFieldOffset = 0, refScaledBottomFieldOffset = 0; if (params->b32xMeInUse) { CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps32xMeMvDataBuffer); currScaledSurface = m_trackedBuf->Get32xDsSurface(CODEC_CURR_TRACKED_BUFFER); meMvDataBuffer = params->ps32xMeMvDataBuffer; meMvBottomFieldOffset = params->dw32xMeMvBottomFieldOffset; currScaledBottomFieldOffset = params->dw32xScaledBottomFieldOffset; } else if (params->b16xMeInUse) { CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps16xMeMvDataBuffer); currScaledSurface = m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER); meMvDataBuffer = params->ps16xMeMvDataBuffer; meMvBottomFieldOffset = params->dw16xMeMvBottomFieldOffset; currScaledBottomFieldOffset = params->dw16xScaledBottomFieldOffset; } else { currScaledSurface = m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER); meMvDataBuffer = params->ps4xMeMvDataBuffer; meMvBottomFieldOffset = params->dw4xMeMvBottomFieldOffset; currScaledBottomFieldOffset = params->dw4xScaledBottomFieldOffset; } // Reference height and width information should be taken from the current scaled surface rather // than from the reference scaled surface in the case of PAFF. auto refScaledSurface = *currScaledSurface; auto width = MOS_ALIGN_CEIL(params->dwDownscaledWidthInMb * 32, 64); auto height = params->dwDownscaledHeightInMb * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER; // Force the values meMvDataBuffer->dwWidth = width; meMvDataBuffer->dwHeight = height; meMvDataBuffer->dwPitch = width; CODECHAL_SURFACE_CODEC_PARAMS surfaceParams; MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = meMvDataBuffer; surfaceParams.dwOffset = meMvBottomFieldOffset; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; surfaceParams.dwBindingTableOffset = meBindingTable->dwMEMVDataSurface; surfaceParams.bIsWritable = true; surfaceParams.bRenderTarget = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); if (params->b16xMeInUse && params->b32xMeEnabled) { // Pass 32x MV to 16x ME operation MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = params->ps32xMeMvDataBuffer; surfaceParams.dwOffset = currBottomField ? params->dw32xMeMvBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; surfaceParams.dwBindingTableOffset = meBindingTable->dw32xMEMVDataSurface; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); } else if (!params->b32xMeInUse && params->b16xMeEnabled) { // Pass 16x MV to 4x ME operation MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = params->ps16xMeMvDataBuffer; surfaceParams.dwOffset = currBottomField ? params->dw16xMeMvBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; surfaceParams.dwBindingTableOffset = meBindingTable->dw16xMEMVDataSurface; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); } // Insert Distortion buffers only for 4xMe case if (!params->b32xMeInUse && !params->b16xMeInUse) { MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = params->psMeBrcDistortionBuffer; surfaceParams.dwOffset = params->dwMeBrcDistortionBottomFieldOffset; surfaceParams.dwBindingTableOffset = meBindingTable->dwMEBRCDist; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value; surfaceParams.bIsWritable = true; surfaceParams.bRenderTarget = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bIs2DSurface = true; surfaceParams.bMediaBlockRW = true; surfaceParams.psSurface = params->psMeDistortionBuffer; surfaceParams.dwOffset = params->dwMeDistortionBottomFieldOffset; surfaceParams.dwBindingTableOffset = meBindingTable->dwMEDist; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value; surfaceParams.bIsWritable = true; surfaceParams.bRenderTarget = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); } // Setup references 1...n // LIST 0 references uint8_t refPicIdx, refIdx; CODEC_PICTURE refPic; bool refFieldPicture, refBottomField; for (refIdx = 0; refIdx <= params->dwNumRefIdxL0ActiveMinus1; refIdx++) { refPic = params->pL0RefFrameList[refIdx]; if (!CodecHal_PictureIsInvalid(refPic) && params->pPicIdx[refPic.FrameIdx].bValid) { if (refIdx == 0) { // Current Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = currScaledSurface; surfaceParams.dwOffset = currBottomField ? currScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = meBindingTable->dwMECurrForFwdRef; surfaceParams.ucVDirection = ucCurrVDirection; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); } refFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0; refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0; refPicIdx = params->pPicIdx[refPic.FrameIdx].ucPicIdx; uint8_t scaledIdx = params->ppRefList[refPicIdx]->ucScalingIdx; MOS_SURFACE* surface; if (params->b32xMeInUse) { surface = m_trackedBuf->Get32xDsSurface(scaledIdx); } else if (params->b16xMeInUse) { surface = m_trackedBuf->Get16xDsSurface(scaledIdx); } else { surface = m_trackedBuf->Get4xDsSurface(scaledIdx); } CODECHAL_ENCODE_CHK_NULL_RETURN(surface); refScaledSurface.OsResource = surface->OsResource; refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0; // L0 Reference Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = &refScaledSurface; surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = meBindingTable->dwMEFwdRefPicIdx[refIdx]; surfaceParams.ucVDirection = !currFieldPicture ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); } } // Setup references 1...n // LIST 1 references for (refIdx = 0; refIdx <= params->dwNumRefIdxL1ActiveMinus1; refIdx++) { refPic = params->pL1RefFrameList[refIdx]; if (!CodecHal_PictureIsInvalid(refPic) && params->pPicIdx[refPic.FrameIdx].bValid) { if (refIdx == 0) { // Current Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = currScaledSurface; surfaceParams.dwOffset = currBottomField ? currScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = meBindingTable->dwMECurrForBwdRef; surfaceParams.ucVDirection = ucCurrVDirection; CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); } refFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0; refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0; refPicIdx = params->pPicIdx[refPic.FrameIdx].ucPicIdx; uint8_t scaledIdx = params->ppRefList[refPicIdx]->ucScalingIdx; MOS_SURFACE* surface; if (params->b32xMeInUse) { surface = m_trackedBuf->Get32xDsSurface(scaledIdx); } else if (params->b16xMeInUse) { surface = m_trackedBuf->Get16xDsSurface(scaledIdx); } else { surface = m_trackedBuf->Get4xDsSurface(scaledIdx); } CODECHAL_ENCODE_CHK_NULL_RETURN(surface); refScaledSurface.OsResource = surface->OsResource; refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0; // L1 Reference Picture Y - VME MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.bUseAdvState = true; surfaceParams.psSurface = &refScaledSurface; surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0; surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value; surfaceParams.dwBindingTableOffset = meBindingTable->dwMEBwdRefPicIdx[refIdx]; surfaceParams.ucVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( m_hwInterface, cmdBuffer, &surfaceParams, params->pKernelState)); } } return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::GenericEncodePictureLevel(PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_ENCODE_FUNCTION_ENTER; auto trellisQuantParams = &m_trellisQuantParams; PerfTagSetting perfTag; perfTag.Value = 0; perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE; perfTag.PictureCodingType = m_pictureCodingType; m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); // set MFX_PIPE_MODE_SELECT values MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams; pipeModeSelectParams.Mode = m_mode; pipeModeSelectParams.bStreamOutEnabled = (m_currPass != m_numPasses);// Disable Stream Out for final pass; its important for multiple passes, because , next pass will take the qp from stream out pipeModeSelectParams.bDeblockerStreamOutEnable = params->bDeblockerStreamOutEnable; pipeModeSelectParams.bPostDeblockOutEnable = params->bPostDeblockOutEnable; pipeModeSelectParams.bPreDeblockOutEnable = params->bPreDeblockOutEnable; pipeModeSelectParams.bDynamicSliceEnable = m_avcSeqParam->EnableSliceLevelRateCtrl; // set MFX_PIPE_BUF_ADDR_STATE values MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams; pipeBufAddrParams.Mode = m_mode; pipeBufAddrParams.psPreDeblockSurface = params->psPreDeblockSurface; pipeBufAddrParams.psPostDeblockSurface = params->psPostDeblockSurface; CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetPipeBufAddr(&pipeBufAddrParams)); pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak; pipeBufAddrParams.presStreamOutBuffer = &m_resStreamOutBuffer[m_currRecycledBufIdx]; pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer; pipeBufAddrParams.presMfdIntraRowStoreScratchBuffer = &m_intraRowStoreScratchBuffer; pipeBufAddrParams.presMacroblockIldbStreamOutBuffer1 = params->presMacroblockIldbStreamOutBuffer1; pipeBufAddrParams.presMacroblockIldbStreamOutBuffer2 = params->presMacroblockIldbStreamOutBuffer2; CODECHAL_DEBUG_TOOL( // PAK Input Raw Surface CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( m_rawSurfaceToPak, CodechalDbgAttr::attrEncodeRawInputSurface, "PAK_Input_SrcSurf")); ) auto firstValidFrame = &m_reconSurface.OsResource; // Setting invalid entries to nullptr for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) { pipeBufAddrParams.presReferences[i] = nullptr; } uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME; for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) { if (m_picIdx[i].bValid) { uint8_t picIdx = m_picIdx[i].ucPicIdx; uint8_t frameStoreId = m_refList[picIdx]->ucFrameId; CodecHalGetResourceInfo( m_osInterface, &(m_refList[picIdx]->sRefReconBuffer)); pipeBufAddrParams.presReferences[frameStoreId] = &(m_refList[picIdx]->sRefReconBuffer.OsResource); if (picIdx < firstValidFrameId) { firstValidFrameId = picIdx; firstValidFrame = pipeBufAddrParams.presReferences[picIdx]; } CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface); MOS_SURFACE refSurface; MOS_ZeroMemory(&refSurface, sizeof(refSurface)); refSurface.Format = Format_NV12; refSurface.OsResource = *(pipeBufAddrParams.presReferences[frameStoreId]); CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo( m_osInterface, &refSurface)); m_debugInterface->m_refIndex = frameStoreId; std::string refSurfName = "RefSurf[" + std::to_string(static_cast(m_debugInterface->m_refIndex)) + "]"; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( &refSurface, CodechalDbgAttr::attrReferenceSurfaces, refSurfName.c_str()));) } } for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) { // error concealment for the unset reference addresses if (!pipeBufAddrParams.presReferences[i]) { pipeBufAddrParams.presReferences[i] = firstValidFrame; } } if (m_sliceSizeStreamoutSupported) { pipeBufAddrParams.presSliceSizeStreamOutBuffer = &m_pakSliceSizeStreamoutBuffer; } // set MFX_IND_OBJ_BASE_ADDR_STATE values MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams; MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams)); indObjBaseAddrParams.Mode = CODECHAL_ENCODE_MODE_AVC; indObjBaseAddrParams.presMvObjectBuffer = &m_resMvDataSurface; indObjBaseAddrParams.dwMvObjectOffset = m_mvBottomFieldOffset; indObjBaseAddrParams.dwMvObjectSize = m_mvDataSize; indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer; indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound; // set MFX_BSP_BUF_BASE_ADDR_STATE values MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams; MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams)); bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resMPCRowStoreScratchBuffer; MHW_VDBOX_QM_PARAMS qmParams; qmParams.Standard = CODECHAL_AVC; qmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists; MHW_VDBOX_QM_PARAMS fqmParams; fqmParams.Standard = CODECHAL_AVC; fqmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists; // Add AVC Direct Mode command MHW_VDBOX_AVC_DIRECTMODE_PARAMS directmodeParams; MOS_ZeroMemory(&directmodeParams, sizeof(directmodeParams)); directmodeParams.CurrPic = m_avcPicParam->CurrReconstructedPic; directmodeParams.isEncode = true; directmodeParams.uiUsedForReferenceFlags = 0xFFFFFFFF; directmodeParams.pAvcPicIdx = &(m_picIdx[0]); directmodeParams.avcRefList = (void**)m_refList; directmodeParams.bPicIdRemappingInUse = false; directmodeParams.bDisableDmvBuffers = true; // PAK cmd buffer header insertion for 1) non STF 2) STF (except VDEnc BRC case inserted in HuC cmd buffer) if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) { bool requestFrameTracking = false; m_hwInterface->m_numRequestedEuSlices = ((m_frameHeight * m_frameWidth) >= m_ssdResolutionThreshold && m_targetUsage <= m_ssdTargetUsageThreshold) ? m_sliceShutdownRequestState : m_sliceShutdownDefaultState; // Send command buffer header at the beginning (OS dependent) // frame tracking tag is only added in the last command buffer header requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase; CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking)); m_hwInterface->m_numRequestedEuSlices = CODECHAL_SLICE_SHUTDOWN_DEFAULT; } if (m_currPass == 0 && params->bBrcEnabled) { CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS encodePictureLevelParam; MOS_ZeroMemory(&encodePictureLevelParam, sizeof(encodePictureLevelParam)); encodePictureLevelParam.presBrcHistoryBuffer = params->presBrcHistoryBuffer; CODECHAL_ENCODE_CHK_STATUS_RETURN(SceneChangeReport(&cmdBuffer, &encodePictureLevelParam)); } if (m_currPass) { MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams; // Insert conditional batch buffer end MOS_ZeroMemory( &miConditionalBatchBufferEndParams, sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS)); miConditionalBatchBufferEndParams.presSemaphoreBuffer = &m_encodeStatusBuf.resStatusBuffer; miConditionalBatchBufferEndParams.dwOffset = (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) + m_encodeStatusBuf.dwImageStatusMaskOffset + (sizeof(uint32_t) * 2); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd( &cmdBuffer, &miConditionalBatchBufferEndParams)); } if (!m_currPass && m_osInterface->bTagResourceSync) { // This is a short term solution to solve the sync tag issue: the sync tag write for PAK is inserted at the end of 2nd pass PAK BB // which may be skipped in multi-pass PAK enabled case. The idea here is to insert the previous frame's tag at the beginning // of the BB and keep the current frame's tag at the end of the BB. There will be a delay for tag update but it should be fine // as long as Dec/VP/Enc won't depend on this PAK so soon. MHW_MI_STORE_DATA_PARAMS params; PMOS_RESOURCE globalGpuContextSyncTagBuffer = nullptr; uint32_t value; CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource( m_osInterface, globalGpuContextSyncTagBuffer)); CODECHAL_HW_CHK_NULL_RETURN(globalGpuContextSyncTagBuffer); value = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal); params.pOsResource = globalGpuContextSyncTagBuffer; params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal); params.dwValue = (value > 0) ? (value - 1) : 0; CODECHAL_HW_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, ¶ms)); } CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams)); // set MFX_SURFACE_STATE values // Ref surface MHW_VDBOX_SURFACE_PARAMS reconSurfaceParams; MOS_ZeroMemory(&reconSurfaceParams, sizeof(reconSurfaceParams)); reconSurfaceParams.Mode = m_mode; reconSurfaceParams.ucSurfaceStateId = CODECHAL_MFX_REF_SURFACE_ID; reconSurfaceParams.psSurface = &m_reconSurface; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &reconSurfaceParams)); // Src surface MHW_VDBOX_SURFACE_PARAMS surfaceParams; MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); surfaceParams.Mode = m_mode; surfaceParams.ucSurfaceStateId = CODECHAL_MFX_SRC_SURFACE_ID; surfaceParams.psSurface = m_rawSurfaceToPak; surfaceParams.bDisplayFormatSwizzle = m_avcPicParam->bDisplayFormatSwizzle; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams)); if (params->bBrcEnabled && m_avcSeqParam->RateControlMethod != RATECONTROL_ICQ) { CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd( &cmdBuffer, params->pImgStateBatchBuffer)); } else { //Set MFX_AVC_IMG_STATE command MHW_VDBOX_AVC_IMG_PARAMS imageStateParams; imageStateParams.currPass = m_currPass; imageStateParams.pEncodeAvcPicParams = m_avcPicParam; imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam; imageStateParams.pEncodeAvcSliceParams = m_avcSliceParams; if (CodecHalIsFeiEncode(m_codecFunction) && m_avcFeiPicParams && m_avcFeiPicParams->dwMaxFrameSize) { imageStateParams.pDeltaQp = m_avcFeiPicParams->pDeltaQp; imageStateParams.dwMaxFrameSize = m_avcFeiPicParams->dwMaxFrameSize; } else if (CodecHalUsesPakEngine(m_codecFunction) && m_avcPicParam->dwMaxFrameSize) { imageStateParams.pDeltaQp = m_avcPicParam->pDeltaQp; imageStateParams.dwMaxFrameSize = m_avcPicParam->dwMaxFrameSize; } imageStateParams.wPicWidthInMb = m_picWidthInMb; imageStateParams.wPicHeightInMb = m_picHeightInMb; imageStateParams.ppRefList = &(m_refList[0]); imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled; imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding; imageStateParams.ucKernelMode = m_kernelMode; imageStateParams.wSlcHeightInMb = m_sliceHeight; imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level); imageStateParams.bSliceSizeStreamOutEnabled = m_sliceSizeStreamoutSupported; if (m_currPass && m_currPass == m_numPasses) { // Enable IPCM pass, excluding VDENC BRC case imageStateParams.bIPCMPass = true; } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(&cmdBuffer, nullptr, &imageStateParams)); CODECHAL_DEBUG_TOOL( CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam( &cmdBuffer, nullptr)); ) } CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxFqmCmd(&cmdBuffer, &fqmParams)); CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcDirectmodeCmd(&cmdBuffer, &directmodeParams)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); return eStatus; } MOS_STATUS CodechalEncodeAvcEnc::SendPrologWithFrameTracking( PMOS_COMMAND_BUFFER cmdBuffer, bool frameTracking, MHW_MI_MMIOREGISTERS *mmioRegister) { return CodechalEncoderState::SendPrologWithFrameTracking(cmdBuffer, frameTracking, mmioRegister); } MOS_STATUS CodechalEncodeAvcEnc::ExecutePreEnc(EncoderParams* encodeParams) { MOS_SYNC_PARAMS syncParams; CODECHAL_ENCODE_FUNCTION_ENTER; CODECHAL_ENCODE_CHK_NULL_RETURN(encodeParams->pPreEncParams); FeiPreEncParams *preEncParams = (FeiPreEncParams *)encodeParams->pPreEncParams; m_encodeParams = *encodeParams; m_newSeqHeader = encodeParams->newSeqHeader; m_newPpsHeader = encodeParams->newPpsHeader; m_arbitraryNumMbsInSlice = encodeParams->arbitraryNumMbsInSlice; if (preEncParams->bDisableMVOutput && preEncParams->bDisableStatisticsOutput) { m_disableStatusReport = true; } m_osInterface->pfnIncPerfFrameID(m_osInterface); CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(InitializePicture(m_encodeParams), "Encoding initialization failed."); // Check if source surface needs to be synchronized and should wait for decode or VPP or any other context if (m_firstField) { syncParams = g_cInitSyncParams; syncParams.GpuContext = m_renderContext; syncParams.presSyncResource = &m_rawSurface.OsResource; syncParams.bReadOnly = true; CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams)); // Update the resource tag (s/w tag) for On-Demand Sync // set the tag on render context for ENC case only, else set it on video context for ENC+PAK case m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams); } // set render engine context m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext); m_osInterface->pfnResetOsStates(m_osInterface); // set all status reports to completed state InitStatusReport(); // Call ENC Kernels CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(ExecuteKernelFunctions(), "ENC failed."); #ifndef FEI_ENABLE_CMRT // Flush encode eStatus buffer CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(ResetStatusReport(), "ResetStatusReprot failed."); #else CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(ResetStatusReport(), "ResetStatusReprot failed."); #endif m_disableStatusReport = false; if (m_firstFrame == false && m_firstTwoFrames == true) { m_firstTwoFrames = false; } m_firstFrame = false; return MOS_STATUS_SUCCESS; } #if USE_CODECHAL_DEBUG_TOOL MOS_STATUS CodechalEncodeAvcEnc::PopulateHmeParam( bool is16xMeEnabled, bool is32xMeEnabled, uint8_t meMethod, void *cmd) { CODECHAL_DEBUG_FUNCTION_ENTER; CODECHAL_DEBUG_CHK_NULL(m_debugInterface); if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar)) { return MOS_STATUS_SUCCESS; } CODECHAL_ENCODE_AVC_ME_CURBE *curbe = (CODECHAL_ENCODE_AVC_ME_CURBE *)cmd; if (m_pictureCodingType == P_TYPE) { m_avcPar->SuperHME = is16xMeEnabled; m_avcPar->UltraHME = is32xMeEnabled; m_avcPar->SuperCombineDist = curbe->DW6.SuperCombineDist; } return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalEncodeAvcEnc::DumpFrameParFile() { CODECHAL_DEBUG_FUNCTION_ENTER; CODECHAL_DEBUG_CHK_NULL(m_debugInterface); if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar)) { return MOS_STATUS_SUCCESS; } std::ostringstream oss; oss.setf(std::ios::showbase | std::ios::uppercase); if (m_pictureCodingType == I_TYPE) { // I Slice Parameters // DDI Params oss << "ProfileIDC = " << std::dec << +m_avcPar->ProfileIDC << std::endl; oss << "LevelIDC = " << std::dec << +m_avcPar->LevelIDC << std::endl; oss << "DisableVUIHeader = " << std::dec << +m_avcPar->DisableVUIHeader << std::endl; oss << "ChromaFormatIDC = " << std::dec << +m_avcPar->ChromaFormatIDC << std::endl; oss << "ChromaQpOffset = " << std::dec << +m_avcPar->ChromaQpOffset << std::endl; oss << "SecondChromaQpOffset = " << std::dec << +m_avcPar->SecondChromaQpOffset << std::endl; oss << "PictureCodingType = " << std::dec << +m_avcPar->PictureCodingType << std::endl; oss << "NumP = " << std::dec << +m_avcPar->NumP << std::endl; oss << "NumB = " << std::dec << +m_avcPar->NumB << std::endl; oss << "NumSlices = " << std::dec << +m_avcPar->NumSlices << std::endl; oss << "ISliceQP = " << std::dec << +m_avcPar->ISliceQP << std::endl; oss << "FrameRateM = " << std::dec << +m_avcPar->FrameRateM << std::endl; oss << "FrameRateD = " << std::dec << +m_avcPar->FrameRateD << std::endl; oss << "BRCMethod = " << std::dec << +m_avcPar->BRCMethod << std::endl; oss << "BRCType = " << std::dec << +m_avcPar->BRCType << std::endl; oss << "DeblockingIDC = " << std::dec << +m_avcPar->DeblockingIDC << std::endl; oss << "DeblockingFilterAlpha = " << std::dec << +m_avcPar->DeblockingFilterAlpha << std::endl; oss << "DeblockingFilterBeta = " << std::dec << +m_avcPar->DeblockingFilterBeta << std::endl; oss << "EntropyCodingMode = " << std::dec << +m_avcPar->EntropyCodingMode << std::endl; oss << "DirectInference = " << std::dec << +m_avcPar->DirectInference << std::endl; oss << "Transform8x8Mode = " << std::dec << +m_avcPar->Transform8x8Mode << std::endl; oss << "CRFQualityFactor = " << std::dec << +m_avcPar->CRFQualityFactor << std::endl; oss << "ConstrainedIntraPred = " << std::dec << +m_avcPar->ConstrainedIntraPred << std::endl; if (m_avcPar->NumP == 0) // There's no P frame { oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl; oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl; } // DS Params oss << "MBFlatnessThreshold = " << std::dec << +m_encodeParState->m_commonPar->mbFlatnessThreshold << std::endl; // BRC init Params oss << "MBBRCEnable = " << std::dec << +m_avcPar->MBBRCEnable << std::endl; oss << "MBRC = " << std::dec << +m_avcPar->MBRC << std::endl; oss << "BitRate = " << std::dec << +m_avcPar->BitRate << std::endl; oss << "InitVbvFullnessInBit = " << std::dec << +m_avcPar->InitVbvFullnessInBit << std::endl; oss << "MaxBitRate = " << std::dec << +m_avcPar->MaxBitRate << std::endl; oss << "VbvSzInBit = " << std::dec << +m_avcPar->VbvSzInBit << std::endl; oss << "AvbrAccuracy = " << std::dec << +m_avcPar->AvbrAccuracy << std::endl; oss << "AvbrConvergence = " << std::dec << +m_avcPar->AvbrConvergence << std::endl; oss << "Window_Size = " << std::dec << +m_avcPar->SlidingWindowSize << std::endl; oss << "LongTermReferenceInterval = " << std::dec << +m_avcPar->LongTermInterval << std::endl; // BRC frame update Params oss << "EnableMultipass = " << std::dec << +m_avcPar->EnableMultipass << std::endl; oss << "MaxNumPakPasses = " << std::dec << +m_avcPar->MaxNumPakPasses << std::endl; oss << "Sliding_Window_Enable = " << std::dec << +m_avcPar->SlidingWindowEnable << std::endl; oss << "UserMaxFrame = " << std::dec << +m_avcPar->UserMaxFrame << std::endl; oss << "FrameSkip_enable = " << std::dec << +m_avcPar->FrameSkipEnable << std::endl; // Enc Params oss << "BlockBasedSkip = " << std::dec << +m_avcPar->BlockBasedSkip << std::endl; oss << "DisableExtendedMvCostRange = " << std::dec << +m_avcPar->DisableExtendedMvCostRange << std::endl; oss << "EnableAdaptiveSearch = " << std::dec << +m_avcPar->EnableAdaptiveSearch << std::endl; oss << "EnableFBRBypass = " << std::dec << +m_avcPar->EnableFBRBypass << std::endl; oss << "MRDisableQPCheck = " << std::dec << +m_avcPar->MRDisableQPCheck << std::endl; oss << "MADEnableFlag = " << std::dec << +m_avcPar->MADEnableFlag << std::endl; oss << "EnableMBFlatnessCheckOptimization = " << std::dec << +m_avcPar->EnableMBFlatnessCheckOptimization << std::endl; oss << "EnableArbitrarySliceSize = " << std::dec << +m_avcPar->EnableArbitrarySliceSize << std::endl; oss << "RefThresh = " << std::dec << +m_avcPar->RefThresh << std::endl; oss << "EnableWavefrontOptimization = " << std::dec << +m_avcPar->EnableWavefrontOptimization << std::endl; oss << "AllFractional = " << std::dec << +m_avcPar->AllFractional << std::endl; oss << "DisableAllFractionalCheckForHighRes = " << std::dec << +m_avcPar->DisableAllFractionalCheckForHighRes << std::endl; oss << "MaxLenSP = " << std::dec << +m_avcPar->MaxLenSP << std::endl; // PAK Params oss << "TrellisQuantizationEnable = " << std::dec << +m_avcPar->TrellisQuantizationEnable << std::endl; oss << "RoundingIntraEnabled = " << std::dec << +m_avcPar->RoundingIntraEnabled << std::endl; oss << "RoundingIntra = " << std::dec << +m_avcPar->RoundingIntra << std::endl; oss << "EnableAdaptiveTrellisQuantization = " << std::dec << +m_avcPar->EnableAdaptiveTrellisQuantization << std::endl; oss << "TrellisQuantizationRounding = " << std::dec << +m_avcPar->TrellisQuantizationRounding << std::endl; oss << "TrellisQuantizationChromaDisable = " << std::dec << +m_avcPar->TrellisQuantizationChromaDisable << std::endl; oss << "ExtendedRhoDomainEn = " << std::dec << +m_avcPar->ExtendedRhoDomainEn << std::endl; oss << "EnableSEI = " << std::dec << +m_avcPar->EnableSEI << std::endl; if (m_avcPar->NumP == 0) // There's no P frame { oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl; } } else if (m_pictureCodingType == P_TYPE) { // P Slice Parameters // DDI Params oss << "PSliceQP = " << std::dec << +m_avcPar->PSliceQP << std::endl; oss << "CabacInitIDC = " << std::dec << +m_avcPar->CabacInitIDC << std::endl; oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl; oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl; if (m_avcPar->NumB == 0) // There's no B frame { oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl; } oss << "WeightedPred = " << std::dec << +m_avcPar->WeightedPred << std::endl; oss << "UseOrigAsRef = " << std::dec << +m_avcPar->UseOrigAsRef << std::endl; oss << "BiSubMbPartMask = " << std::dec << +m_avcPar->BiSubMbPartMask << std::endl; // HME Params oss << "SuperHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superHME : m_avcPar->SuperHME) << std::endl; oss << "UltraHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->ultraHME : m_avcPar->UltraHME) << std::endl; oss << "SuperCombineDist = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superCombineDist : m_avcPar->SuperCombineDist) << std::endl; // Enc Params oss << "SubPelMode = " << std::dec << +m_avcPar->SubPelMode << std::endl; oss << "FTQBasedSkip = " << std::dec << +m_avcPar->FTQBasedSkip << std::endl; oss << "BiMixDisable = " << std::dec << +m_avcPar->BiMixDisable << std::endl; oss << "SurvivedSkipCost = " << std::dec << +m_avcPar->SurvivedSkipCost << std::endl; oss << "UniMixDisable = " << std::dec << +m_avcPar->UniMixDisable << std::endl; oss << "EnableIntraCostScalingForStaticFrame = " << std::dec << +m_avcPar->EnableIntraCostScalingForStaticFrame << std::endl; if (m_avcPar->EnableIntraCostScalingForStaticFrame) { oss << "IntraCostUpdateMethod = 3" << std::endl; } oss << "StaticFrameIntraCostScalingRatioP = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioP << std::endl; oss << "MEMethod = " << std::dec << +m_avcPar->MEMethod << std::endl; oss << "HMECombineLen = " << std::dec << +m_avcPar->HMECombineLen << std::endl; oss << "HMECombineOverlap = " << std::dec << +m_avcPar->HMECombineOverlap << std::endl; oss << "SearchX = " << std::dec << +m_avcPar->SearchX << std::endl; oss << "SearchY = " << std::dec << +m_avcPar->SearchY << std::endl; oss << "SearchControl = " << std::dec << +m_avcPar->SearchControl << std::endl; oss << "MultiplePred = " << std::dec << +m_avcPar->MultiplePred << std::endl; oss << "EnableAdaptiveTxDecision = " << std::dec << +m_avcPar->EnableAdaptiveTxDecision << std::endl; oss << "MBTextureThreshold = " << std::dec << +m_avcPar->MBTextureThreshold << std::endl; oss << "TxDecisionThr = " << std::dec << +m_avcPar->TxDecisionThr << std::endl; oss << "EnablePerMBStaticCheck = " << std::dec << +m_avcPar->EnablePerMBStaticCheck << std::endl; oss << "EnableAdaptiveSearchWindowSize = " << std::dec << +m_avcPar->EnableAdaptiveSearchWindowSize << std::endl; oss << "EnableAdaptiveIntraScaling = " << std::dec << +m_avcPar->EnableAdaptiveIntraScaling << std::endl; // BRC Frame Update oss << "UserMaxFrame_P = " << std::dec << +m_avcPar->UserMaxFrameP << std::endl; // PAK Params oss << "RoundingInterEnabled = " << std::dec << +m_avcPar->RoundingInterEnabled << std::endl; oss << "RoundingInter = " << std::dec << +m_avcPar->RoundingInter << std::endl; oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl; oss << "EnableAdaptiveRounding = " << std::dec << +m_avcPar->EnableAdaptiveRounding << std::endl; } else if (m_pictureCodingType == B_TYPE) { // B Slice Parameters // DDI Params oss << "BSliceQP = " << std::dec << +m_avcPar->BSliceQP << std::endl; oss << "MaxBRefIdxL0 = " << std::dec << +m_avcPar->MaxBRefIdxL0 << std::endl; oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl; oss << "WeightedBiPred = " << std::dec << +m_avcPar->WeightedBiPred << std::endl; // Enc Params oss << "BMEMethod = " << std::dec << +m_avcPar->BMEMethod << std::endl; oss << "HMEBCombineLen = " << std::dec << +m_avcPar->HMEBCombineLen << std::endl; oss << "BSearchX = " << std::dec << +m_avcPar->BSearchX << std::endl; oss << "BSearchY = " << std::dec << +m_avcPar->BSearchY << std::endl; oss << "BSearchControl = " << std::dec << +m_avcPar->BSearchControl << std::endl; oss << "BSkipType = " << std::dec << +m_avcPar->BSkipType << std::endl; oss << "DirectMode = " << std::dec << +m_avcPar->DirectMode << std::endl; oss << "BiWeight = " << std::dec << +m_avcPar->BiWeight << std::endl; oss << "StaticFrameIntraCostScalingRatioB = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioB << std::endl; // PAK Params oss << "RoundingInterB = " << std::dec << +m_avcPar->RoundingInterB << std::endl; } // Dump per frame par file const char *fileName = m_debugInterface->CreateFileName( "EncodeFrame", "EncodePar", CodechalDbgExtType::par); std::ofstream ofs(fileName, std::ios::out); ofs << oss.str(); ofs.close(); return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalEncodeAvcEnc::DumpSeqParFile() { CODECHAL_DEBUG_FUNCTION_ENTER; CODECHAL_DEBUG_CHK_NULL(m_debugInterface); if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar)) { return MOS_STATUS_SUCCESS; } std::ostringstream oss; oss.setf(std::ios::showbase | std::ios::uppercase); // I Slice Parameters // DDI Params oss << "ProfileIDC = " << std::dec << +m_avcPar->ProfileIDC << std::endl; oss << "LevelIDC = " << std::dec << +m_avcPar->LevelIDC << std::endl; oss << "DisableVUIHeader = " << std::dec << +m_avcPar->DisableVUIHeader << std::endl; oss << "ChromaFormatIDC = " << std::dec << +m_avcPar->ChromaFormatIDC << std::endl; oss << "ChromaQpOffset = " << std::dec << +m_avcPar->ChromaQpOffset << std::endl; oss << "SecondChromaQpOffset = " << std::dec << +m_avcPar->SecondChromaQpOffset << std::endl; oss << "PictureCodingType = " << std::dec << +m_avcPar->PictureCodingType << std::endl; oss << "NumP = " << std::dec << +m_avcPar->NumP << std::endl; oss << "NumB = " << std::dec << +m_avcPar->NumB << std::endl; oss << "NumSlices = " << std::dec << +m_avcPar->NumSlices << std::endl; oss << "ISliceQP = " << std::dec << +m_avcPar->ISliceQP << std::endl; oss << "FrameRateM = " << std::dec << +m_avcPar->FrameRateM << std::endl; oss << "FrameRateD = " << std::dec << +m_avcPar->FrameRateD << std::endl; oss << "BRCMethod = " << std::dec << +m_avcPar->BRCMethod << std::endl; oss << "BRCType = " << std::dec << +m_avcPar->BRCType << std::endl; oss << "DeblockingIDC = " << std::dec << +m_avcPar->DeblockingIDC << std::endl; oss << "DeblockingFilterAlpha = " << std::dec << +m_avcPar->DeblockingFilterAlpha << std::endl; oss << "DeblockingFilterBeta = " << std::dec << +m_avcPar->DeblockingFilterBeta << std::endl; oss << "EntropyCodingMode = " << std::dec << +m_avcPar->EntropyCodingMode << std::endl; oss << "DirectInference = " << std::dec << +m_avcPar->DirectInference << std::endl; oss << "Transform8x8Mode = " << std::dec << +m_avcPar->Transform8x8Mode << std::endl; oss << "CRFQualityFactor = " << std::dec << +m_avcPar->CRFQualityFactor << std::endl; oss << "ConstrainedIntraPred = " << std::dec << +m_avcPar->ConstrainedIntraPred << std::endl; if (m_avcPar->NumP == 0) // There's no P frame { oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl; oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl; } // DS Params oss << "MBFlatnessThreshold = " << std::dec << +m_encodeParState->m_commonPar->mbFlatnessThreshold << std::endl; // BRC init Params oss << "MBBRCEnable = " << std::dec << +m_avcPar->MBBRCEnable << std::endl; oss << "MBRC = " << std::dec << +m_avcPar->MBRC << std::endl; oss << "BitRate = " << std::dec << +m_avcPar->BitRate << std::endl; oss << "InitVbvFullnessInBit = " << std::dec << +m_avcPar->InitVbvFullnessInBit << std::endl; oss << "MaxBitRate = " << std::dec << +m_avcPar->MaxBitRate << std::endl; oss << "VbvSzInBit = " << std::dec << +m_avcPar->VbvSzInBit << std::endl; oss << "AvbrAccuracy = " << std::dec << +m_avcPar->AvbrAccuracy << std::endl; oss << "AvbrConvergence = " << std::dec << +m_avcPar->AvbrConvergence << std::endl; oss << "Window_Size = " << std::dec << +m_avcPar->SlidingWindowSize << std::endl; oss << "LongTermReferenceInterval = " << std::dec << +m_avcPar->LongTermInterval << std::endl; // BRC frame update Params oss << "EnableMultipass = " << std::dec << +m_avcPar->EnableMultipass << std::endl; oss << "MaxNumPakPasses = " << std::dec << +m_avcPar->MaxNumPakPasses << std::endl; oss << "Sliding_Window_Enable = " << std::dec << +m_avcPar->SlidingWindowEnable << std::endl; oss << "UserMaxFrame = " << std::dec << +m_avcPar->UserMaxFrame << std::endl; oss << "FrameSkip_enable = " << std::dec << +m_avcPar->FrameSkipEnable << std::endl; // Enc Params oss << "BlockBasedSkip = " << std::dec << +m_avcPar->BlockBasedSkip << std::endl; oss << "DisableExtendedMvCostRange = " << std::dec << +m_avcPar->DisableExtendedMvCostRange << std::endl; oss << "EnableAdaptiveSearch = " << std::dec << +m_avcPar->EnableAdaptiveSearch << std::endl; oss << "EnableFBRBypass = " << std::dec << +m_avcPar->EnableFBRBypass << std::endl; oss << "MRDisableQPCheck = " << std::dec << +m_avcPar->MRDisableQPCheck << std::endl; oss << "MADEnableFlag = " << std::dec << +m_avcPar->MADEnableFlag << std::endl; oss << "EnableMBFlatnessCheckOptimization = " << std::dec << +m_avcPar->EnableMBFlatnessCheckOptimization << std::endl; oss << "EnableArbitrarySliceSize = " << std::dec << +m_avcPar->EnableArbitrarySliceSize << std::endl; oss << "RefThresh = " << std::dec << +m_avcPar->RefThresh << std::endl; oss << "EnableWavefrontOptimization = " << std::dec << +m_avcPar->EnableWavefrontOptimization << std::endl; oss << "AllFractional = " << std::dec << +m_avcPar->AllFractional << std::endl; oss << "DisableAllFractionalCheckForHighRes = " << std::dec << +m_avcPar->DisableAllFractionalCheckForHighRes << std::endl; oss << "MaxLenSP = " << std::dec << +m_avcPar->MaxLenSP << std::endl; // PAK Params oss << "TrellisQuantizationEnable = " << std::dec << +m_avcPar->TrellisQuantizationEnable << std::endl; oss << "RoundingIntraEnabled = " << std::dec << +m_avcPar->RoundingIntraEnabled << std::endl; oss << "RoundingIntra = " << std::dec << +m_avcPar->RoundingIntra << std::endl; oss << "EnableAdaptiveTrellisQuantization = " << std::dec << +m_avcPar->EnableAdaptiveTrellisQuantization << std::endl; oss << "TrellisQuantizationRounding = " << std::dec << +m_avcPar->TrellisQuantizationRounding << std::endl; oss << "TrellisQuantizationChromaDisable = " << std::dec << +m_avcPar->TrellisQuantizationChromaDisable << std::endl; oss << "ExtendedRhoDomainEn = " << std::dec << +m_avcPar->ExtendedRhoDomainEn << std::endl; oss << "EnableSEI = " << std::dec << +m_avcPar->EnableSEI << std::endl; if (m_avcPar->NumP == 0) // There's no P frame { oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl; } if (m_avcPar->NumP > 0) { // P Slice Parameters // DDI Params oss << "PSliceQP = " << std::dec << +m_avcPar->PSliceQP << std::endl; oss << "CabacInitIDC = " << std::dec << +m_avcPar->CabacInitIDC << std::endl; oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl; oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl; if (m_avcPar->NumB == 0) // There's no B frame { oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl; } oss << "WeightedPred = " << std::dec << +m_avcPar->WeightedPred << std::endl; oss << "UseOrigAsRef = " << std::dec << +m_avcPar->UseOrigAsRef << std::endl; oss << "BiSubMbPartMask = " << std::dec << +m_avcPar->BiSubMbPartMask << std::endl; // HME Params oss << "SuperHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superHME : m_avcPar->SuperHME) << std::endl; oss << "UltraHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->ultraHME : m_avcPar->UltraHME) << std::endl; oss << "SuperCombineDist = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superCombineDist : m_avcPar->SuperCombineDist) << std::endl; // Enc Params oss << "SubPelMode = " << std::dec << +m_avcPar->SubPelMode << std::endl; oss << "FTQBasedSkip = " << std::dec << +m_avcPar->FTQBasedSkip << std::endl; oss << "BiMixDisable = " << std::dec << +m_avcPar->BiMixDisable << std::endl; oss << "SurvivedSkipCost = " << std::dec << +m_avcPar->SurvivedSkipCost << std::endl; oss << "UniMixDisable = " << std::dec << +m_avcPar->UniMixDisable << std::endl; oss << "EnableIntraCostScalingForStaticFrame = " << std::dec << +m_avcPar->EnableIntraCostScalingForStaticFrame << std::endl; if (m_avcPar->EnableIntraCostScalingForStaticFrame) { oss << "IntraCostUpdateMethod = 3" << std::endl; } oss << "StaticFrameIntraCostScalingRatioP = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioP << std::endl; oss << "MEMethod = " << std::dec << +m_avcPar->MEMethod << std::endl; oss << "HMECombineLen = " << std::dec << +m_avcPar->HMECombineLen << std::endl; oss << "HMECombineOverlap = " << std::dec << +m_avcPar->HMECombineOverlap << std::endl; oss << "SearchX = " << std::dec << +m_avcPar->SearchX << std::endl; oss << "SearchY = " << std::dec << +m_avcPar->SearchY << std::endl; oss << "SearchControl = " << std::dec << +m_avcPar->SearchControl << std::endl; oss << "MultiplePred = " << std::dec << +m_avcPar->MultiplePred << std::endl; oss << "EnableAdaptiveTxDecision = " << std::dec << +m_avcPar->EnableAdaptiveTxDecision << std::endl; oss << "MBTextureThreshold = " << std::dec << +m_avcPar->MBTextureThreshold << std::endl; oss << "TxDecisionThr = " << std::dec << +m_avcPar->TxDecisionThr << std::endl; oss << "EnablePerMBStaticCheck = " << std::dec << +m_avcPar->EnablePerMBStaticCheck << std::endl; oss << "EnableAdaptiveSearchWindowSize = " << std::dec << +m_avcPar->EnableAdaptiveSearchWindowSize << std::endl; oss << "EnableAdaptiveIntraScaling = " << std::dec << +m_avcPar->EnableAdaptiveIntraScaling << std::endl; // BRC Frame Update oss << "UserMaxFrame_P = " << std::dec << +m_avcPar->UserMaxFrameP << std::endl; // PAK Params oss << "RoundingInterEnabled = " << std::dec << +m_avcPar->RoundingInterEnabled << std::endl; oss << "RoundingInter = " << std::dec << +m_avcPar->RoundingInter << std::endl; oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl; oss << "EnableAdaptiveRounding = " << std::dec << +m_avcPar->EnableAdaptiveRounding << std::endl; } if (m_avcPar->NumB > 0) { // B Slice Parameters // DDI Params oss << "BSliceQP = " << std::dec << +m_avcPar->BSliceQP << std::endl; oss << "MaxBRefIdxL0 = " << std::dec << +m_avcPar->MaxBRefIdxL0 << std::endl; oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl; oss << "WeightedBiPred = " << std::dec << +m_avcPar->WeightedBiPred << std::endl; // Enc Params oss << "BMEMethod = " << std::dec << +m_avcPar->BMEMethod << std::endl; oss << "HMEBCombineLen = " << std::dec << +m_avcPar->HMEBCombineLen << std::endl; oss << "BSearchX = " << std::dec << +m_avcPar->BSearchX << std::endl; oss << "BSearchY = " << std::dec << +m_avcPar->BSearchY << std::endl; oss << "BSearchControl = " << std::dec << +m_avcPar->BSearchControl << std::endl; oss << "BSkipType = " << std::dec << +m_avcPar->BSkipType << std::endl; oss << "DirectMode = " << std::dec << +m_avcPar->DirectMode << std::endl; oss << "BiWeight = " << std::dec << +m_avcPar->BiWeight << std::endl; oss << "StaticFrameIntraCostScalingRatioB = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioB << std::endl; // PAK Params oss << "RoundingInterB = " << std::dec << +m_avcPar->RoundingInterB << std::endl; } const char *fileName = m_debugInterface->CreateFileName( "EncodeSequence", "EncodePar", CodechalDbgExtType::par); std::ofstream ofs(fileName, std::ios::app); ofs << oss.str(); ofs.close(); return MOS_STATUS_SUCCESS; } #endif