1 /* 2 * Copyright (c) 2018-2020, Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 //! 23 //! \file encode_hevc_vdenc_weighted_prediction.cpp 24 //! \brief Implemetation for hevc weighted prediction feature 25 //! 26 27 #include "encode_hevc_vdenc_weighted_prediction.h" 28 #include "encode_hevc_vdenc_feature_manager.h" 29 namespace encode 30 { HevcVdencWeightedPred(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)31 HevcVdencWeightedPred::HevcVdencWeightedPred( 32 MediaFeatureManager *featureManager, 33 EncodeAllocator *allocator, 34 CodechalHwInterfaceNext *hwInterface, 35 void *constSettings) : 36 MediaFeature(constSettings) 37 { 38 ENCODE_CHK_NULL_NO_STATUS_RETURN(featureManager); 39 40 m_basicFeature = dynamic_cast<HevcBasicFeature *>(featureManager->GetFeature(FeatureIDs::basicFeature)); 41 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature); 42 } 43 Update(void * params)44 MOS_STATUS HevcVdencWeightedPred::Update(void *params) 45 { 46 ENCODE_FUNC_CALL(); 47 ENCODE_CHK_NULL_RETURN(params); 48 49 EncoderParams *encodeParams = (EncoderParams *)params; 50 51 auto hevcPicParams = static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams); 52 ENCODE_CHK_NULL_RETURN(hevcPicParams); 53 54 m_hevcSliceParams = static_cast<PCODEC_HEVC_ENCODE_SLICE_PARAMS>(encodeParams->pSliceParams); 55 ENCODE_CHK_NULL_RETURN(m_hevcSliceParams); 56 57 if (hevcPicParams->weighted_pred_flag || hevcPicParams->weighted_bipred_flag) 58 { 59 m_enabled = true; 60 } 61 62 m_bEnableGPUWeightedPrediction = m_enabled && hevcPicParams->bEnableGPUWeightedPrediction; 63 64 return MOS_STATUS_SUCCESS; 65 } 66 SetHucBrcUpdateDmemBuffer(bool isFirstPass,VdencHevcHucBrcUpdateDmem & dmem)67 MOS_STATUS HevcVdencWeightedPred::SetHucBrcUpdateDmemBuffer( 68 bool isFirstPass, 69 VdencHevcHucBrcUpdateDmem &dmem) 70 { 71 ENCODE_FUNC_CALL(); 72 73 // 1: BRC (including ACQP), 2: Weighted prediction (should not be enabled in first pass) 74 // 01: BRC, 10: WP never used, 11: BRC + WP 75 dmem.OpMode_U8 = (m_bEnableGPUWeightedPrediction && !isFirstPass) ? 3 : 1; 76 77 if (m_enabled) 78 { 79 dmem.LumaLog2WeightDenom_S8 = 6; 80 dmem.ChromaLog2WeightDenom_S8 = 6; 81 } 82 83 return MOS_STATUS_SUCCESS; 84 } 85 SetHucBrcUpdateConstData(const CODEC_HEVC_ENCODE_SLICE_PARAMS & hevcSliceParams,uint32_t sliceIndex,uint32_t weightOffsetStateCmdSize,uint32_t & sliceLocation,VdencHevcHucBrcConstantData & constantData)86 MOS_STATUS HevcVdencWeightedPred::SetHucBrcUpdateConstData( 87 const CODEC_HEVC_ENCODE_SLICE_PARAMS &hevcSliceParams, 88 uint32_t sliceIndex, 89 uint32_t weightOffsetStateCmdSize, 90 uint32_t &sliceLocation, 91 VdencHevcHucBrcConstantData &constantData) 92 { 93 ENCODE_FUNC_CALL(); 94 95 uint32_t sliceType = hevcSliceParams.slice_type; 96 97 if (m_enabled) 98 { 99 // 1st HCP_WEIGHTOFFSET_STATE cmd - P & B 100 if (sliceType == encodeHevcPSlice || sliceType == encodeHevcBSlice) 101 { 102 // HCP_WEIGHTOFFSET_L0 starts in byte from beginning of the SLB. 103 // 0xFFFF means unavailable in SLB 104 constantData.Slice[sliceIndex].HcpWeightOffsetL0_StartInBytes = 105 (uint16_t)sliceLocation; 106 sliceLocation += weightOffsetStateCmdSize; 107 } 108 109 // 2nd HCP_WEIGHTOFFSET_STATE cmd - B 110 if (sliceType == encodeHevcBSlice) 111 { 112 // HCP_WEIGHTOFFSET_L1 starts in byte from beginning of the SLB. 113 // 0xFFFF means unavailable in SLB 114 constantData.Slice[sliceIndex].HcpWeightOffsetL1_StartInBytes = 115 (uint16_t)sliceLocation; 116 sliceLocation += weightOffsetStateCmdSize; 117 } 118 119 constantData.Slice[sliceIndex].WeightTable_StartInBits = 120 (uint16_t)hevcSliceParams.PredWeightTableBitOffset; 121 constantData.Slice[sliceIndex].WeightTable_EndInBits = 122 (uint16_t)(hevcSliceParams.PredWeightTableBitOffset + 123 (hevcSliceParams.PredWeightTableBitLength)); 124 } 125 else 126 { 127 // 0xFFFF means unavailable in SLB 128 constantData.Slice[sliceIndex].HcpWeightOffsetL0_StartInBytes = 0xFFFF; 129 constantData.Slice[sliceIndex].HcpWeightOffsetL1_StartInBytes = 0xFFFF; 130 131 // number of bits from beginning of slice header, 0xffff means not awailable 132 constantData.Slice[sliceIndex].WeightTable_StartInBits = 0xFFFF; 133 constantData.Slice[sliceIndex].WeightTable_EndInBits = 0xFFFF; 134 } 135 return MOS_STATUS_SUCCESS; 136 } 137 MHW_SETPAR_DECL_SRC(VDENC_WEIGHTSOFFSETS_STATE,HevcVdencWeightedPred)138 MHW_SETPAR_DECL_SRC(VDENC_WEIGHTSOFFSETS_STATE, HevcVdencWeightedPred) 139 { 140 params.denomLuma = 1; 141 142 if (m_enabled) 143 { 144 char lumaWeights[2][CODEC_MAX_NUM_REF_FRAME_HEVC]; 145 int16_t lumaOffsets[2][CODEC_MAX_NUM_REF_FRAME_HEVC]; 146 char chromaWeights[2][CODEC_MAX_NUM_REF_FRAME_HEVC][2]; 147 int16_t chromaOffsets[2][CODEC_MAX_NUM_REF_FRAME_HEVC][2]; 148 149 params.denomLuma = 1 << (m_hevcSliceParams->luma_log2_weight_denom); 150 params.denomChroma = 1 << (m_hevcSliceParams->luma_log2_weight_denom + m_hevcSliceParams->delta_chroma_log2_weight_denom); 151 152 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) 153 { 154 // Luma offset 155 lumaOffsets[0][i] = (int16_t)m_hevcSliceParams->luma_offset[0][i]; 156 lumaOffsets[1][i] = (int16_t)m_hevcSliceParams->luma_offset[1][i]; 157 158 // Cb offset 159 chromaOffsets[0][i][0] = (int16_t)m_hevcSliceParams->chroma_offset[0][i][0]; 160 chromaOffsets[1][i][0] = (int16_t)m_hevcSliceParams->chroma_offset[1][i][0]; 161 162 // Cr offset 163 chromaOffsets[0][i][1] = (int16_t)m_hevcSliceParams->chroma_offset[0][i][1]; 164 chromaOffsets[1][i][1] = (int16_t)m_hevcSliceParams->chroma_offset[1][i][1]; 165 } 166 167 // Luma Weight 168 ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(&lumaWeights[0], sizeof(lumaWeights[0]), &m_hevcSliceParams->delta_luma_weight[0], sizeof(m_hevcSliceParams->delta_luma_weight[0])), "Failed to copy luma weight 0 memory."); 169 170 ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(&lumaWeights[1], sizeof(lumaWeights[1]), &m_hevcSliceParams->delta_luma_weight[1], sizeof(m_hevcSliceParams->delta_luma_weight[1])), "Failed to copy luma weight 1 memory."); 171 172 // Chroma Weight 173 ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(&chromaWeights[0], sizeof(chromaWeights[0]), &m_hevcSliceParams->delta_chroma_weight[0], sizeof(m_hevcSliceParams->delta_chroma_weight[0])), "Failed to copy chroma weight 0 memory."); 174 175 ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(&chromaWeights[1], sizeof(chromaWeights[1]), &m_hevcSliceParams->delta_chroma_weight[1], sizeof(m_hevcSliceParams->delta_chroma_weight[1])), "Failed to copy chroma weight 1 memory."); 176 177 if (m_basicFeature->m_ref.IsLowDelay()) 178 { 179 lumaWeights[1][0] = lumaWeights[0][0]; 180 lumaOffsets[1][0] = lumaOffsets[0][0]; 181 182 chromaWeights[1][0][0] = chromaWeights[0][0][0]; 183 chromaOffsets[1][0][0] = chromaOffsets[0][0][0]; 184 185 chromaWeights[1][0][1] = chromaWeights[0][0][1]; 186 chromaOffsets[1][0][1] = chromaOffsets[0][0][1]; 187 } 188 189 for (auto i = 0; i < 3; i++) 190 { 191 params.offsetsLuma[0][i] = lumaOffsets[0][i]; 192 params.offsetsLuma[1][i] = lumaOffsets[1][i]; 193 params.weightsLuma[0][i] = lumaWeights[0][i]; 194 params.weightsLuma[1][i] = lumaWeights[1][i]; 195 196 params.offsetsChroma[0][i][0] = chromaOffsets[0][i][0]; 197 params.offsetsChroma[1][i][0] = chromaOffsets[1][i][0]; 198 params.offsetsChroma[0][i][1] = chromaOffsets[0][i][1]; 199 params.offsetsChroma[1][i][1] = chromaOffsets[1][i][1]; 200 201 params.weightsChroma[0][i][0] = chromaWeights[0][i][0]; 202 params.weightsChroma[1][i][0] = chromaWeights[1][i][0]; 203 params.weightsChroma[0][i][1] = chromaWeights[0][i][1]; 204 params.weightsChroma[1][i][1] = chromaWeights[1][i][1]; 205 } 206 } 207 208 return MOS_STATUS_SUCCESS; 209 } 210 MHW_SETPAR_DECL_SRC(HCP_WEIGHTOFFSET_STATE,HevcVdencWeightedPred)211 MHW_SETPAR_DECL_SRC(HCP_WEIGHTOFFSET_STATE, HevcVdencWeightedPred) 212 { 213 ENCODE_FUNC_CALL(); 214 215 if (!m_enabled) 216 { 217 return MOS_STATUS_SUCCESS; 218 } 219 220 ENCODE_CHK_NULL_RETURN(m_hevcSliceParams); 221 222 PCODEC_HEVC_ENCODE_SLICE_PARAMS pEncodeHevcSliceParams = &m_basicFeature->m_hevcSliceParams[m_basicFeature->m_curNumSlices]; 223 224 for (auto k = 0; k < 2; k++) // k=0: LIST_0, k=1: LIST_1 225 { 226 // LUMA, Chroma offset 227 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) 228 { 229 params.LumaOffsets[k][i] = pEncodeHevcSliceParams->luma_offset[k][i]; 230 // Cb, Cr 231 for (auto j = 0; j < 2; j++) 232 { 233 params.ChromaOffsets[k][i][j] = pEncodeHevcSliceParams->chroma_offset[k][i][j]; 234 } 235 } 236 237 // LUMA Weight 238 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy( 239 ¶ms.LumaWeights[k], 240 sizeof(params.LumaWeights[k]), 241 &pEncodeHevcSliceParams->delta_luma_weight[k], 242 sizeof(pEncodeHevcSliceParams->delta_luma_weight[k]))); 243 244 // Chroma Weight 245 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) 246 { 247 for (auto j = 0; j < 2; j++) 248 { 249 params.ChromaWeights[k][i][j] = pEncodeHevcSliceParams->delta_chroma_weight[k][i][j]; 250 } 251 } 252 } 253 return MOS_STATUS_SUCCESS; 254 } 255 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,HevcVdencWeightedPred)256 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, HevcVdencWeightedPred) 257 { 258 auto hevcFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 259 ENCODE_CHK_NULL_RETURN(hevcFeature); 260 261 params.log2WeightDenomLuma = params.hevcVp9Log2WeightDenomLuma = m_enabled ? (m_bEnableGPUWeightedPrediction ? 6 : hevcFeature->m_hevcSliceParams->luma_log2_weight_denom) : 0; 262 params.log2WeightDenomChroma = m_enabled ? (m_bEnableGPUWeightedPrediction ? 6 : hevcFeature->m_hevcSliceParams->luma_log2_weight_denom + hevcFeature->m_hevcSliceParams->delta_chroma_log2_weight_denom) : 0; 263 264 return MOS_STATUS_SUCCESS; 265 } 266 } // namespace encode 267