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_basic_feature.cpp 24 //! \brief Defines the common interface for decode vvc parameter 25 //! 26 27 #include "decode_vvc_basic_feature.h" 28 #include "decode_utils.h" 29 #include "decode_allocator.h" 30 31 namespace decode 32 { ~VvcBasicFeature()33 VvcBasicFeature::~VvcBasicFeature() { } 34 Init(void * setting)35 MOS_STATUS VvcBasicFeature::Init(void *setting) 36 { 37 DECODE_FUNC_CALL(); 38 39 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL); 40 41 DECODE_CHK_NULL(setting); 42 43 DECODE_CHK_STATUS(DecodeBasicFeature::Init(setting)); 44 CodechalSetting *codecSettings = (CodechalSetting*)setting; 45 m_shortFormatInUse = codecSettings->shortFormatInUse; 46 47 DECODE_CHK_STATUS(m_refFrames.Init(this, *m_allocator)); 48 DECODE_CHK_STATUS(m_mvBuffers.Init(m_hwInterface, *m_allocator, *this, 49 vvcNumInitialMvBuffers)); 50 51 return MOS_STATUS_SUCCESS; 52 } 53 UpdateAPS(void * params)54 MOS_STATUS VvcBasicFeature::UpdateAPS(void *params) 55 { 56 DECODE_FUNC_CALL(); 57 58 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL); 59 60 DECODE_CHK_NULL(params); 61 62 CodechalDecodeParams* decodeParams = (CodechalDecodeParams*)params; 63 64 // ALF APS 65 if (m_vvcPicParams->m_numAlfBuffers > 0 && decodeParams->m_deblockData != nullptr) 66 { 67 uint32_t actualBufNum = decodeParams->m_deblockDataSize / sizeof(CodecVvcAlfData); 68 if (m_vvcPicParams->m_numAlfBuffers > actualBufNum) 69 { 70 DECODE_ASSERTMESSAGE("Received ALF buffer size < claimed buffer size in pic params buffer.\n"); 71 return MOS_STATUS_INVALID_PARAMETER; 72 } 73 74 CodecVvcAlfData* alfData = (CodecVvcAlfData*)decodeParams->m_deblockData; 75 for (uint32_t i = 0; i < actualBufNum; i++) 76 { 77 if (alfData->m_apsAdaptationParameterSetId >= vvcMaxAlfNum) 78 { 79 DECODE_ASSERTMESSAGE("ALF: Invalid APS set ID from App.\n"); 80 return MOS_STATUS_INVALID_PARAMETER; 81 } 82 83 m_concealAlfMask &= ~(1 << alfData->m_apsAdaptationParameterSetId); 84 if (MOS_STATUS_INVALID_PARAMETER == CheckAlfRange(alfData)) 85 { 86 m_concealAlfMask |= (1 << alfData->m_apsAdaptationParameterSetId); 87 } 88 89 MOS_SecureMemcpy(&m_alfApsArray[alfData->m_apsAdaptationParameterSetId], sizeof(CodecVvcAlfData), alfData, sizeof(CodecVvcAlfData)); 90 m_activeAlfMask |= (1 << alfData->m_apsAdaptationParameterSetId); 91 92 alfData++; 93 } 94 95 //calc accumulated valid ALF number 96 m_numAlf = 0; 97 uint8_t alfFlag = m_activeAlfMask; 98 for (auto i = 0; i < vvcMaxAlfNum; i++) 99 { 100 m_numAlf += (alfFlag >> i) & 0x1; 101 } 102 } 103 else if(m_vvcPicParams->m_numAlfBuffers > 0 && decodeParams->m_deblockData == nullptr) 104 { 105 DECODE_ASSERTMESSAGE("Inconsistent between pic params ALF num and actual ALF buffer\n"); 106 return MOS_STATUS_INVALID_PARAMETER; 107 } 108 109 // decide ALF error concealment 110 if(m_concealAlfMask) 111 { 112 DECODE_ASSERTMESSAGE("Error concealed: Disable ALF since out-of-range ALF parameters detected.\n"); 113 m_vvcPicParams->m_spsFlags0.m_fields.m_spsAlfEnabledFlag = 0; 114 m_vvcPicParams->m_spsFlags0.m_fields.m_spsCcalfEnabledFlag = 0; 115 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsAlfInfoInPhFlag = 1; 116 m_vvcPicParams->m_phFlags.m_fields.m_phAlfEnabledFlag = 0; 117 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCbEnabledFlag = 0; 118 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCrEnabledFlag = 0; 119 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCcCbEnabledFlag = 0; 120 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCcCrEnabledFlag = 0; 121 } 122 123 // LMCS APS 124 if (m_vvcPicParams->m_numLmcsBuffers > 0 && decodeParams->m_macroblockParams != nullptr) 125 { 126 if (m_vvcPicParams->m_numLmcsBuffers > decodeParams->m_numMacroblocks) 127 { 128 DECODE_ASSERTMESSAGE("Received LMCS buffer size < claimed buffer size in pic params buffer.\n"); 129 return MOS_STATUS_INVALID_PARAMETER; 130 } 131 132 CodecVvcLmcsData *lmcsData = (CodecVvcLmcsData*)decodeParams->m_macroblockParams; 133 for (uint32_t i = 0; i < decodeParams->m_numMacroblocks; i++) 134 { 135 if (lmcsData->m_apsAdaptationParameterSetId >= vvcMaxLmcsNum) 136 { 137 DECODE_ASSERTMESSAGE("LMCS: Invalid APS set ID from App.\n"); 138 return MOS_STATUS_INVALID_PARAMETER; 139 } 140 MOS_SecureMemcpy(&m_lmcsApsArray[lmcsData->m_apsAdaptationParameterSetId], sizeof(CodecVvcLmcsData), lmcsData, sizeof(CodecVvcLmcsData)); 141 m_activeLmcsMask |= (1 << lmcsData->m_apsAdaptationParameterSetId); 142 m_lmcsReshaperReady &= ~(1 << lmcsData->m_apsAdaptationParameterSetId);//reset the flag to indicate reshape info not derived yet 143 144 lmcsData++; 145 } 146 147 //calc accumulated valid LMCS number 148 m_numLmcs = 0; 149 uint8_t lmcsMask = m_activeLmcsMask; 150 for (auto i = 0; i < vvcMaxLmcsNum; i++) 151 { 152 m_numLmcs += (lmcsMask >> i) & 0x1; 153 } 154 } 155 else if(m_vvcPicParams->m_numLmcsBuffers > 0 && decodeParams->m_macroblockParams == nullptr) 156 { 157 DECODE_ASSERTMESSAGE("Inconsistent between pic params LMCS num and actual LMCS buffer\n"); 158 return MOS_STATUS_INVALID_PARAMETER; 159 } 160 161 // Scaling List APS 162 if (m_vvcPicParams->m_numScalingMatrixBuffers > 0 && decodeParams->m_iqMatrixBuffer != nullptr) 163 { 164 uint32_t actualBufNum = decodeParams->m_iqMatrixSize / sizeof(CodecVvcQmData); 165 if (m_vvcPicParams->m_numScalingMatrixBuffers > actualBufNum) 166 { 167 DECODE_ASSERTMESSAGE("Received Scaling List APS buffer size < claimed buffer size in pic params buffer.\n"); 168 return MOS_STATUS_INVALID_PARAMETER; 169 } 170 171 CodecVvcQmData* scalingListData = (CodecVvcQmData*)decodeParams->m_iqMatrixBuffer; 172 for (uint32_t i = 0; i < actualBufNum; i++) 173 { 174 if (scalingListData->m_apsAdaptationParameterSetId >= vvcMaxScalingMatrixNum) 175 { 176 DECODE_ASSERTMESSAGE("Scaling List: Invalid APS set ID from App.\n"); 177 return MOS_STATUS_INVALID_PARAMETER; 178 } 179 MOS_SecureMemcpy(&m_scalingListArray[scalingListData->m_apsAdaptationParameterSetId], sizeof(CodecVvcQmData), scalingListData, sizeof(CodecVvcQmData)); 180 m_activeScalingListMask |= (1 << scalingListData->m_apsAdaptationParameterSetId); 181 182 scalingListData++; 183 } 184 185 //calc accumulated valid scaling list number 186 m_numScalingList = 0; 187 uint8_t scalingListMask = m_activeScalingListMask; 188 for (auto i = 0; i < vvcMaxScalingMatrixNum; i++) 189 { 190 m_numScalingList += (scalingListMask >> i) & 0x1; 191 } 192 } 193 else if(m_vvcPicParams->m_numScalingMatrixBuffers > 0 && decodeParams->m_iqMatrixBuffer == nullptr) 194 { 195 DECODE_ASSERTMESSAGE("Scaling List APS: Inconsistent between pic params Scaling List num and actual Scaling List buffer\n"); 196 return MOS_STATUS_INVALID_PARAMETER; 197 } 198 199 return MOS_STATUS_SUCCESS; 200 } 201 Update(void * params)202 MOS_STATUS VvcBasicFeature::Update(void *params) 203 { 204 DECODE_FUNC_CALL(); 205 206 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL); 207 208 DECODE_CHK_NULL(params); 209 210 DECODE_CHK_STATUS(DecodeBasicFeature::Update(params)); 211 212 CodechalDecodeParams* decodeParams = (CodechalDecodeParams*)params; 213 m_dataSize = decodeParams->m_dataSize; 214 m_vvcPicParams = static_cast<CodecVvcPicParams*>(decodeParams->m_picParams); 215 DECODE_CHK_NULL(m_vvcPicParams); 216 m_vvcSliceParams = static_cast<CodecVvcSliceParams*>(decodeParams->m_sliceParams); 217 DECODE_CHK_NULL(m_vvcSliceParams); 218 m_curSlice = 0; 219 220 DECODE_CHK_STATUS(SetPictureStructs(decodeParams)); 221 222 // APS update 223 DECODE_CHK_STATUS(UpdateAPS(params)); 224 225 // Partition & RPL update 226 m_subPicParams = static_cast<CodecVvcSubpicParam*>(decodeParams->m_extPicParams); 227 if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && m_vvcPicParams->m_spsNumSubpicsMinus1 > 0) 228 { 229 DECODE_CHK_NULL(m_subPicParams); 230 } 231 m_sliceStructParams = static_cast<CodecVvcSliceStructure*>(decodeParams->m_extSliceParams); 232 if (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag && m_vvcPicParams->m_numSliceStructsMinus1 > 0) 233 { 234 DECODE_CHK_NULL(m_sliceStructParams); 235 } 236 m_rplParams = static_cast<CodecVvcRplStructure*>(decodeParams->m_refParams); 237 m_tileParams = static_cast<CodecVvcTileParam*>(decodeParams->m_tileParams); 238 239 if (m_shortFormatInUse) 240 { 241 DECODE_CHK_STATUS(UpdateNumRefForList()); 242 } 243 244 DECODE_CHK_STATUS(ReconstructPartition(decodeParams)); 245 246 // Error detection and concealment 247 DECODE_CHK_STATUS(ErrorDetectAndConceal()); 248 249 return MOS_STATUS_SUCCESS; 250 } 251 CheckAlfRange(CodecVvcAlfData * alfData)252 MOS_STATUS VvcBasicFeature::CheckAlfRange(CodecVvcAlfData* alfData) 253 { 254 DECODE_FUNC_CALL() 255 256 DECODE_CHK_NULL(alfData); 257 MOS_STATUS res = MOS_STATUS_SUCCESS; 258 259 // Luma 260 if (alfData->m_alfFlags.m_fields.m_alfLumaFilterSignalFlag) 261 { 262 CHECK_RANGE(alfData->m_alfLumaNumFiltersSignalledMinus1, 0, 24); 263 for (auto i = 0; i < 25; i++) 264 { 265 CHECK_RANGE(alfData->m_alfLumaCoeffDeltaIdx[i], 0, 24); 266 } 267 for (auto i = 0; i <= alfData->m_alfLumaNumFiltersSignalledMinus1; i++) 268 { 269 for (auto j = 0; j < 12; j++) 270 { 271 CHECK_RANGE(alfData->m_alfLumaClipIdx[i][j], 0, 3); 272 } 273 } 274 } 275 276 // Chroma 277 if (alfData->m_alfFlags.m_fields.m_alfChromaFilterSignalFlag) 278 { 279 CHECK_RANGE(alfData->m_alfChromaNumAltFiltersMinus1, 0, 7); 280 for (auto i = 0; i <= alfData->m_alfChromaNumAltFiltersMinus1; i++) 281 { 282 for (auto j = 0; j < 6; j++) 283 { 284 CHECK_RANGE(alfData->m_alfChromaClipIdx[i][j], 0, 3); 285 } 286 } 287 } 288 289 // CC Cb 290 if (alfData->m_alfFlags.m_fields.m_alfCcCbFilterSignalFlag) 291 { 292 CHECK_RANGE(alfData->m_alfCcCbFiltersSignalledMinus1, 0, 3); 293 for (auto i = 0; i <= alfData->m_alfCcCbFiltersSignalledMinus1; i++) 294 { 295 for (auto j = 0; j < 7; j++) 296 { 297 CHECK_RANGE(alfData->m_ccAlfApsCoeffCb[i][j], -64, 64); 298 } 299 } 300 } 301 302 // CC Cr 303 if (alfData->m_alfFlags.m_fields.m_alfCcCrFilterSignalFlag) 304 { 305 CHECK_RANGE(alfData->m_alfCcCrFiltersSignalledMinus1, 0, 3); 306 for (auto i = 0; i <= alfData->m_alfCcCrFiltersSignalledMinus1; i++) 307 { 308 for (auto j = 0; j < 7; j++) 309 { 310 CHECK_RANGE(alfData->m_ccAlfApsCoeffCr[i][j], -64, 64); 311 } 312 } 313 } 314 315 return res; 316 } 317 SliceErrorHandlingLF()318 MOS_STATUS VvcBasicFeature::SliceErrorHandlingLF() 319 { 320 DECODE_FUNC_CALL() 321 DECODE_CHK_NULL(m_vvcPicParams); 322 DECODE_CHK_NULL(m_vvcSliceParams); 323 324 m_sliceIdxInOrder.clear(); 325 if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag) 326 { 327 m_sliceIdxInOrder.push_back(0); 328 for (uint16_t i = 1; i < m_numSlices; i++) 329 { 330 CodecVvcSliceParams temp = m_vvcSliceParams[i]; 331 uint16_t startTile = temp.m_shSliceAddress; 332 int16_t j = i - 1; 333 for (; (j >= 0) && (m_vvcSliceParams[m_sliceIdxInOrder[j]].m_shSliceAddress > startTile); j--) {} 334 335 if (j == -1) 336 { 337 m_sliceIdxInOrder.insert(m_sliceIdxInOrder.begin(), i); 338 } 339 else if (m_vvcSliceParams[m_sliceIdxInOrder[j]].m_shSliceAddress == startTile) // duplicated slices detected, keep the one with bigger bitstream size 340 { 341 if (m_vvcSliceParams[m_sliceIdxInOrder[j]].m_sliceBytesInBuffer - m_vvcSliceParams[m_sliceIdxInOrder[j]].m_byteOffsetToSliceData < temp.m_sliceBytesInBuffer - temp.m_byteOffsetToSliceData) 342 { 343 m_sliceIdxInOrder[j] = i; 344 } 345 } 346 else 347 { 348 m_sliceIdxInOrder.insert(m_sliceIdxInOrder.begin() + j + 1, i); 349 } 350 } 351 } 352 else 353 { 354 for (uint16_t i = 0; i < m_numSlices; i++) 355 { 356 uint16_t subPicIdx = GetSubPicIdxFromSubPicId(m_vvcSliceParams[i].m_shSubpicId); 357 uint16_t sliceIdx = 0; 358 359 if(m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && m_vvcPicParams->m_spsNumSubpicsMinus1 > 0) 360 { 361 sliceIdx = m_subPicParams[subPicIdx].m_sliceIdx[m_vvcSliceParams[i].m_shSliceAddress]; 362 } 363 else 364 { 365 DECODE_CHK_COND(subPicIdx != 0, "Error detected: incorrect subpic index\n"); 366 sliceIdx = m_vvcSliceParams[i].m_shSliceAddress; 367 } 368 369 if (!m_sliceDesc[sliceIdx].m_sliceAvailableFlag) 370 { 371 m_sliceDesc[sliceIdx].m_sliceAvailableFlag = true; 372 m_sliceDesc[sliceIdx].m_sliceCtrlIdx = i; 373 } 374 else if(m_vvcSliceParams[m_sliceDesc[sliceIdx].m_sliceCtrlIdx].m_sliceBytesInBuffer - m_vvcSliceParams[m_sliceDesc[sliceIdx].m_sliceCtrlIdx].m_byteOffsetToSliceData < m_vvcSliceParams[i].m_sliceBytesInBuffer - m_vvcSliceParams[i].m_byteOffsetToSliceData) 375 { 376 m_sliceDesc[sliceIdx].m_sliceCtrlIdx = i; 377 } 378 } 379 380 uint16_t numSliceDesc = (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag) ? 381 ((m_vvcPicParams->m_spsNumSubpicsMinus1 == 0 || !m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag) ? 1 : (m_vvcPicParams->m_spsNumSubpicsMinus1 + 1)) : (m_vvcPicParams->m_ppsNumSlicesInPicMinus1 + 1); 382 for (auto i = 0; i < numSliceDesc; i++) 383 { 384 if (m_sliceDesc[i].m_sliceAvailableFlag) 385 { 386 m_sliceIdxInOrder.push_back(m_sliceDesc[i].m_sliceCtrlIdx); 387 } 388 } 389 } 390 391 //Override with valid slice number 392 m_numSlices = m_sliceIdxInOrder.size(); 393 394 return MOS_STATUS_SUCCESS; 395 } 396 CheckProfileCaps()397 MOS_STATUS VvcBasicFeature::CheckProfileCaps() 398 { 399 DECODE_FUNC_CALL(); 400 401 // Check chroma format 402 if (m_vvcPicParams->m_spsChromaFormatIdc != 1 || // 4:2:0 403 !(m_vvcPicParams->m_spsBitdepthMinus8 == 0 || // 8 bit 404 m_vvcPicParams->m_spsBitdepthMinus8 == 2)) // 10 bit 405 { 406 DECODE_ASSERTMESSAGE("Only 4:2:0 8bit and 10bit are supported!"); 407 return MOS_STATUS_INVALID_PARAMETER; 408 } 409 410 return MOS_STATUS_SUCCESS; 411 } 412 ErrorDetectAndConceal()413 MOS_STATUS VvcBasicFeature::ErrorDetectAndConceal() 414 { 415 DECODE_FUNC_CALL() 416 DECODE_CHK_NULL(m_vvcPicParams); 417 418 DECODE_CHK_STATUS(CheckProfileCaps()); 419 420 // Error Detection 421 if (m_vvcPicParams->m_spsLog2CtuSizeMinus5 > 2) 422 { 423 DECODE_ASSERTMESSAGE("pps_log2_ctu_size_minus5 must be less than or equal to 2.\n"); 424 return MOS_STATUS_INVALID_PARAMETER; 425 } 426 427 //slice number limit 428 if (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag && !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag) 429 { 430 if (m_vvcPicParams->m_ppsNumSlicesInPicMinus1 + 1 > vvcMaxSliceNum) 431 { 432 return MOS_STATUS_INVALID_PARAMETER; 433 } 434 } 435 436 //Slice number check 437 int16_t numSlices = 0; 438 if (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag) 439 { 440 numSlices = (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag)? (m_vvcPicParams->m_spsNumSubpicsMinus1 + 1):(m_vvcPicParams->m_ppsNumSlicesInPicMinus1 + 1); 441 if (m_numSlices != numSlices) 442 { 443 DECODE_ASSERTMESSAGE("Rect Slice: Slice number is incorrect.\n"); 444 } 445 } 446 447 //Concealment for bitstream size 448 if (m_numSlices > 0) 449 { 450 CodecVvcSliceParams *lastSlice = m_vvcSliceParams + (m_numSlices - 1); 451 DECODE_CHK_STATUS(SetRequiredBitstreamSize(lastSlice->m_bSNALunitDataLocation + lastSlice->m_sliceBytesInBuffer)); 452 } 453 454 if ((m_vvcPicParams->m_spsFlags0.m_fields.m_spsMaxLumaTransformSize64Flag == 1) && (m_vvcPicParams->m_spsLog2CtuSizeMinus5 == 0)) 455 { 456 DECODE_ASSERTMESSAGE("Error concealed: force sps_max_luma_transform_size_64_flag = 0 when sps_log2_ctu_size_minus5 = 0.\n"); 457 m_vvcPicParams->m_spsFlags0.m_fields.m_spsMaxLumaTransformSize64Flag = 0; 458 } 459 460 if ((m_vvcPicParams->m_spsFlags0.m_fields.m_spsTransformSkipEnabledFlag == 0) && 461 (m_vvcPicParams->m_spsLog2TransformSkipMaxSizeMinus2 > 0 || m_vvcPicParams->m_spsFlags0.m_fields.m_spsBdpcmEnabledFlag > 0)) 462 { 463 DECODE_ASSERTMESSAGE("Error detected: (sps_transform_skip_enabled_flag == 0) && (sps_log2_transform_skip_max_size_minus2 > 0 || sps_bdpcm_enabled_flag >0).\n"); 464 return MOS_STATUS_INVALID_PARAMETER; 465 } 466 467 if ((m_vvcPicParams->m_spsFlags0.m_fields.m_spsMtsEnabledFlag == 0) && 468 (m_vvcPicParams->m_spsFlags0.m_fields.m_spsExplicitMtsIntraEnabledFlag == 1 || m_vvcPicParams->m_spsFlags0.m_fields.m_spsExplicitMtsInterEnabledFlag == 1)) 469 { 470 DECODE_ASSERTMESSAGE("Error detected: (sps_mts_enabled_flag == 0) && (sps_explicit_mts_intra_enabled_flag == 1 || sps_explicit_mts_inter_enabled_flag == 1).\n"); 471 return MOS_STATUS_INVALID_PARAMETER; 472 } 473 474 if ((m_vvcPicParams->m_spsFlags0.m_fields.m_spsAlfEnabledFlag == 0 || m_vvcPicParams->m_spsChromaFormatIdc == 0) && 475 (m_vvcPicParams->m_spsFlags0.m_fields.m_spsCcalfEnabledFlag == 1)) 476 { 477 DECODE_ASSERTMESSAGE("Error detected: (sps_alf_enabled_flag == 0 || sps_chroma_format_idc == 0) && (sps_ccalf_enabled_flag == 1).\n"); 478 return MOS_STATUS_INVALID_PARAMETER; 479 } 480 481 if (m_shortFormatInUse && (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRefWraparoundEnabledFlag) && m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag) 482 { 483 uint16_t picWidthMaxInCtus = MOS_ROUNDUP_SHIFT(m_vvcPicParams->m_spsPicWidthMaxInLumaSamples, m_vvcPicParams->m_spsLog2CtuSizeMinus5 + 5); 484 uint16_t picWidthInCtus = MOS_ROUNDUP_SHIFT(m_vvcPicParams->m_ppsPicWidthInLumaSamples, m_vvcPicParams->m_spsLog2CtuSizeMinus5 + 5); 485 if (m_vvcPicParams->m_spsNumSubpicsMinus1 > 0) 486 { 487 for (int16_t sp = 0; sp < m_vvcPicParams->m_spsNumSubpicsMinus1 + 1; sp++) 488 { 489 if ((m_subPicParams[sp].m_spsSubpicWidthMinus1 + 1 != picWidthMaxInCtus) && 490 m_subPicParams[sp].m_subPicFlags.m_fields.m_spsSubpicTreatedAsPicFlag) 491 { 492 DECODE_ASSERTMESSAGE("Error detected: (sps_ref_wraparound_enabled_flag == 1) && (at least one SubPic with sps_subpic_treated_as_pic_flag[i] == 1 && sps_subpic_width_minus1[i] + 1 != (sps_pic_width_max_in_luma_samples + CtbSizeY - 1 ) >> CtbLog2SizeY )).\n"); 493 return MOS_STATUS_INVALID_PARAMETER; 494 } 495 } 496 } 497 else 498 { 499 if (picWidthInCtus != picWidthMaxInCtus) 500 { 501 DECODE_ASSERTMESSAGE("Error detected: (sps_ref_wraparound_enabled_flag == 1) && (at least one SubPic with sps_subpic_treated_as_pic_flag[i] == 1 && sps_subpic_width_minus1[i] + 1 != (sps_pic_width_max_in_luma_samples + CtbSizeY - 1 ) >> CtbLog2SizeY )).\n"); 502 return MOS_STATUS_INVALID_PARAMETER; 503 } 504 } 505 } 506 507 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsTemporalMvpEnabledFlag && m_vvcPicParams->m_spsFlags1.m_fields.m_spsSbtmvpEnabledFlag) 508 { 509 DECODE_ASSERTMESSAGE("Error detected: sps_temporal_mvp_enabled_flag == 0 && sps_sbtmvp_enabled_flag == 1.\n"); 510 return MOS_STATUS_INVALID_PARAMETER; 511 } 512 513 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsBdofEnabledFlag && m_vvcPicParams->m_spsFlags1.m_fields.m_spsBdofControlPresentInPhFlag) 514 { 515 DECODE_ASSERTMESSAGE("Error detected: sps_bdof_enabled_flag == 0 && sps_bdof_control_present_in_ph_flag == 1.\n"); 516 return MOS_STATUS_INVALID_PARAMETER; 517 } 518 519 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsDmvrEnabledFlag && m_vvcPicParams->m_spsFlags1.m_fields.m_spsDmvrControlPresentInPhFlag) 520 { 521 DECODE_ASSERTMESSAGE("Error detected: sps_dmvr_enabled_flag == 0 && sps_dmvr_control_present_in_ph_flag == 1.\n"); 522 return MOS_STATUS_INVALID_PARAMETER; 523 } 524 525 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsMmvdEnabledFlag && m_vvcPicParams->m_spsFlags1.m_fields.m_spsMmvdFullpelOnlyEnabledFlag) 526 { 527 DECODE_ASSERTMESSAGE("Error detected: (sps_mmvd_enabled_flag == 0) && (sps_mmvd_fullpel_only_enabled_flag == 1).\n"); 528 return MOS_STATUS_INVALID_PARAMETER; 529 } 530 531 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsAffineEnabledFlag && 532 (m_vvcPicParams->m_spsFiveMinusMaxNumSubblockMergeCand != 0 || 533 m_vvcPicParams->m_spsFlags1.m_fields.m_sps6paramAffineEnabledFlag != 0 || 534 m_vvcPicParams->m_spsFlags1.m_fields.m_spsAffineAmvrEnabledFlag == 1 || 535 m_vvcPicParams->m_spsFlags1.m_fields.m_spsAffineProfEnabledFlag == 1 || 536 m_vvcPicParams->m_spsFlags1.m_fields.m_spsProfControlPresentInPhFlag == 1)) 537 { 538 DECODE_ASSERTMESSAGE("Error detected: sps_affine_enabled_flag == 0 && (sps_five_minus_max_num_subblock_merge_cand != 0 || sps_6param_affine_enabled_flag != 0 || sps_affine_amvr_enabled_flag == 1 || sps_affine_prof_enabled_flag == 1 || sps_prof_control_present_in_ph_flag == 1).\n"); 539 return MOS_STATUS_INVALID_PARAMETER; 540 } 541 542 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsAmvrEnabledFlag && m_vvcPicParams->m_spsFlags1.m_fields.m_spsAffineAmvrEnabledFlag == 1) 543 { 544 DECODE_ASSERTMESSAGE("Error detected: sps_amvr_enabled_flag == 0 && sps_affine_amvr_enabled_flag == 1.\n"); 545 return MOS_STATUS_INVALID_PARAMETER; 546 } 547 548 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsAffineProfEnabledFlag && m_vvcPicParams->m_spsFlags1.m_fields.m_spsProfControlPresentInPhFlag) 549 { 550 DECODE_ASSERTMESSAGE("Error detected: sps_affine_prof_enabled_flag == 0 && sps_prof_control_present_in_ph_flag == 1.\n"); 551 return MOS_STATUS_INVALID_PARAMETER; 552 } 553 554 if (m_vvcPicParams->m_spsSixMinusMaxNumMergeCand == 5 && m_vvcPicParams->m_spsFlags1.m_fields.m_spsGpmEnabledFlag) 555 { 556 DECODE_ASSERTMESSAGE("Error detected: sps_six_minus_max_num_merge_cand == 5 && sps_gpm_enabled_flag == 1.\n"); 557 return MOS_STATUS_INVALID_PARAMETER; 558 } 559 560 if (m_vvcPicParams->m_spsChromaFormatIdc == 0 && m_vvcPicParams->m_spsFlags1.m_fields.m_spsCclmEnabledFlag) 561 { 562 DECODE_ASSERTMESSAGE("Error detected: sps_chroma_format_idc == 0 && sps_cclm_enabled_flag == 1.\n"); 563 return MOS_STATUS_INVALID_PARAMETER; 564 } 565 566 if (m_vvcPicParams->m_spsChromaFormatIdc != 1 && 567 (m_vvcPicParams->m_spsFlags1.m_fields.m_spsChromaHorizontalCollocatedFlag || 568 m_vvcPicParams->m_spsFlags1.m_fields.m_spsChromaVerticalCollocatedFlag)) 569 { 570 DECODE_ASSERTMESSAGE("Error detected: (sps_chroma_format_idc != 1) && ((sps_chroma_horizontal_collocated_flag != 0) || (sps_chroma_vertical_collocated_flag!=0)).\n"); 571 return MOS_STATUS_INVALID_PARAMETER; 572 } 573 574 if ((m_vvcPicParams->m_spsChromaFormatIdc != 3 || m_vvcPicParams->m_spsFlags0.m_fields.m_spsMaxLumaTransformSize64Flag) && 575 m_vvcPicParams->m_spsFlags2.m_fields.m_spsActEnabledFlag != 0) 576 { 577 DECODE_ASSERTMESSAGE("Error detected: (sps_chroma_format_idc != 3 || sps_max_luma_transform_size_64_flag ==1) && (sps_act_enabled_flag != 0).\n"); 578 return MOS_STATUS_INVALID_PARAMETER; 579 } 580 581 if (!m_vvcPicParams->m_spsFlags0.m_fields.m_spsTransformSkipEnabledFlag && 582 !m_vvcPicParams->m_spsFlags2.m_fields.m_spsPaletteEnabledFlag && 583 m_vvcPicParams->m_spsMinQpPrimeTs == 1) 584 { 585 DECODE_ASSERTMESSAGE("Error detected: sps_transform_skip_enabled_flag ==0 && sps_palette_enabled_flag == 0 && sps_min_qp_prime_ts == 1.\n"); 586 return MOS_STATUS_INVALID_PARAMETER; 587 } 588 589 if ((!m_vvcPicParams->m_spsFlags2.m_fields.m_spsActEnabledFlag || !m_vvcPicParams->m_spsFlags2.m_fields.m_spsExplicitScalingListEnabledFlag) && 590 m_vvcPicParams->m_spsFlags2.m_fields.m_spsScalingMatrixForAlternativeColourSpaceDisabledFlag) 591 { 592 DECODE_ASSERTMESSAGE("Error detected: (sps_act_enabled_flag == 0 || sps_explicit_scaling_list_enabled_flag == 0 ) && sps_scaling_matrix_for_alternative_colour_space_disabled_flag == 1.\n"); 593 return MOS_STATUS_INVALID_PARAMETER; 594 } 595 596 if (!m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesEnabledFlag && m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesPresentFlag) 597 { 598 DECODE_ASSERTMESSAGE("Error detected: sps_virtual_boundaries_enabled_flag ==0 && sps_virtual_boundaries_present_flag==1.\n"); 599 return MOS_STATUS_INVALID_PARAMETER; 600 } 601 602 if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && 603 m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesEnabledFlag && 604 !m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesPresentFlag) 605 { 606 DECODE_ASSERTMESSAGE("Error concealed: force sps_virtual_boundaries_enabled_flag from 1 to 0.\n"); 607 m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesEnabledFlag = 0; 608 } 609 610 if (!m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesPresentFlag && m_vvcPicParams->m_spsNumVerVirtualBoundaries > 0) 611 { 612 DECODE_ASSERTMESSAGE("Error detected: sps_virtual_boundaries_present_flag == 0 && sps_num_ver_virtual_boundaries > 0.\n"); 613 return MOS_STATUS_INVALID_PARAMETER; 614 } 615 616 if (m_shortFormatInUse && (m_vvcPicParams->m_ppsPicWidthInLumaSamples != m_vvcPicParams->m_spsPicWidthMaxInLumaSamples || 617 m_vvcPicParams->m_ppsPicHeightInLumaSamples != m_vvcPicParams->m_spsPicHeightMaxInLumaSamples)) 618 { 619 if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag) 620 { 621 DECODE_ASSERTMESSAGE("Error detected: (pps_pic_width_in_luma_samples != sps_pic_width_max_in_luma_samples || pps_pic_height_in_luma_samples != sps_pic_height_max_in_luma_samples) && (sps_virtual_boundaries_present_flag == 1 || sps_subpic_info_present_flag == 1).\n"); 622 return MOS_STATUS_INVALID_PARAMETER; 623 } 624 625 if (m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesPresentFlag) 626 { 627 DECODE_ASSERTMESSAGE("Error concealed: force sps_virtual_boundaries_present_flag from 1 to 0 when (pps_pic_width_in_luma_samples != sps_pic_width_max_in_luma_samples || pps_pic_height_in_luma_samples != sps_pic_height_max_in_luma_samples).\n"); 628 m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesEnabledFlag = 0; 629 } 630 } 631 632 if (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRefWraparoundEnabledFlag) 633 { 634 if ((1 << (m_vvcPicParams->m_spsLog2CtuSizeMinus5 + 3 - m_vvcPicParams->m_spsLog2MinLumaCodingBlockSizeMinus2)) > ((m_vvcPicParams->m_ppsPicWidthInLumaSamples >> (m_vvcPicParams->m_spsLog2MinLumaCodingBlockSizeMinus2 + 2)) - 1)) 635 { 636 DECODE_ASSERTMESSAGE("Error detected: pps_ref_wraparound_enabled_flag == 1 && ( CtbSizeY / MinCbSizeY + 1 ) > ( pps_pic_width_in_luma_samples / MinCbSizeY - 1 ).\n"); 637 return MOS_STATUS_INVALID_PARAMETER; 638 } 639 } 640 641 if (!m_shortFormatInUse) 642 { 643 // Scaling Window 644 int8_t subWidthC = (m_vvcPicParams->m_spsChromaFormatIdc == 0 || m_vvcPicParams->m_spsChromaFormatIdc == 3) ? 1 : 2; 645 int8_t subHeightC = (m_vvcPicParams->m_spsChromaFormatIdc == 0 || m_vvcPicParams->m_spsChromaFormatIdc == 3) ? 1 : ((m_vvcPicParams->m_spsChromaFormatIdc == 1) ? 2 : 1); 646 647 int32_t value1 = subWidthC * m_vvcPicParams->m_ppsScalingWinLeftOffset; 648 int32_t value2 = subWidthC * m_vvcPicParams->m_ppsScalingWinRightOffset; 649 int32_t min = -15 * m_vvcPicParams->m_ppsPicWidthInLumaSamples; 650 int32_t max = m_vvcPicParams->m_ppsPicWidthInLumaSamples; 651 bool scalWinOutOfHorRange = false; 652 653 if ((value1 < min || value1 >= max) || 654 (value2 < min || value2 >= max) || 655 (value1 + value2 < min || value1 + value2 >= max)) 656 { 657 scalWinOutOfHorRange = true; 658 } 659 660 value1 = subHeightC * m_vvcPicParams->m_ppsScalingWinTopOffset; 661 value2 = subHeightC * m_vvcPicParams->m_ppsScalingWinBottomOffset; 662 min = -15 * m_vvcPicParams->m_ppsPicHeightInLumaSamples; 663 max = m_vvcPicParams->m_ppsPicHeightInLumaSamples; 664 bool scalWinOutOfVerRange = false; 665 666 if ((value1 < min || value1 >= max) || 667 (value2 < min || value2 >= max) || 668 (value1 + value2 < min || value1 + value2 >= max)) 669 { 670 scalWinOutOfVerRange = true; 671 } 672 673 VvcRefFrameAttributes curFrameAttr; 674 DECODE_CHK_STATUS(m_refFrames.GetRefAttrByFrameIndex( 675 m_vvcPicParams->m_currPic.FrameIdx, 676 &curFrameAttr)); 677 678 for (uint32_t slc = 0; slc < m_numSlices; slc++) 679 { 680 CodecVvcSliceParams* curSliceParams = &m_vvcSliceParams[slc]; 681 if (curSliceParams->m_shSliceType != vvcSliceI) 682 { 683 if (scalWinOutOfHorRange == true) 684 { 685 DECODE_ASSERTMESSAGE("Error detected: pps_scaling_win_left_offset or pps_scaling_win_right_offset out of range.\n"); 686 return MOS_STATUS_INVALID_PARAMETER; 687 } 688 if (scalWinOutOfVerRange == true) 689 { 690 DECODE_ASSERTMESSAGE("Error detected: pps_scaling_win_top_offset or pps_scaling_win_bottom_offset out of range.\n"); 691 return MOS_STATUS_INVALID_PARAMETER; 692 } 693 694 for (auto i = 0; i < 2; i++) 695 { 696 for (auto j = 0; j < curSliceParams->m_numRefIdxActive[i]; j++) 697 { 698 uint8_t refPicIdx = curSliceParams->m_refPicList[i][j].FrameIdx; 699 if (refPicIdx < vvcMaxNumRefFrame) 700 { 701 VvcRefFrameAttributes refFrameAttr; 702 uint8_t refFrameIdx; 703 if (m_vvcPicParams->m_refFrameList[refPicIdx].PicFlags != PICTURE_INVALID) 704 { 705 refFrameIdx = m_vvcPicParams->m_refFrameList[refPicIdx].FrameIdx; 706 DECODE_CHK_STATUS(m_refFrames.GetRefAttrByFrameIndex( 707 refFrameIdx, 708 &refFrameAttr)); 709 710 if (((curFrameAttr.m_currPicScalWinWidthL << 1) < refFrameAttr.m_currPicScalWinWidthL) || 711 ((curFrameAttr.m_currPicScalWinHeightL << 1) < refFrameAttr.m_currPicScalWinHeightL) || 712 (curFrameAttr.m_currPicScalWinWidthL > (refFrameAttr.m_currPicScalWinWidthL << 3)) || 713 (curFrameAttr.m_currPicScalWinHeightL > (refFrameAttr.m_currPicScalWinHeightL << 3))) 714 { 715 DECODE_ASSERTMESSAGE("Error detected: current frame's scaling window width/height out of range against ref frame.\n"); 716 return MOS_STATUS_INVALID_PARAMETER; 717 } 718 } 719 } 720 } 721 } 722 } 723 } 724 } 725 if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag) 726 { 727 DECODE_ASSERTMESSAGE("Error detected: sps_subpic_info_present_flag == 1 && pps_rect_slice_flag == 0.\n"); 728 return MOS_STATUS_INVALID_PARAMETER; 729 } 730 731 if (m_shortFormatInUse && m_vvcPicParams->m_spsChromaFormatIdc == 0 && m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag) 732 { 733 DECODE_ASSERTMESSAGE("Error detected: sps_chroma_format_idc == 0 && pps_chroma_tool_offsets_present_flag == 1.\n"); 734 return MOS_STATUS_INVALID_PARAMETER; 735 } 736 737 if (m_shortFormatInUse && (m_vvcPicParams->m_spsChromaFormatIdc == 0 || !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag) && 738 (m_vvcPicParams->m_ppsCbQpOffset != 0 || 739 m_vvcPicParams->m_ppsCrQpOffset != 0 || 740 m_vvcPicParams->m_ppsJointCbcrQpOffsetValue != 0 || 741 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSliceChromaQpOffsetsPresentFlag != 0 || 742 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsCuChromaQpOffsetListEnabledFlag != 0)) 743 { 744 DECODE_ASSERTMESSAGE("Error concealed: force chroma qp offsets/flags to 0 for (sps_chroma_format_idc == 0 || pps_chroma_tool_offsets_present_flag == 0).\n"); 745 m_vvcPicParams->m_ppsCbQpOffset = 0; 746 m_vvcPicParams->m_ppsCrQpOffset = 0; 747 m_vvcPicParams->m_ppsJointCbcrQpOffsetValue = 0; 748 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSliceChromaQpOffsetsPresentFlag = 0; 749 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsCuChromaQpOffsetListEnabledFlag = 0; 750 } 751 752 if (m_shortFormatInUse && !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag) 753 { 754 for (auto i = 0; i < 6; i++) 755 { 756 if (m_vvcPicParams->m_ppsJointCbcrQpOffsetList[i] != 0) 757 { 758 DECODE_ASSERTMESSAGE("Error concealed: force pps_joint_cbcr_qp_offset_list[i] to 0 since pps_chroma_tool_offsets_present_flag == 0.\n"); 759 m_vvcPicParams->m_ppsJointCbcrQpOffsetList[i] = 0; 760 } 761 } 762 } 763 764 bool partitionFlag = ((m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag && m_vvcPicParams->m_spsNumSubpicsMinus1 > 0) || 765 (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag && m_vvcPicParams->m_ppsNumSlicesInPicMinus1 > 0) || 766 m_tileRows > 0 || m_tileCols > 0 ); 767 if ((!partitionFlag || (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsDeblockingFilterOverrideEnabledFlag == 0)) && 768 (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsDbfInfoInPhFlag == 1)) 769 { 770 DECODE_ASSERTMESSAGE("Error concealed: force pps_dbf_info_in_ph_flag to 0 when (!pps_no_pic_partition_flag && pps_deblocking_filter_override_enabled_flag) is false.\n"); 771 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsDbfInfoInPhFlag = 0; 772 } 773 774 if (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsDeblockingFilterDisabledFlag && 775 (m_vvcPicParams->m_ppsLumaBetaOffsetDiv2 != 0 || m_vvcPicParams->m_ppsLumaTcOffsetDiv2 != 0)) 776 { 777 DECODE_ASSERTMESSAGE("Error concealed: force luma_beta_offset_div2 and luma_tc_offset_div2 to 0 when pps_deblocking_filter_disabled_flag is true.\n"); 778 m_vvcPicParams->m_ppsLumaBetaOffsetDiv2 = 0; 779 m_vvcPicParams->m_ppsLumaTcOffsetDiv2 = 0; 780 } 781 782 if (m_shortFormatInUse && !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag && 783 (m_vvcPicParams->m_phCbBetaOffsetDiv2 != m_vvcPicParams->m_phLumaBetaOffsetDiv2 || 784 m_vvcPicParams->m_phCbTcOffsetDiv2 != m_vvcPicParams->m_phLumaTcOffsetDiv2 || 785 m_vvcPicParams->m_phCrBetaOffsetDiv2 != m_vvcPicParams->m_phLumaBetaOffsetDiv2 || 786 m_vvcPicParams->m_phCrTcOffsetDiv2 != m_vvcPicParams->m_phLumaTcOffsetDiv2)) 787 { 788 DECODE_ASSERTMESSAGE("Error concealed: force chroma beta/tc offsets to the same syntax of luma when pps_chroma_tool_offsets_present_flag is 0.\n"); 789 m_vvcPicParams->m_phCbBetaOffsetDiv2 = m_vvcPicParams->m_phLumaBetaOffsetDiv2; 790 m_vvcPicParams->m_phCbTcOffsetDiv2 = m_vvcPicParams->m_phLumaTcOffsetDiv2; 791 m_vvcPicParams->m_phCrBetaOffsetDiv2 = m_vvcPicParams->m_phLumaBetaOffsetDiv2; 792 m_vvcPicParams->m_phCrTcOffsetDiv2 = m_vvcPicParams->m_phLumaTcOffsetDiv2; 793 } 794 795 if (m_shortFormatInUse && ((!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsWeightedPredFlag && !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsWeightedBipredFlag) || 796 !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRplInfoInPhFlag) && m_vvcPicParams->m_ppsFlags.m_fields.m_ppsWpInfoInPhFlag) 797 { 798 DECODE_ASSERTMESSAGE("Error concealed: force pps_wp_info_in_ph_flag = 0 when ((pps_weighted_pred_flag == 0 && pps_weighted_bipred_flag ==0) || pps_rpl_info_in_ph_flag == 0 ).\n"); 799 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsWpInfoInPhFlag = 0; 800 } 801 802 if ((!m_vvcPicParams->m_spsFlags0.m_fields.m_spsAlfEnabledFlag || 803 !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsAlfInfoInPhFlag) && 804 m_vvcPicParams->m_phFlags.m_fields.m_phAlfEnabledFlag) 805 { 806 DECODE_ASSERTMESSAGE("Error concealed: force ph_alf_enabled_flag = 0 when (sps_alf_enabled_flag == 0 || pps_alf_info_in_ph_flag == 0) is true\n"); 807 m_vvcPicParams->m_phFlags.m_fields.m_phAlfEnabledFlag = 0; 808 } 809 810 if (!m_vvcPicParams->m_spsFlags0.m_fields.m_spsCcalfEnabledFlag) 811 { 812 for (auto i = 0; i < vvcMaxAlfNum; i++) 813 { 814 if (m_activeAlfMask & (1 << i)) 815 { 816 if (m_alfApsArray[i].m_alfFlags.m_fields.m_alfCcCbFilterSignalFlag || 817 m_alfApsArray[i].m_alfFlags.m_fields.m_alfCcCrFilterSignalFlag) 818 { 819 DECODE_ASSERTMESSAGE("Error concealed: force alf_cc_cb_filter_signal_flag = 0, alf_cc_cr_filter_signal_flag = 0 when sps_ccalf_enabled_flag is 0\n"); 820 m_alfApsArray[i].m_alfFlags.m_fields.m_alfCcCbFilterSignalFlag = 0; 821 m_alfApsArray[i].m_alfFlags.m_fields.m_alfCcCrFilterSignalFlag = 0; 822 } 823 } 824 } 825 } 826 827 if (!m_vvcPicParams->m_phFlags.m_fields.m_phAlfEnabledFlag && 828 (m_vvcPicParams->m_phFlags.m_fields.m_phAlfCbEnabledFlag || 829 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCrEnabledFlag)) 830 { 831 DECODE_ASSERTMESSAGE("Error concealed: force ph_alf_cb_enabled_flag = 0, ph_alf_cr_enabled_flag = 0 when ph_alf_enabled_flag = 0.\n"); 832 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCbEnabledFlag = 0; 833 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCrEnabledFlag = 0; 834 } 835 836 if (!m_vvcPicParams->m_spsFlags0.m_fields.m_spsCcalfEnabledFlag && 837 (m_vvcPicParams->m_phFlags.m_fields.m_phAlfCcCbEnabledFlag || 838 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCcCrEnabledFlag)) 839 { 840 DECODE_ASSERTMESSAGE("Error concealed: force ph_alf_cc_cb_enabled_flag = 0, ph_alf_cc_cr_enabled_flag = 0 when sps_ccalf_enabled_flag = 0.\n"); 841 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCcCbEnabledFlag = 0; 842 m_vvcPicParams->m_phFlags.m_fields.m_phAlfCcCrEnabledFlag = 0; 843 } 844 845 if (!m_vvcPicParams->m_spsFlags0.m_fields.m_spsLmcsEnabledFlag && m_vvcPicParams->m_phFlags.m_fields.m_phLmcsEnabledFlag) 846 { 847 DECODE_ASSERTMESSAGE("Error concealed: force ph_lmcs_enabled_flag = 0 when sps_lmcs_enabled_flag = 0.\n"); 848 m_vvcPicParams->m_phFlags.m_fields.m_phLmcsEnabledFlag = 0; 849 } 850 851 if (!m_vvcPicParams->m_phFlags.m_fields.m_phLmcsEnabledFlag && m_vvcPicParams->m_phFlags.m_fields.m_phChromaResidualScaleFlag) 852 { 853 DECODE_ASSERTMESSAGE("Error concealed: force ph_chroma_residual_scale_flag = 0 when ph_lmcs_enabled_flag = 0.\n"); 854 m_vvcPicParams->m_phFlags.m_fields.m_phChromaResidualScaleFlag = 0; 855 } 856 857 if (!m_vvcPicParams->m_spsFlags2.m_fields.m_spsExplicitScalingListEnabledFlag && 858 m_vvcPicParams->m_phFlags.m_fields.m_phExplicitScalingListEnabledFlag) 859 { 860 DECODE_ASSERTMESSAGE("Error concealed: force ph_explicit_scaling_list_enabled_flag = 0 when sps_explicit_scaling_list_enabled_flag = 0.\n"); 861 m_vvcPicParams->m_phFlags.m_fields.m_phExplicitScalingListEnabledFlag = 0; 862 } 863 864 if ((!m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesEnabledFlag || 865 m_vvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesPresentFlag) && 866 m_vvcPicParams->m_phFlags.m_fields.m_phVirtualBoundariesPresentFlag) 867 { 868 DECODE_ASSERTMESSAGE("Error concealed: force ph_virtual_boundaries_present_flag = 0 when (sps_virtual_boundaries_enabled_flag == 0 || sps_virtual_boundaries_present_flag == 1) is true.\n"); 869 m_vvcPicParams->m_phFlags.m_fields.m_phVirtualBoundariesPresentFlag = 0; 870 } 871 872 if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsCuQpDeltaEnabledFlag && 873 m_vvcPicParams->m_phCuQpDeltaSubdivIntraSlice != 0) 874 { 875 DECODE_ASSERTMESSAGE("Error concealed: force ph_cu_qp_delta_subdiv_intra_slice = 0 when pps_cu_qp_delta_enabled_flag is 0.\n"); 876 m_vvcPicParams->m_phCuQpDeltaSubdivIntraSlice = 0; 877 } 878 879 if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsCuChromaQpOffsetListEnabledFlag && 880 m_vvcPicParams->m_phCuChromaQpOffsetSubdivIntraSlice != 0) 881 { 882 DECODE_ASSERTMESSAGE("Error concealed: force ph_cu_chroma_qp_offset_subdiv_intra_slice = 0 when pps_cu_chroma_qp_offset_list_enabled_flag is 0.\n"); 883 m_vvcPicParams->m_phCuChromaQpOffsetSubdivIntraSlice = 0; 884 } 885 886 if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsCuQpDeltaEnabledFlag && 887 m_vvcPicParams->m_phCuQpDeltaSubdivInterSlice != 0) 888 { 889 DECODE_ASSERTMESSAGE("Error concealed: force ph_cu_qp_delta_subdiv_inter_slice = 0 when pps_cu_qp_delta_enabled_flag is 0.\n"); 890 m_vvcPicParams->m_phCuQpDeltaSubdivInterSlice = 0; 891 } 892 893 if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsCuChromaQpOffsetListEnabledFlag && 894 m_vvcPicParams->m_phCuChromaQpOffsetSubdivInterSlice != 0) 895 { 896 DECODE_ASSERTMESSAGE("Error concealed: force ph_cu_chroma_qp_offset_subdiv_inter_slice = 0 when pps_cu_chroma_qp_offset_list_enabled_flag is 0.\n"); 897 m_vvcPicParams->m_phCuChromaQpOffsetSubdivInterSlice = 0; 898 } 899 900 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsTemporalMvpEnabledFlag && 901 m_vvcPicParams->m_phFlags.m_fields.m_phTemporalMvpEnabledFlag) 902 { 903 DECODE_ASSERTMESSAGE("Error concealed: force ph_temporal_mvp_enabled_flag = 0 when sps_temporal_mvp_enabled_flag is 0.\n"); 904 m_vvcPicParams->m_phFlags.m_fields.m_phTemporalMvpEnabledFlag = 0; 905 } 906 907 if (m_vvcPicParams->m_phFlags.m_fields.m_phTemporalMvpEnabledFlag == 1) 908 { 909 VvcRefFrameAttributes curFrameAttr; 910 DECODE_CHK_STATUS(m_refFrames.GetRefAttrByFrameIndex( 911 m_vvcPicParams->m_currPic.FrameIdx, 912 &curFrameAttr)); 913 914 bool allDiffFlag = true; 915 uint8_t frameIdx = 0; 916 VvcRefFrameAttributes refFrameAttr; 917 for (uint8_t i = 0; i < vvcMaxNumRefFrame; i++) 918 { 919 if (m_vvcPicParams->m_refFrameList[i].PicFlags != PICTURE_INVALID) 920 { 921 frameIdx = m_vvcPicParams->m_refFrameList[i].FrameIdx; 922 DECODE_CHK_STATUS(m_refFrames.GetRefAttrByFrameIndex( 923 frameIdx, 924 &refFrameAttr)); 925 926 allDiffFlag &= (curFrameAttr.m_refpicwidth != refFrameAttr.m_refpicwidth) || 927 (curFrameAttr.m_refpicheight != refFrameAttr.m_refpicheight) || 928 (curFrameAttr.m_refscalingwinbottomoffset != refFrameAttr.m_refscalingwinbottomoffset) || 929 (curFrameAttr.m_refscalingwintopoffset != refFrameAttr.m_refscalingwintopoffset) || 930 (curFrameAttr.m_refscalingwinleftoffset != refFrameAttr.m_refscalingwinleftoffset) || 931 (curFrameAttr.m_refscalingwinrightoffset != refFrameAttr.m_refscalingwinrightoffset); 932 933 if (!allDiffFlag) 934 { 935 DECODE_NORMALMESSAGE("Found a ref pic in the DPB has the same spatial resolution and the same scaling window offsets as the current picture.\n"); 936 break; 937 } 938 } 939 } 940 941 if (allDiffFlag) 942 { 943 DECODE_ASSERTMESSAGE("Error concealed: force ph_temporal_mvp_enabled_flag = 0 if no reference picture in the DPB has the same spatial resolution and the same scaling window offsets as the current picture.\n"); 944 m_vvcPicParams->m_phFlags.m_fields.m_phTemporalMvpEnabledFlag = 0; 945 } 946 } 947 948 if (m_shortFormatInUse && m_vvcPicParams->m_phFlags.m_fields.m_phInterSliceAllowedFlag && m_vvcPicParams->m_phFlags.m_fields.m_phTemporalMvpEnabledFlag && 949 m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRplInfoInPhFlag && 950 !m_vvcPicParams->m_phFlags.m_fields.m_numRefEntries1RplIdx1LargerThan0 && 951 !m_vvcPicParams->m_phFlags.m_fields.m_phCollocatedFromL0Flag) 952 { 953 DECODE_ASSERTMESSAGE("Error detected: ph_collocated_from_l0_flag = 0 when (ph_temporal_mvp_enabled_flag == 1 && pps_rpl_info_in_ph_flag == 1 && num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] == 0) is true.\n"); 954 return MOS_STATUS_INVALID_PARAMETER; 955 } 956 957 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsMmvdFullpelOnlyEnabledFlag && 958 m_vvcPicParams->m_phFlags.m_fields.m_phMmvdFullpelOnlyFlag) 959 { 960 DECODE_ASSERTMESSAGE("Error concealed: force ph_mmvd_fullpel_only_flag = 0 when sps_mmvd_fullpel_only_enabled_flag is 0.\n"); 961 m_vvcPicParams->m_phFlags.m_fields.m_phMmvdFullpelOnlyFlag = 0; 962 } 963 964 uint32_t bdofDisabledFlag = m_vvcPicParams->m_spsFlags1.m_fields.m_spsBdofControlPresentInPhFlag ? 1 : (1 - m_vvcPicParams->m_spsFlags1.m_fields.m_spsBdofEnabledFlag); 965 uint32_t dmvrDisabledFlag = m_vvcPicParams->m_spsFlags1.m_fields.m_spsDmvrControlPresentInPhFlag ? 1 : (1-m_vvcPicParams->m_spsFlags1.m_fields.m_spsDmvrEnabledFlag); 966 967 if (m_shortFormatInUse && m_vvcPicParams->m_phFlags.m_fields.m_phInterSliceAllowedFlag && m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRplInfoInPhFlag && 968 !m_vvcPicParams->m_phFlags.m_fields.m_numRefEntries1RplIdx1LargerThan0 && 969 (!m_vvcPicParams->m_phFlags.m_fields.m_phMvdL1ZeroFlag || 970 m_vvcPicParams->m_phFlags.m_fields.m_phBdofDisabledFlag != bdofDisabledFlag || 971 m_vvcPicParams->m_phFlags.m_fields.m_phDmvrDisabledFlag != dmvrDisabledFlag)) 972 { 973 if (!m_vvcPicParams->m_phFlags.m_fields.m_phMvdL1ZeroFlag) 974 { 975 DECODE_ASSERTMESSAGE("Error detected: ph_mvd_l1_zero_flag = 0 when pps_rpl_info_in_ph_flag = 1 && num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] = 0;\n"); 976 return MOS_STATUS_INVALID_PARAMETER; 977 } 978 else 979 { 980 DECODE_ASSERTMESSAGE("Error concealed: since pps_rpl_info_in_ph_flag = 1 && num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] = 0, do concealment:\n\ 981 Force ph_bdof_disabled_flag = sps_bdof_control_present_in_ph_flag == 0? 1 - sps_bdof_enabled_flag : 1;\n\ 982 Force ph_dmvr_disabled_flag = sps_dmvr_control_present_in_ph_flag == 0 ? 1 - sps_dmvr_enabled_flag : 1;\n"); 983 984 m_vvcPicParams->m_phFlags.m_fields.m_phBdofDisabledFlag = bdofDisabledFlag; 985 m_vvcPicParams->m_phFlags.m_fields.m_phDmvrDisabledFlag = dmvrDisabledFlag; 986 } 987 } 988 989 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsBdofControlPresentInPhFlag && 990 m_vvcPicParams->m_phFlags.m_fields.m_phBdofDisabledFlag != bdofDisabledFlag) 991 { 992 DECODE_ASSERTMESSAGE("Error concealed: Force ph_bdof_disabled_flag = sps_bdof_control_present_in_ph_flag == 0? 1 - sps_bdof_enabled_flag : 1;\n"); 993 m_vvcPicParams->m_phFlags.m_fields.m_phBdofDisabledFlag = bdofDisabledFlag; 994 } 995 996 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsDmvrControlPresentInPhFlag && 997 m_vvcPicParams->m_phFlags.m_fields.m_phDmvrDisabledFlag != dmvrDisabledFlag) 998 { 999 DECODE_ASSERTMESSAGE("Error concealed: force ph_dmvr_disabled_flag = sps_dmvr_control_present_in_ph_flag == 0 ? 1 - sps_dmvr_enabled_flag : 1;\n"); 1000 m_vvcPicParams->m_phFlags.m_fields.m_phDmvrDisabledFlag = dmvrDisabledFlag; 1001 } 1002 1003 if (m_shortFormatInUse && !m_vvcPicParams->m_spsFlags1.m_fields.m_spsProfControlPresentInPhFlag && 1004 m_vvcPicParams->m_phFlags.m_fields.m_phProfDisabledFlag != 1 - m_vvcPicParams->m_spsFlags1.m_fields.m_spsAffineProfEnabledFlag) 1005 { 1006 DECODE_ASSERTMESSAGE("Error concealed: force ph_prof_disabled_flag = 1-sps_affine_prof_enabled_flag when sps_prof_control_present_in_ph_flag = 0.\n"); 1007 m_vvcPicParams->m_phFlags.m_fields.m_phProfDisabledFlag = 1 - m_vvcPicParams->m_spsFlags1.m_fields.m_spsAffineProfEnabledFlag; 1008 } 1009 1010 if ((!m_vvcPicParams->m_spsFlags0.m_fields.m_spsSaoEnabledFlag || !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSaoInfoInPhFlag) && 1011 m_vvcPicParams->m_phFlags.m_fields.m_phSaoLumaEnabledFlag) 1012 { 1013 DECODE_ASSERTMESSAGE("Error concealed: force ph_sao_luma_enabled_flag = 0 when (sps_sao_enabled_flag == 0 || pps_sao_info_in_ph_flag == 0) is true.\n"); 1014 m_vvcPicParams->m_phFlags.m_fields.m_phSaoLumaEnabledFlag = 0; 1015 } 1016 1017 if ((!m_vvcPicParams->m_spsFlags0.m_fields.m_spsSaoEnabledFlag || 1018 !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSaoInfoInPhFlag || 1019 m_vvcPicParams->m_spsChromaFormatIdc == 0) && 1020 m_vvcPicParams->m_phFlags.m_fields.m_phSaoChromaEnabledFlag) 1021 { 1022 DECODE_ASSERTMESSAGE("Error concealed: force ph_sao_chroma_enabled_flag = 0 when (sps_sao_enabled_flag == 0 || pps_sao_info_in_ph_flag == 0 || sps_chroma_format_idc == 0) is true.\n"); 1023 m_vvcPicParams->m_phFlags.m_fields.m_phSaoChromaEnabledFlag = 0; 1024 } 1025 1026 // Deblocking filter - luma 1027 if(m_shortFormatInUse && (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsDbfInfoInPhFlag || 1028 m_vvcPicParams->m_phFlags.m_fields.m_phDeblockingFilterDisabledFlag) && 1029 (m_vvcPicParams->m_phLumaBetaOffsetDiv2 != m_vvcPicParams->m_ppsLumaBetaOffsetDiv2 || 1030 m_vvcPicParams->m_phLumaTcOffsetDiv2 != m_vvcPicParams->m_ppsLumaTcOffsetDiv2)) 1031 { 1032 DECODE_ASSERTMESSAGE("Error concealed: force ph_luma_beta_offset_div2=pps_luma_beta_offset_div2, ph_luma_tc_offset_div2 = pps_luma_tc_offset_div2 when (pps_dbf_info_in_ph_flag == 0 || ph_deblocking_filter_disabled_flag == 1) is true.\n"); 1033 m_vvcPicParams->m_phLumaBetaOffsetDiv2 = m_vvcPicParams->m_ppsLumaBetaOffsetDiv2; 1034 m_vvcPicParams->m_phLumaTcOffsetDiv2 = m_vvcPicParams->m_ppsLumaTcOffsetDiv2; 1035 } 1036 1037 if (m_shortFormatInUse) 1038 { 1039 // Deblocking filter - chroma 1040 int8_t cbBetaOffsetDiv2 = m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag ? m_vvcPicParams->m_ppsCbBetaOffsetDiv2 : m_vvcPicParams->m_phLumaBetaOffsetDiv2; 1041 int8_t cbTcOffsetDiv2 = m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag ? m_vvcPicParams->m_ppsCbTcOffsetDiv2 : m_vvcPicParams->m_phLumaTcOffsetDiv2; 1042 int8_t crBetaOffsetDiv2 = m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag ? m_vvcPicParams->m_ppsCrBetaOffsetDiv2 : m_vvcPicParams->m_phLumaBetaOffsetDiv2; 1043 int8_t crTcOffsetDiv2 = m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag ? m_vvcPicParams->m_ppsCrTcOffsetDiv2 : m_vvcPicParams->m_phLumaTcOffsetDiv2; 1044 1045 if ((!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsDbfInfoInPhFlag || 1046 m_vvcPicParams->m_phFlags.m_fields.m_phDeblockingFilterDisabledFlag || 1047 !m_vvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag) && 1048 (m_vvcPicParams->m_phCbBetaOffsetDiv2 != cbBetaOffsetDiv2 || 1049 m_vvcPicParams->m_phCbTcOffsetDiv2 != cbTcOffsetDiv2 || 1050 m_vvcPicParams->m_phCrBetaOffsetDiv2 != crBetaOffsetDiv2 || 1051 m_vvcPicParams->m_phCrTcOffsetDiv2 != crTcOffsetDiv2)) 1052 { 1053 DECODE_ASSERTMESSAGE( 1054 "Error concealed: force the following since (pps_dbf_info_in_ph_flag == 0 || ph_deblocking_filter_disabled_flag == 1 || pps_chroma_tool_offsets_present_flag == 0) is true: \n\ 1055 ph_cb_beta_offset_div2 = pps_chroma_tool_offsets_present_flag == 1? pps_cb_beta_offset_div2 : ph_luma_beta_offset_div2;\n\ 1056 ph_cb_tc_offset_div2 = pps_chroma_tool_offsets_present_flag == 1? pps_cb_tc_offset_div2 : ph_luma_tc_offset_div2;\n\ 1057 ph_cr_beta_offset_div2 = pps_chroma_tool_offsets_present_flag == 1 ? pps_cr_beta_offset_div2 : ph_luma_beta_offset_div2;\n\ 1058 ph_cr_tc_offset_div2 = pps_chroma_tool_offsets_present_flag == 1 ? pps_cr_tc_offset_div2 : ph_luma_tc_offset_div2;\n"); 1059 m_vvcPicParams->m_phCbBetaOffsetDiv2 = cbBetaOffsetDiv2; 1060 m_vvcPicParams->m_phCbTcOffsetDiv2 = cbTcOffsetDiv2; 1061 m_vvcPicParams->m_phCrBetaOffsetDiv2 = crBetaOffsetDiv2; 1062 m_vvcPicParams->m_phCrTcOffsetDiv2 = crTcOffsetDiv2; 1063 } 1064 } 1065 // detection + concealment for slice duplication + reorder for Long Format decoding 1066 if (!m_shortFormatInUse) 1067 { 1068 DECODE_CHK_STATUS(SliceErrorHandlingLF()); 1069 } 1070 1071 return MOS_STATUS_SUCCESS; 1072 } 1073 SetRequiredBitstreamSize(uint32_t requiredSize)1074 MOS_STATUS VvcBasicFeature::SetRequiredBitstreamSize(uint32_t requiredSize) 1075 { 1076 DECODE_FUNC_CALL(); 1077 if (requiredSize > m_dataSize) 1078 { 1079 m_dataOffset = 0; 1080 m_dataSize = MOS_ALIGN_CEIL(requiredSize, CODEC_BITSTREAM_ALIGN_SIZE_VVC); 1081 } 1082 DECODE_NORMALMESSAGE("Estimate bitstream size in this Frame: %u", requiredSize); 1083 return MOS_STATUS_SUCCESS; 1084 } 1085 GetSubPicIdxFromSubPicId(uint16_t subPicId)1086 int16_t VvcBasicFeature::GetSubPicIdxFromSubPicId(uint16_t subPicId) 1087 { 1088 DECODE_FUNC_CALL(); 1089 1090 if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && 1091 m_vvcPicParams->m_spsNumSubpicsMinus1 > 0) 1092 { 1093 DECODE_CHK_NULL(m_subPicParams); 1094 1095 for (int16_t idx = 0; idx < m_vvcPicParams->m_spsNumSubpicsMinus1 + 1; idx++) 1096 { 1097 if(m_subPicParams[idx].m_subpicIdVal == subPicId) 1098 { 1099 return idx; 1100 } 1101 } 1102 } 1103 1104 return 0; 1105 } 1106 SetSubPicStruct()1107 MOS_STATUS VvcBasicFeature::SetSubPicStruct() 1108 { 1109 DECODE_FUNC_CALL(); 1110 1111 DECODE_CHK_NULL(m_vvcPicParams); 1112 DECODE_CHK_NULL(m_subPicParams); 1113 1114 if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && m_vvcPicParams->m_spsNumSubpicsMinus1 > 0) 1115 { 1116 DECODE_CHK_NULL(m_subPicParams); 1117 DECODE_CHK_COND(m_vvcPicParams->m_spsNumSubpicsMinus1 >= vvcMaxSubpicNum, "Error detected: subpic number out of range!\n"); 1118 1119 MOS_ZeroMemory(m_sliceIdxInPicScanOrder, sizeof(m_sliceIdxInPicScanOrder)); 1120 uint32_t accNumCtu = 0; 1121 for (auto i = 0; i < m_vvcPicParams->m_spsNumSubpicsMinus1 + 1; i++) 1122 { 1123 CodecVvcSubpicParam* subPic = &m_subPicParams[i]; 1124 subPic->m_endCtbX = subPic->m_spsSubpicCtuTopLeftX + subPic->m_spsSubpicWidthMinus1; 1125 subPic->m_endCtbY = subPic->m_spsSubpicCtuTopLeftY + subPic->m_spsSubpicHeightMinus1; 1126 subPic->m_numSlices = 0; 1127 subPic->m_sliceIdx = &m_sliceIdxInPicScanOrder[0]; 1128 1129 accNumCtu += (subPic->m_spsSubpicWidthMinus1 + 1) * (subPic->m_spsSubpicHeightMinus1 + 1); 1130 DECODE_CHK_COND(subPic->m_endCtbX > m_picWidthInCtu - 1, "Error detected: subpic hor boundary out of pic!\n"); 1131 DECODE_CHK_COND(subPic->m_endCtbY > m_picHeightInCtu - 1, "Error detected: subpic vert boundary out of pic!\n"); 1132 } 1133 DECODE_CHK_COND(accNumCtu != m_picWidthInCtu * m_picHeightInCtu, "Error detected: subpictures have gap/overlap!\n"); 1134 } 1135 1136 return MOS_STATUS_SUCCESS; 1137 } 1138 ReconstructTile()1139 MOS_STATUS VvcBasicFeature::ReconstructTile() 1140 { 1141 DECODE_FUNC_CALL(); 1142 1143 MOS_ZeroMemory(m_tileRow, sizeof(m_tileRow)); 1144 MOS_ZeroMemory(m_tileCol, sizeof(m_tileCol)); 1145 1146 uint16_t accWidth = 0, accHeight = 0; 1147 uint16_t col = 0, row = 0; 1148 uint16_t ctuSize = 1 << (m_vvcPicParams->m_spsLog2CtuSizeMinus5 + 5); 1149 1150 //column 1151 for (col = 0; col <= m_vvcPicParams->m_ppsNumExpTileColumnsMinus1; col++) 1152 { 1153 m_tileCol[col].m_startCtbX = accWidth; 1154 m_tileCol[col].m_widthInCtb = m_tileParams[col].m_tileDimension + 1; 1155 m_tileCol[col].m_endCtbX = m_tileCol[col].m_startCtbX + m_tileCol[col].m_widthInCtb - 1; 1156 accWidth += m_tileParams[col].m_tileDimension + 1; 1157 DECODE_CHK_COND(accWidth > m_picWidthInCtu, "Error Detected: Tile hor boundary out of pic.\n"); 1158 } 1159 1160 uint16_t uniformWidthInCtb = m_tileParams[m_vvcPicParams->m_ppsNumExpTileColumnsMinus1].m_tileDimension + 1; 1161 for (; accWidth + uniformWidthInCtb <= m_picWidthInCtu; col++) 1162 { 1163 m_tileCol[col].m_startCtbX = accWidth; 1164 m_tileCol[col].m_widthInCtb = uniformWidthInCtb; 1165 m_tileCol[col].m_endCtbX = m_tileCol[col].m_startCtbX + m_tileCol[col].m_widthInCtb - 1; 1166 accWidth += uniformWidthInCtb; 1167 } 1168 if (accWidth < m_picWidthInCtu) 1169 { 1170 m_tileCol[col].m_startCtbX = accWidth; 1171 m_tileCol[col].m_widthInCtb = m_picWidthInCtu - accWidth; 1172 m_tileCol[col].m_endCtbX = m_picWidthInCtu - 1; 1173 col++; 1174 } 1175 1176 m_tileCols = col; 1177 DECODE_CHK_COND(m_tileCols > vvcMaxTileColNum || m_tileCols == 0, "Error detected: tile column number out of range!\n"); 1178 1179 // row 1180 for (row = 0; row <= m_vvcPicParams->m_ppsNumExpTileRowsMinus1; row++) 1181 { 1182 m_tileRow[row].m_startCtbY = accHeight; 1183 m_tileRow[row].m_heightInCtb = m_tileParams[m_vvcPicParams->m_ppsNumExpTileColumnsMinus1 + 1 + row].m_tileDimension + 1; 1184 m_tileRow[row].m_endCtbY = m_tileRow[row].m_startCtbY + m_tileRow[row].m_heightInCtb - 1; 1185 accHeight += m_tileParams[m_vvcPicParams->m_ppsNumExpTileColumnsMinus1 + 1 + row].m_tileDimension + 1; 1186 DECODE_CHK_COND(accHeight > m_picHeightInCtu, "Error Detected: Tile vert boundary out of pic.\n"); 1187 } 1188 uint16_t lastIdx = m_vvcPicParams->m_ppsNumExpTileRowsMinus1 + m_vvcPicParams->m_ppsNumExpTileColumnsMinus1 + 1; 1189 uint16_t uniformHeightInCtb = m_tileParams[lastIdx].m_tileDimension + 1; 1190 for (; accHeight + uniformHeightInCtb <= m_picHeightInCtu; row++) 1191 { 1192 m_tileRow[row].m_startCtbY = accHeight; 1193 m_tileRow[row].m_heightInCtb = uniformHeightInCtb; 1194 m_tileRow[row].m_endCtbY = m_tileRow[row].m_startCtbY + m_tileRow[row].m_heightInCtb - 1; 1195 accHeight += uniformHeightInCtb; 1196 } 1197 if (accHeight < m_picHeightInCtu) 1198 { 1199 m_tileRow[row].m_startCtbY = accHeight; 1200 m_tileRow[row].m_heightInCtb = m_picHeightInCtu - accHeight; 1201 m_tileRow[row].m_endCtbY = m_picHeightInCtu - 1; 1202 row++; 1203 } 1204 m_tileRows = row; 1205 DECODE_CHK_COND((m_tileRows * m_tileCols > vvcMaxTileNum) || m_tileRows == 0, "Error detected: tile number out of range!\n"); 1206 1207 m_maxTileWidth = 0; 1208 for (col = 0; col <= m_vvcPicParams->m_ppsNumExpTileColumnsMinus1; col++) 1209 { 1210 if (m_tileParams[col].m_tileDimension + 1 > m_maxTileWidth) 1211 { 1212 m_maxTileWidth = m_tileParams[col].m_tileDimension + 1; 1213 } 1214 } 1215 1216 if (((ctuSize == vvcCtu32) && (m_maxTileWidth > vvcMaxTileWCtb32)) || 1217 ((ctuSize == vvcCtu64) && (m_maxTileWidth > vvcMaxTileWCtb64)) || 1218 ((ctuSize == vvcCtu128) && (m_maxTileWidth > vvcMaxTileWCtb128))) 1219 { 1220 DECODE_ASSERTMESSAGE("Tile width exceeds maximum allowed value.\n"); 1221 return MOS_STATUS_INVALID_PARAMETER; 1222 } 1223 1224 return MOS_STATUS_SUCCESS; 1225 } 1226 ReconstructSlice()1227 MOS_STATUS VvcBasicFeature::ReconstructSlice() 1228 { 1229 DECODE_FUNC_CALL(); 1230 1231 DECODE_CHK_NULL(m_vvcPicParams); 1232 DECODE_CHK_NULL(m_vvcSliceParams); 1233 1234 MOS_ZeroMemory(m_sliceDesc, sizeof(m_sliceDesc)); 1235 1236 // Partition - reconstruct Slices 1237 if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag) 1238 { 1239 //Category1: Raster Scan Slice 1240 uint16_t col, row; 1241 for (uint32_t i = 0; i < m_numSlices; i++) 1242 { 1243 uint16_t start = m_vvcSliceParams[i].m_shSliceAddress; 1244 uint16_t end = start + m_vvcSliceParams[i].m_shNumTilesInSliceMinus1; 1245 1246 uint32_t numCtus = 0; 1247 for (auto idx = start; idx <= end; idx++) 1248 { 1249 col = idx % m_tileCols; 1250 row = idx / m_tileCols; 1251 1252 numCtus += m_tileCol[col].m_widthInCtb * m_tileRow[row].m_heightInCtb; 1253 } 1254 m_sliceDesc[i].m_numCtusInCurrSlice = numCtus; 1255 1256 col = start % m_tileCols; 1257 row = start / m_tileCols; 1258 m_sliceDesc[i].m_startTileX = col; 1259 m_sliceDesc[i].m_startTileY = row; 1260 m_sliceDesc[i].m_sliceStartCtbx = m_tileCol[col].m_startCtbX; 1261 m_sliceDesc[i].m_sliceStartCtby = m_tileRow[row].m_startCtbY; 1262 } 1263 } 1264 else if(!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag) 1265 { 1266 // Category2: Most general rect slice case, subpic v.s. slice partition is not the same 1267 DECODE_CHK_NULL(m_sliceStructParams); 1268 1269 uint16_t tileIdx = 0; 1270 int32_t slcStructIdx = -1;//index to slice structure 1271 CodecVvcSliceStructure* slcStruct = nullptr; 1272 DECODE_ASSERT(m_sliceStructParams[0].m_sliceTopLeftTileIdx == 0); 1273 1274 // Go through rectangular slice parameters 1275 int32_t i = 0; 1276 for( i = 0; i < m_vvcPicParams->m_ppsNumSlicesInPicMinus1; i++ ) 1277 { 1278 slcStructIdx++; 1279 if (slcStructIdx > m_vvcPicParams->m_numSliceStructsMinus1) 1280 { 1281 DECODE_ASSERTMESSAGE("Incomplete slice structures received.\n"); 1282 return MOS_STATUS_INVALID_PARAMETER; 1283 } 1284 slcStruct = &m_sliceStructParams[slcStructIdx]; 1285 DECODE_CHK_COND(slcStruct->m_sliceTopLeftTileIdx >= m_tileCols * m_tileRows,"Error Detected: error slice structure params, SliceTopLeftTileIdx exceeds the max tile index in the picture!\n"); 1286 tileIdx = slcStruct->m_sliceTopLeftTileIdx; 1287 m_sliceDesc[i].m_tileIdx = tileIdx; 1288 1289 // complete tiles within a single slice 1290 DECODE_CHK_COND((tileIdx % m_tileCols) + slcStruct->m_ppsSliceWidthInTilesMinus1 >= m_tileCols, "Error Detected: rect slice right border exceeds picture boundary.\n"); 1291 DECODE_CHK_COND((tileIdx / m_tileCols) + slcStruct->m_ppsSliceHeightInTilesMinus1 >= m_tileRows, "Error Detected: rect slice bottom border exceeds picture boundary.\n"); 1292 m_sliceDesc[i].m_sliceWidthInTiles = slcStruct->m_ppsSliceWidthInTilesMinus1 + 1; 1293 m_sliceDesc[i].m_sliceHeightInTiles = slcStruct->m_ppsSliceHeightInTilesMinus1 + 1; 1294 1295 // Derived variables on slice v.s. CTU 1296 m_sliceDesc[i].m_sliceStartCtbx = m_tileCol[tileIdx % m_tileCols].m_startCtbX; 1297 m_sliceDesc[i].m_sliceStartCtby = m_tileRow[tileIdx / m_tileCols].m_startCtbY; 1298 1299 // multiple slices within a single tile special case 1300 if( m_sliceDesc[i].m_sliceWidthInTiles == 1 && m_sliceDesc[i].m_sliceHeightInTiles == 1) 1301 { 1302 if((m_tileRow[tileIdx/m_tileCols].m_heightInCtb == 1) || 1303 (slcStruct->m_ppsExpSliceHeightInCtusMinus1 + 1 == m_tileRow[tileIdx / m_tileCols].m_heightInCtb)) 1304 { 1305 m_sliceDesc[i].m_numSlicesInTile = 1; 1306 m_sliceDesc[i].m_sliceHeightInCtu = slcStruct->m_ppsExpSliceHeightInCtusMinus1 + 1; 1307 } 1308 else 1309 { 1310 uint16_t remTileRowHeight = m_tileRow[tileIdx / m_tileCols].m_heightInCtb; 1311 int j = 0; 1312 for (;;j++) 1313 { 1314 DECODE_CHK_COND(slcStruct->m_ppsExpSliceHeightInCtusMinus1 + 1 > remTileRowHeight || slcStruct->m_ppsExpSliceHeightInCtusMinus1 + 1 == 0, "Error Detected: Accumulated rect slice height of multiple slices in one tile case exceeds the tile height.\n"); 1315 m_sliceDesc[i+j].m_sliceHeightInCtu = slcStruct->m_ppsExpSliceHeightInCtusMinus1 + 1; 1316 remTileRowHeight -= m_sliceDesc[i+j].m_sliceHeightInCtu; 1317 1318 slcStructIdx++; 1319 if (slcStructIdx > m_vvcPicParams->m_numSliceStructsMinus1) 1320 { 1321 slcStructIdx--; 1322 break; 1323 } 1324 slcStruct = &m_sliceStructParams[slcStructIdx]; 1325 if (slcStruct->m_sliceTopLeftTileIdx != tileIdx) 1326 { 1327 slcStructIdx--; 1328 break; 1329 } 1330 } 1331 1332 uint16_t uniformSliceHeight = m_sliceDesc[i + j].m_sliceHeightInCtu; 1333 1334 uint16_t deriveNum = MOS_ROUNDUP_DIVIDE(remTileRowHeight, uniformSliceHeight); 1335 DECODE_CHK_COND(i + j + deriveNum > m_vvcPicParams->m_ppsNumSlicesInPicMinus1, "Error detected: Derived slice index exceeds the the last slice index in pic!\n"); 1336 1337 while( remTileRowHeight >= uniformSliceHeight ) 1338 { 1339 j++; 1340 m_sliceDesc[i + j].m_sliceHeightInCtu = uniformSliceHeight; 1341 remTileRowHeight -= uniformSliceHeight; 1342 } 1343 if( remTileRowHeight > 0 ) 1344 { 1345 j++; 1346 m_sliceDesc[i + j].m_sliceHeightInCtu = remTileRowHeight; 1347 } 1348 1349 for( int k = 0; k < j + 1; k++ ) 1350 { 1351 m_sliceDesc[i + k].m_numSlicesInTile = j + 1; 1352 m_sliceDesc[i + k].m_sliceWidthInTiles = 1; 1353 m_sliceDesc[i + k].m_sliceHeightInTiles = 1; 1354 m_sliceDesc[i + k].m_tileIdx = tileIdx; 1355 1356 //derived variables 1357 if (k > 0) 1358 { 1359 m_sliceDesc[i + k].m_sliceStartCtby = m_sliceDesc[i + k - 1].m_sliceStartCtby + m_sliceDesc[i + k - 1].m_sliceHeightInCtu; 1360 } 1361 m_sliceDesc[i + k].m_sliceStartCtbx = m_tileCol[tileIdx % m_tileCols].m_startCtbX; 1362 } 1363 m_sliceDesc[i].m_topSliceInTileFlag = 1; 1364 m_sliceDesc[i + j].m_bottomSliceInTileFlag = 1; 1365 i += j; 1366 } 1367 } 1368 } 1369 1370 // The last slice not covered in multi-slice tile 1371 if (i == m_vvcPicParams->m_ppsNumSlicesInPicMinus1) 1372 { 1373 slcStructIdx++; 1374 if (slcStructIdx != m_vvcPicParams->m_numSliceStructsMinus1) 1375 { 1376 DECODE_ASSERTMESSAGE("Incorrect slice structures received.\n"); 1377 return MOS_STATUS_INVALID_PARAMETER; 1378 } 1379 slcStruct = &m_sliceStructParams[slcStructIdx]; 1380 m_sliceDesc[i].m_tileIdx = slcStruct->m_sliceTopLeftTileIdx; 1381 1382 //Derive other params 1383 m_sliceDesc[i].m_numSlicesInTile = 1; 1384 m_sliceDesc[i].m_sliceStartCtbx = m_tileCol[m_sliceDesc[i].m_tileIdx % m_tileCols].m_startCtbX; 1385 m_sliceDesc[i].m_sliceStartCtby = m_tileRow[m_sliceDesc[i].m_tileIdx / m_tileCols].m_startCtbY; 1386 m_sliceDesc[i].m_sliceHeightInCtu = m_picHeightInCtu - m_sliceDesc[i].m_sliceStartCtby; 1387 m_sliceDesc[i].m_sliceHeightInTiles = m_tileRows - (m_sliceDesc[i].m_tileIdx / m_tileCols); 1388 m_sliceDesc[i].m_sliceWidthInTiles = m_tileCols - (m_sliceDesc[i].m_tileIdx % m_tileCols); 1389 } 1390 1391 //Derived variables on SubPic v.s. Slice 1392 if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && m_vvcPicParams->m_spsNumSubpicsMinus1 > 0) 1393 { 1394 for (auto slc = 0; slc < m_vvcPicParams->m_ppsNumSlicesInPicMinus1 + 1; slc++) 1395 { 1396 for (uint16_t sp = 0; sp < m_vvcPicParams->m_spsNumSubpicsMinus1 + 1; sp++) 1397 { 1398 if ((m_sliceDesc[slc].m_sliceStartCtbx >= m_subPicParams[sp].m_spsSubpicCtuTopLeftX) && 1399 (m_sliceDesc[slc].m_sliceStartCtbx <= m_subPicParams[sp].m_endCtbX) && 1400 (m_sliceDesc[slc].m_sliceStartCtby >= m_subPicParams[sp].m_spsSubpicCtuTopLeftY) && 1401 (m_sliceDesc[slc].m_sliceStartCtby <= m_subPicParams[sp].m_endCtbY)) 1402 { 1403 m_sliceDesc[slc].m_subPicIdx = sp; 1404 m_sliceDesc[slc].m_sliceIdxInSubPic = m_subPicParams[sp].m_numSlices; 1405 1406 m_subPicParams[sp].m_numSlices++; 1407 1408 break; 1409 } 1410 } 1411 } 1412 int32_t accSlice = 0; 1413 for (auto sp = 0; sp < m_vvcPicParams->m_spsNumSubpicsMinus1 + 1; sp++) 1414 { 1415 m_subPicParams[sp].m_sliceIdx = &m_sliceIdxInPicScanOrder[accSlice]; 1416 accSlice += m_subPicParams[sp].m_numSlices; 1417 } 1418 for (auto sp = 0; sp < m_vvcPicParams->m_spsNumSubpicsMinus1 + 1; sp++) 1419 { 1420 m_subPicParams[sp].m_numSlices = 0; 1421 } 1422 for (uint16_t slc = 0; slc < m_vvcPicParams->m_ppsNumSlicesInPicMinus1 + 1; slc++) 1423 { 1424 int32_t sp = m_sliceDesc[slc].m_subPicIdx; 1425 1426 m_subPicParams[sp].m_numSlices++; 1427 m_subPicParams[sp].m_sliceIdx[m_subPicParams[sp].m_numSlices - 1] = slc; 1428 } 1429 } 1430 1431 for (uint16_t slc = 0; slc < m_vvcPicParams->m_ppsNumSlicesInPicMinus1 + 1; slc++) 1432 { 1433 //Derive other params 1434 m_sliceDesc[slc].m_multiSlicesInTileFlag = (m_sliceDesc[slc].m_numSlicesInTile > 1) ? 1 : 0; 1435 m_sliceDesc[slc].m_startTileX = m_sliceDesc[slc].m_tileIdx % m_tileCols; 1436 m_sliceDesc[slc].m_startTileY = m_sliceDesc[slc].m_tileIdx / m_tileCols; 1437 1438 uint16_t startTile = 0; 1439 uint16_t endTile = 0; 1440 uint16_t sliceWidthInCtu = 0; 1441 uint16_t sliceHeightInCtu = 0; 1442 if (m_sliceDesc[slc].m_numSlicesInTile > 1) 1443 { 1444 startTile = m_sliceDesc[slc].m_startTileX; 1445 sliceWidthInCtu = m_tileCol[startTile].m_widthInCtb; 1446 sliceHeightInCtu = m_sliceDesc[slc].m_sliceHeightInCtu; 1447 } 1448 else 1449 { 1450 startTile = m_sliceDesc[slc].m_startTileX; 1451 endTile = m_sliceDesc[slc].m_sliceWidthInTiles + startTile - 1; 1452 sliceWidthInCtu = m_tileCol[endTile].m_endCtbX + 1 - m_tileCol[startTile].m_startCtbX; 1453 1454 startTile = m_sliceDesc[slc].m_startTileY; 1455 endTile = m_sliceDesc[slc].m_sliceHeightInTiles + startTile - 1; 1456 sliceHeightInCtu = m_tileRow[endTile].m_endCtbY + 1 - m_tileRow[startTile].m_startCtbY; 1457 m_sliceDesc[slc].m_sliceHeightInCtu = sliceHeightInCtu; 1458 } 1459 m_sliceDesc[slc].m_numCtusInCurrSlice = sliceWidthInCtu * sliceHeightInCtu; 1460 } 1461 } 1462 else if(m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag) 1463 { 1464 //Category3/4: slice & subpic have the same partition 1465 if (m_vvcPicParams->m_spsNumSubpicsMinus1 == 0 || !m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag) 1466 { 1467 //Category4: only one slice/subpic 1468 m_sliceDesc[0].m_numCtusInCurrSlice = m_picWidthInCtu * m_picHeightInCtu; 1469 m_sliceDesc[0].m_tileIdx = 0; 1470 m_sliceDesc[0].m_sliceWidthInTiles = m_tileCols; 1471 m_sliceDesc[0].m_sliceHeightInTiles = m_tileRows; 1472 m_sliceDesc[0].m_numSlicesInTile = 1; 1473 m_sliceDesc[0].m_sliceHeightInCtu = m_picHeightInCtu; 1474 m_sliceDesc[0].m_sliceStartCtbx = 0; 1475 m_sliceDesc[0].m_sliceStartCtby = 0; 1476 m_sliceDesc[0].m_subPicIdx = 0; 1477 m_sliceDesc[0].m_sliceIdxInSubPic = 0; 1478 m_sliceDesc[0].m_multiSlicesInTileFlag = 0; 1479 m_sliceDesc[0].m_startTileX = 0; 1480 m_sliceDesc[0].m_startTileY = 0; 1481 } 1482 else 1483 { 1484 //Category3: multiple slice/subpic 1485 uint16_t startCtu = 0, endCtu = 0; 1486 int16_t startTileX = 0, startTileY = 0, endTile = 0; 1487 for (uint16_t i = 0; i < m_vvcPicParams->m_spsNumSubpicsMinus1 + 1; i++) 1488 { 1489 startCtu = m_subPicParams[i].m_spsSubpicCtuTopLeftX; 1490 endCtu = m_subPicParams[i].m_endCtbX; 1491 m_sliceDesc[i].m_sliceWidthInTiles = GetSubpicWidthInTile(startCtu, endCtu, startTileX, endTile); 1492 1493 if ((m_sliceDesc[i].m_sliceWidthInTiles == -1) || (startTileX == -1) || (endTile == -1)) 1494 { 1495 DECODE_ASSERTMESSAGE("Incorrect derived results.\n"); 1496 return MOS_STATUS_INVALID_PARAMETER; 1497 } 1498 1499 startCtu = m_subPicParams[i].m_spsSubpicCtuTopLeftY; 1500 endCtu = m_subPicParams[i].m_endCtbY; 1501 m_sliceDesc[i].m_sliceHeightInTiles = GetSubpicHeightInTile(startCtu, endCtu, startTileY, endTile); 1502 1503 if ((m_sliceDesc[i].m_sliceHeightInTiles == -1) || (startTileY == -1) || (endTile == -1)) 1504 { 1505 DECODE_ASSERTMESSAGE("Incorrect derived results.\n"); 1506 return MOS_STATUS_INVALID_PARAMETER; 1507 } 1508 1509 if (m_sliceDesc[i].m_sliceHeightInTiles == 1 && 1510 m_subPicParams[i].m_spsSubpicHeightMinus1 + 1 < m_tileRow[startTileY].m_heightInCtb) 1511 { 1512 m_sliceDesc[i].m_multiSlicesInTileFlag = 1; 1513 m_sliceDesc[i].m_topSliceInTileFlag = (startCtu == m_tileRow[startTileY].m_startCtbY) ? true : false; 1514 m_sliceDesc[i].m_bottomSliceInTileFlag = (endCtu == m_tileRow[endTile].m_endCtbY) ? true : false; 1515 } 1516 else 1517 { 1518 m_sliceDesc[i].m_multiSlicesInTileFlag = 0; 1519 m_sliceDesc[i].m_topSliceInTileFlag = 0; 1520 m_sliceDesc[i].m_bottomSliceInTileFlag = 0; 1521 } 1522 1523 m_sliceDesc[i].m_startTileX = startTileX; 1524 m_sliceDesc[i].m_startTileY = startTileY; 1525 m_sliceDesc[i].m_tileIdx = startTileX + startTileY * m_tileCols; 1526 m_sliceDesc[i].m_sliceHeightInCtu = m_subPicParams[i].m_spsSubpicHeightMinus1 + 1; 1527 m_sliceDesc[i].m_sliceStartCtbx = m_subPicParams[i].m_spsSubpicCtuTopLeftX; 1528 m_sliceDesc[i].m_sliceStartCtby = m_subPicParams[i].m_spsSubpicCtuTopLeftY; 1529 m_sliceDesc[i].m_subPicIdx = i; 1530 m_sliceDesc[i].m_sliceIdxInSubPic = 0; 1531 1532 //Derive other params 1533 m_sliceDesc[i].m_numCtusInCurrSlice = (m_subPicParams[i].m_spsSubpicHeightMinus1 + 1) * (m_subPicParams[i].m_spsSubpicWidthMinus1 + 1); 1534 m_sliceDesc[i].m_numSlicesInTile = 0; 1535 m_subPicParams[i].m_sliceIdx = &m_sliceIdxInPicScanOrder[i]; 1536 m_subPicParams[i].m_sliceIdx[0] = i; 1537 m_subPicParams[i].m_numSlices = 1; 1538 } 1539 } 1540 } 1541 1542 return MOS_STATUS_SUCCESS; 1543 } 1544 ReconstructPartition(CodechalDecodeParams * decodeParams)1545 MOS_STATUS VvcBasicFeature::ReconstructPartition(CodechalDecodeParams* decodeParams) 1546 { 1547 DECODE_FUNC_CALL(); 1548 1549 DECODE_CHK_NULL(m_vvcPicParams); 1550 DECODE_CHK_NULL(m_vvcSliceParams); 1551 1552 // Tile 1553 DECODE_CHK_STATUS(ReconstructTile()); 1554 1555 // SubPic 1556 DECODE_CHK_STATUS(SetSubPicStruct()); 1557 1558 // Slice 1559 DECODE_CHK_STATUS(ReconstructSlice()); 1560 1561 return MOS_STATUS_SUCCESS; 1562 } 1563 SetPictureStructs(CodechalDecodeParams * decodeParams)1564 MOS_STATUS VvcBasicFeature::SetPictureStructs(CodechalDecodeParams *decodeParams) 1565 { 1566 DECODE_FUNC_CALL(); 1567 1568 m_curRenderPic = m_vvcPicParams->m_currPic; 1569 m_width = (uint32_t)m_vvcPicParams->m_ppsPicWidthInLumaSamples; 1570 m_height = (uint32_t)m_vvcPicParams->m_ppsPicHeightInLumaSamples; 1571 m_picWidthInCtu = MOS_ROUNDUP_SHIFT(m_vvcPicParams->m_ppsPicWidthInLumaSamples, m_vvcPicParams->m_spsLog2CtuSizeMinus5 + 5); 1572 m_picHeightInCtu = MOS_ROUNDUP_SHIFT(m_vvcPicParams->m_ppsPicHeightInLumaSamples, m_vvcPicParams->m_spsLog2CtuSizeMinus5 + 5); 1573 m_frameWidthAlignedMinBlk = MOS_ALIGN_CEIL(m_vvcPicParams->m_ppsPicWidthInLumaSamples, vvcMinBlockWidth); 1574 m_frameHeightAlignedMinBlk = MOS_ALIGN_CEIL(m_vvcPicParams->m_ppsPicHeightInLumaSamples, vvcMinBlockHeight); 1575 1576 m_refFrameIndexList.clear(); 1577 for (auto i = 0; i < vvcMaxNumRefFrame; i++) 1578 { 1579 uint8_t index = m_vvcPicParams->m_refFrameList[i].FrameIdx; 1580 if (index < CODEC_MAX_DPB_NUM_VVC) 1581 { 1582 m_refFrameIndexList.push_back(index); 1583 } 1584 } 1585 1586 DECODE_CHK_STATUS(m_refFrames.UpdatePicture(*m_vvcPicParams)); 1587 DECODE_CHK_STATUS(m_mvBuffers.UpdatePicture(m_vvcPicParams->m_currPic.FrameIdx, m_refFrameIndexList)); 1588 1589 m_pictureCodingType = m_vvcPicParams->m_picMiscFlags.m_fields.m_intraPicFlag ? I_TYPE : MIXED_TYPE; 1590 1591 return MOS_STATUS_SUCCESS; 1592 } 1593 UpdateNumRefForList()1594 MOS_STATUS VvcBasicFeature::UpdateNumRefForList() 1595 { 1596 DECODE_FUNC_CALL(); 1597 if (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRplInfoInPhFlag > 0) 1598 { 1599 //List0: 1600 if (!m_vvcPicParams->m_phFlags.m_fields.m_rplSpsFlag0) 1601 { 1602 m_numRefForList0 = m_rplParams[vvcPhRpl0Offset].m_numRefEntries; 1603 } 1604 else 1605 { 1606 m_numRefForList0 = m_rplParams[m_vvcPicParams->m_rplSpsIndex0].m_numRefEntries; 1607 } 1608 //List1: 1609 if (!m_vvcPicParams->m_phFlags.m_fields.m_rplSpsFlag1) 1610 { 1611 m_numRefForList1 = m_rplParams[vvcPhRpl1Offset].m_numRefEntries; 1612 } 1613 else 1614 { 1615 m_numRefForList1 = m_rplParams[m_vvcPicParams->m_rplSpsIndex1 + vvcSpsCandidateRpl1Offset].m_numRefEntries; 1616 } 1617 } 1618 1619 if (m_vvcPicParams->m_phFlags.m_fields.m_phInterSliceAllowedFlag && m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRplInfoInPhFlag) 1620 { 1621 m_vvcPicParams->m_phFlags.m_fields.m_numRefEntries0RplIdx0LargerThan0 = m_numRefForList0 > 0 ? 1 : 0; 1622 m_vvcPicParams->m_phFlags.m_fields.m_numRefEntries1RplIdx1LargerThan0 = m_numRefForList1 > 0 ? 1 : 0; 1623 } 1624 1625 return MOS_STATUS_SUCCESS; 1626 } 1627 GetSubpicWidthInTile(uint16_t startCtu,uint16_t endCtu,int16_t & startTile,int16_t & endTile)1628 int16_t VvcBasicFeature::GetSubpicWidthInTile(uint16_t startCtu, uint16_t endCtu, int16_t &startTile, int16_t &endTile) 1629 { 1630 DECODE_FUNC_CALL(); 1631 1632 if ((endCtu < startCtu) || 1633 (endCtu > m_picWidthInCtu) || 1634 (startCtu > m_picWidthInCtu)) 1635 { 1636 DECODE_ASSERT(endCtu >= startCtu); 1637 } 1638 1639 startTile = -1; 1640 for (int16_t i = 0; i < m_tileCols; i++) 1641 { 1642 if (startCtu >= m_tileCol[i].m_startCtbX && startCtu <= m_tileCol[i].m_endCtbX) 1643 { 1644 startTile = i; 1645 break; 1646 } 1647 } 1648 1649 endTile = -1; 1650 if ((startTile > -1)) 1651 { 1652 for (int16_t i = startTile; i < m_tileCols; i++) 1653 { 1654 if (endCtu >= m_tileCol[i].m_startCtbX && endCtu <= m_tileCol[i].m_endCtbX) 1655 { 1656 endTile = i; 1657 break; 1658 } 1659 } 1660 } 1661 1662 return ((endTile > -1) ? (endTile + 1 - startTile) : 1); 1663 } 1664 GetSubpicHeightInTile(uint16_t startCtu,uint16_t endCtu,int16_t & startTile,int16_t & endTile)1665 int16_t VvcBasicFeature::GetSubpicHeightInTile(uint16_t startCtu, uint16_t endCtu, int16_t &startTile, int16_t &endTile) 1666 { 1667 DECODE_FUNC_CALL(); 1668 1669 if ((endCtu < startCtu) || 1670 (endCtu > m_picHeightInCtu) || 1671 (startCtu > m_picHeightInCtu)) 1672 { 1673 DECODE_ASSERT(endCtu >= startCtu); 1674 } 1675 1676 startTile = -1; 1677 for (int16_t i = 0; i < m_tileRows; i++) 1678 { 1679 if (startCtu >= m_tileRow[i].m_startCtbY && startCtu <= m_tileRow[i].m_endCtbY) 1680 { 1681 startTile = i; 1682 break; 1683 } 1684 } 1685 1686 endTile = -1; 1687 if ((startTile > -1)) 1688 { 1689 for (int16_t i = startTile; i < m_tileRows; i++) 1690 { 1691 if (endCtu >= m_tileRow[i].m_startCtbY && endCtu <= m_tileRow[i].m_endCtbY) 1692 { 1693 endTile = i; 1694 break; 1695 } 1696 } 1697 } 1698 1699 return ((endTile > -1) ? (endTile + 1 - startTile) : 1); 1700 } 1701 1702 } // namespace decode 1703