1 /* 2 * Copyright (c) 2021-2023, 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 decode_vvc_reference_frames.cpp 24 //! \brief Defines reference list related logic for vvc decode 25 //! 26 27 #include "decode_vvc_basic_feature.h" 28 #include "decode_utils.h" 29 #include "codec_utilities_next.h" 30 #include "decode_vvc_reference_frames.h" 31 #include "codec_def_decode_vvc.h" 32 33 namespace decode 34 { VvcReferenceFrames()35 VvcReferenceFrames::VvcReferenceFrames() 36 { 37 memset(m_refList, 0, sizeof(m_refList)); 38 } 39 Init(VvcBasicFeature * basicFeature,DecodeAllocator & allocator)40 MOS_STATUS VvcReferenceFrames::Init(VvcBasicFeature *basicFeature, DecodeAllocator& allocator) 41 { 42 DECODE_FUNC_CALL(); 43 44 DECODE_CHK_NULL(basicFeature); 45 m_basicFeature = basicFeature; 46 m_allocator = &allocator; 47 DECODE_CHK_NULL(m_allocator); 48 DECODE_CHK_STATUS( 49 CodecUtilities::CodecHalAllocateDataList((CODEC_REF_LIST_VVC **)m_refList, CODEC_MAX_DPB_NUM_VVC)); 50 51 return MOS_STATUS_SUCCESS; 52 } 53 ~VvcReferenceFrames()54 VvcReferenceFrames::~VvcReferenceFrames() 55 { 56 DECODE_FUNC_CALL(); 57 58 CodecUtilities::CodecHalFreeDataList(m_refList, CODEC_MAX_DPB_NUM_VVC); 59 //m_activeReferenceList.clear(); 60 } 61 UpdatePicture(CodecVvcPicParams & picParams)62 MOS_STATUS VvcReferenceFrames::UpdatePicture(CodecVvcPicParams & picParams) 63 { 64 DECODE_FUNC_CALL(); 65 66 DECODE_CHK_STATUS(UpdateCurFrame(picParams)); 67 DECODE_CHK_STATUS(UpdateUnavailableRefFrames(picParams)); 68 69 return MOS_STATUS_SUCCESS; 70 } 71 GetActiveReferenceList(CodecVvcPicParams & picParams)72 const std::vector<uint8_t> & VvcReferenceFrames::GetActiveReferenceList(CodecVvcPicParams & picParams) 73 { 74 DECODE_FUNC_CALL(); 75 76 m_activeReferenceList.clear(); 77 for (auto i = 0; i < vvcMaxNumRefFrame; i++) 78 { 79 uint8_t frameIdx = picParams.m_refFrameList[i].FrameIdx; 80 if (frameIdx >= CODEC_MAX_DPB_NUM_VVC) 81 { 82 continue; 83 } 84 m_activeReferenceList.push_back(frameIdx); 85 } 86 87 return m_activeReferenceList; 88 } 89 GetReferenceByFrameIndex(uint8_t frameIndex)90 PMOS_RESOURCE VvcReferenceFrames::GetReferenceByFrameIndex(uint8_t frameIndex) 91 { 92 DECODE_FUNC_CALL(); 93 94 if (frameIndex >= CODEC_MAX_DPB_NUM_VVC) 95 { 96 DECODE_ASSERTMESSAGE("Invalid reference frame index"); 97 return nullptr; 98 } 99 100 PCODEC_REF_LIST_VVC ref = m_refList[frameIndex]; 101 102 if (ref == nullptr || m_allocator->ResourceIsNull(&(ref->resRefPic))) 103 { 104 return nullptr; 105 } 106 107 return &(ref->resRefPic); 108 } 109 GetRefAttrByFrameIndex(uint8_t frameIndex,VvcRefFrameAttributes * attributes)110 MOS_STATUS VvcReferenceFrames::GetRefAttrByFrameIndex(uint8_t frameIndex, VvcRefFrameAttributes* attributes) 111 { 112 DECODE_FUNC_CALL(); 113 114 DECODE_CHK_NULL(attributes); 115 116 if (frameIndex >= CODEC_MAX_DPB_NUM_VVC) 117 { 118 DECODE_ASSERTMESSAGE("Invalid reference frame index"); 119 return MOS_STATUS_INVALID_PARAMETER; 120 } 121 122 PCODEC_REF_LIST_VVC ref = m_refList[frameIndex]; 123 124 if (ref == nullptr || m_allocator->ResourceIsNull(&(ref->resRefPic))) 125 { 126 return MOS_STATUS_INVALID_PARAMETER; 127 } 128 129 attributes->m_refscalingwinleftoffset = ref->m_ppsScalingWinLeftOffset; 130 attributes->m_refscalingwinrightoffset = ref->m_ppsScalingWinRightOffset; 131 attributes->m_refscalingwintopoffset = ref->m_ppsScalingWinTopOffset; 132 attributes->m_refscalingwinbottomoffset = ref->m_ppsScalingWinBottomOffset; 133 attributes->m_refpicwidth = ref->m_ppsPicWidthInLumaSamples; 134 attributes->m_refpicheight = ref->m_ppsPicHeightInLumaSamples; 135 attributes->m_currPicScalWinWidthL = ref->m_currPicScalWinWidthL; 136 attributes->m_currPicScalWinHeightL = ref->m_currPicScalWinHeightL; 137 138 return MOS_STATUS_SUCCESS; 139 } 140 GetValidReference()141 PMOS_RESOURCE VvcReferenceFrames::GetValidReference() 142 { 143 DECODE_FUNC_CALL(); 144 145 if (m_basicFeature->m_vvcPicParams == nullptr) 146 { 147 m_validRefFrameIdx = CODEC_MAX_DPB_NUM_VVC; 148 return nullptr; 149 } 150 auto m_picParams = m_basicFeature->m_vvcPicParams; 151 152 for(auto i = 0; i < vvcMaxNumRefFrame; i++) 153 { 154 uint8_t frameIdx = m_picParams->m_refFrameList[i].FrameIdx; 155 if (frameIdx >= CODEC_MAX_DPB_NUM_VVC) 156 { 157 continue; 158 } 159 PMOS_RESOURCE buffer = GetReferenceByFrameIndex(frameIdx); 160 if (buffer != nullptr) 161 { 162 m_validRefFrameIdx = frameIdx; 163 return buffer; 164 } 165 } 166 m_validRefFrameIdx = m_picParams->m_currPic.FrameIdx; 167 168 return &(m_basicFeature->m_destSurface.OsResource); 169 } 170 UpdateCurResource(const PCODEC_REF_LIST_VVC pCurRefList)171 MOS_STATUS VvcReferenceFrames::UpdateCurResource(const PCODEC_REF_LIST_VVC pCurRefList) 172 { 173 DECODE_FUNC_CALL(); 174 DECODE_CHK_NULL(pCurRefList); 175 DECODE_CHK_NULL(m_basicFeature->m_vvcPicParams); 176 auto m_picParams = m_basicFeature->m_vvcPicParams; 177 178 // Overwrite the actual surface height with the coded height and width of the frame 179 // since DPB buffer size may be larger than the YUV data size to put in it 180 m_basicFeature->m_destSurface.dwWidth = m_picParams->m_ppsPicWidthInLumaSamples; 181 m_basicFeature->m_destSurface.dwHeight = m_picParams->m_ppsPicHeightInLumaSamples; 182 183 pCurRefList->resRefPic = m_basicFeature->m_destSurface.OsResource; 184 185 return MOS_STATUS_SUCCESS; 186 } 187 UpdateCurFrame(const CodecVvcPicParams & picParams)188 MOS_STATUS VvcReferenceFrames::UpdateCurFrame(const CodecVvcPicParams & picParams) 189 { 190 DECODE_FUNC_CALL(); 191 192 DECODE_CHK_COND(picParams.m_currPic.FrameIdx >= CODEC_MAX_DPB_NUM_VVC, "Invalid frame index of current frame"); 193 m_currRefList = m_refList[picParams.m_currPic.FrameIdx]; 194 MOS_ZeroMemory(m_currRefList, sizeof(CODEC_REF_LIST_VVC)); 195 196 DECODE_CHK_STATUS(UpdateCurResource(m_currRefList)); 197 198 m_currRefList->m_ppsPicWidthInLumaSamples = picParams.m_ppsPicWidthInLumaSamples; 199 m_currRefList->m_ppsPicHeightInLumaSamples = picParams.m_ppsPicHeightInLumaSamples; 200 m_currRefList->m_ppsScalingWinLeftOffset = picParams.m_ppsScalingWinLeftOffset; 201 m_currRefList->m_ppsScalingWinRightOffset = picParams.m_ppsScalingWinRightOffset; 202 m_currRefList->m_ppsScalingWinTopOffset = picParams.m_ppsScalingWinTopOffset; 203 m_currRefList->m_ppsScalingWinBottomOffset = picParams.m_ppsScalingWinBottomOffset; 204 m_currRefList->m_spsNumSubpicsMinus1 = picParams.m_spsNumSubpicsMinus1; 205 m_currRefList->m_spsHorCollocatedChromaFlag = picParams.m_spsFlags1.m_fields.m_spsChromaHorizontalCollocatedFlag; 206 m_currRefList->m_spsVerCollocatedChromaFlag = picParams.m_spsFlags1.m_fields.m_spsChromaVerticalCollocatedFlag; 207 m_curIsIntra = picParams.m_picMiscFlags.m_fields.m_intraPicFlag; 208 209 //Calc CurrPicScalWinWidthL/CurrPicScalWinHeightL 210 int8_t subWidthC, subHeightC; 211 if (picParams.m_spsChromaFormatIdc == 0 || picParams.m_spsChromaFormatIdc == 3) 212 { 213 subWidthC = 1; 214 subHeightC = 1; 215 } 216 else 217 { 218 subWidthC = 2; 219 subHeightC = (picParams.m_spsChromaFormatIdc == 1) ? 2 : 1; 220 } 221 m_currRefList->m_currPicScalWinWidthL = picParams.m_ppsPicWidthInLumaSamples - subWidthC * (picParams.m_ppsScalingWinRightOffset + picParams.m_ppsScalingWinLeftOffset); 222 m_currRefList->m_currPicScalWinHeightL = picParams.m_ppsPicHeightInLumaSamples - subHeightC * (picParams.m_ppsScalingWinBottomOffset + picParams.m_ppsScalingWinTopOffset); 223 224 return MOS_STATUS_SUCCESS; 225 } 226 UpdateUnavailableRefFrames(const CodecVvcPicParams & picParams)227 MOS_STATUS VvcReferenceFrames::UpdateUnavailableRefFrames(const CodecVvcPicParams & picParams) 228 { 229 DECODE_FUNC_CALL(); 230 231 for (auto i = 0; i < vvcMaxNumRefFrame; i++) 232 { 233 if (picParams.m_refFrameList[i].PicFlags == PICTURE_UNAVAILABLE_FRAME) 234 { 235 236 if (picParams.m_refFrameList[i].FrameIdx >= CODEC_MAX_DPB_NUM_VVC) 237 { 238 continue; 239 } 240 241 PCODEC_REF_LIST_VVC refList = m_refList[picParams.m_refFrameList[i].FrameIdx]; 242 243 refList->resRefPic = m_basicFeature->m_destSurface.OsResource; 244 refList->m_ppsPicWidthInLumaSamples = picParams.m_ppsPicWidthInLumaSamples; 245 refList->m_ppsPicHeightInLumaSamples = picParams.m_ppsPicHeightInLumaSamples; 246 refList->m_ppsScalingWinLeftOffset = picParams.m_ppsScalingWinLeftOffset; 247 refList->m_ppsScalingWinRightOffset = picParams.m_ppsScalingWinRightOffset; 248 refList->m_ppsScalingWinTopOffset = picParams.m_ppsScalingWinTopOffset; 249 refList->m_ppsScalingWinBottomOffset = picParams.m_ppsScalingWinBottomOffset; 250 refList->m_spsNumSubpicsMinus1 = picParams.m_spsNumSubpicsMinus1; 251 refList->m_currPicScalWinWidthL = picParams.m_ppsPicWidthInLumaSamples; 252 refList->m_currPicScalWinHeightL = picParams.m_ppsPicHeightInLumaSamples; 253 } 254 } 255 256 return MOS_STATUS_SUCCESS; 257 } 258 CalcRprConstraintsActiveFlag(uint8_t refFrameIdx,bool & flag)259 MOS_STATUS VvcReferenceFrames::CalcRprConstraintsActiveFlag(uint8_t refFrameIdx, bool &flag) 260 { 261 DECODE_FUNC_CALL(); 262 263 if (refFrameIdx >= CODEC_MAX_DPB_NUM_VVC) 264 { 265 return MOS_STATUS_INVALID_PARAMETER; 266 } 267 268 PCODEC_REF_LIST_VVC ref = m_refList[refFrameIdx]; 269 270 if (ref == nullptr || m_allocator->ResourceIsNull(&(ref->resRefPic))) 271 { 272 return MOS_STATUS_INVALID_PARAMETER; 273 } 274 275 flag = (ref->m_ppsPicHeightInLumaSamples != m_currRefList->m_ppsPicHeightInLumaSamples) || 276 (ref->m_ppsPicWidthInLumaSamples != m_currRefList->m_ppsPicWidthInLumaSamples) || 277 (ref->m_ppsScalingWinTopOffset != m_currRefList->m_ppsScalingWinTopOffset) || 278 (ref->m_ppsScalingWinBottomOffset != m_currRefList->m_ppsScalingWinBottomOffset) || 279 (ref->m_ppsScalingWinLeftOffset != m_currRefList->m_ppsScalingWinLeftOffset) || 280 (ref->m_ppsScalingWinRightOffset != m_currRefList->m_ppsScalingWinRightOffset) || 281 (ref->m_spsNumSubpicsMinus1 != m_currRefList->m_spsNumSubpicsMinus1); 282 283 if (flag && 284 (ref->m_spsHorCollocatedChromaFlag != m_currRefList->m_spsHorCollocatedChromaFlag 285 || ref->m_spsVerCollocatedChromaFlag != m_currRefList->m_spsVerCollocatedChromaFlag)) 286 { 287 return MOS_STATUS_INVALID_PARAMETER; 288 } 289 290 return MOS_STATUS_SUCCESS; 291 } 292 293 294 } // namespace decode 295