| 499 | } |
| 500 | |
| 501 | int32_t ParseDecRefPicMarking (PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps, |
| 502 | const bool kbIdrFlag) { |
| 503 | PRefPicMarking const kpRefMarking = &pSh->sRefMarking; |
| 504 | uint32_t uiCode; |
| 505 | if (kbIdrFlag) { |
| 506 | WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //no_output_of_prior_pics_flag |
| 507 | kpRefMarking->bNoOutputOfPriorPicsFlag = !!uiCode; |
| 508 | WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //long_term_reference_flag |
| 509 | kpRefMarking->bLongTermRefFlag = !!uiCode; |
| 510 | } else { |
| 511 | WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_ref_pic_marking_mode_flag |
| 512 | kpRefMarking->bAdaptiveRefPicMarkingModeFlag = !!uiCode; |
| 513 | if (kpRefMarking->bAdaptiveRefPicMarkingModeFlag) { |
| 514 | int32_t iIdx = 0; |
| 515 | bool bAllowMmco5 = true, bMmco4Exist = false, bMmco5Exist = false, bMmco6Exist = false; |
| 516 | do { |
| 517 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //memory_management_control_operation |
| 518 | const uint32_t kuiMmco = uiCode; |
| 519 | |
| 520 | kpRefMarking->sMmcoRef[iIdx].uiMmcoType = kuiMmco; |
| 521 | if (kuiMmco == MMCO_END) |
| 522 | break; |
| 523 | |
| 524 | if (kuiMmco == MMCO_SHORT2UNUSED || kuiMmco == MMCO_SHORT2LONG) { |
| 525 | bAllowMmco5 = false; |
| 526 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //difference_of_pic_nums_minus1 |
| 527 | kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + uiCode; |
| 528 | kpRefMarking->sMmcoRef[iIdx].iShortFrameNum = (pSh->iFrameNum - kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum) & (( |
| 529 | 1 << pSps->uiLog2MaxFrameNum) - 1); |
| 530 | } else if (kuiMmco == MMCO_LONG2UNUSED) { |
| 531 | bAllowMmco5 = false; |
| 532 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num |
| 533 | kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = uiCode; |
| 534 | } |
| 535 | if (kuiMmco == MMCO_SHORT2LONG || kuiMmco == MMCO_LONG) { |
| 536 | if (kuiMmco == MMCO_LONG) { |
| 537 | WELS_VERIFY_RETURN_IF (-1, bMmco6Exist); |
| 538 | bMmco6Exist = true; |
| 539 | } |
| 540 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_frame_idx |
| 541 | kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = uiCode; |
| 542 | } else if (kuiMmco == MMCO_SET_MAX_LONG) { |
| 543 | WELS_VERIFY_RETURN_IF (-1, bMmco4Exist); |
| 544 | bMmco4Exist = true; |
| 545 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //max_long_term_frame_idx_plus1 |
| 546 | int32_t iMaxLongTermFrameIdx = -1 + uiCode; |
| 547 | if (iMaxLongTermFrameIdx > pSps->iNumRefFrames) { |
| 548 | //ISO/IEC 14496-10:2009(E) 7.4.3.3 Decoded reference picture marking semantics page 96 |
| 549 | return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_MARKING); |
| 550 | } |
| 551 | kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = iMaxLongTermFrameIdx; |
| 552 | } else if (kuiMmco == MMCO_RESET) { |
| 553 | WELS_VERIFY_RETURN_IF (-1, (!bAllowMmco5 || bMmco5Exist)); |
| 554 | bMmco5Exist = true; |
| 555 | |
| 556 | pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb = 0; |
| 557 | pCtx->pLastDecPicInfo->iPrevPicOrderCntMsb = 0; |
| 558 | pSh->iPicOrderCntLsb = 0; |
no test coverage detected