| 518 | } |
| 519 | |
| 520 | int32_t ParseInterPMotionInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, |
| 521 | int16_t pMotionVector[LIST_A][30][MV_A], int16_t pMvdCache[LIST_A][30][MV_A], int8_t pRefIndex[LIST_A][30]) { |
| 522 | PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer; |
| 523 | PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; |
| 524 | PDqLayer pCurDqLayer = pCtx->pCurDqLayer; |
| 525 | PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0]; |
| 526 | int32_t pRefCount[2]; |
| 527 | int32_t i, j; |
| 528 | int32_t iMbXy = pCurDqLayer->iMbXyIndex; |
| 529 | int16_t pMv[4] = {0}; |
| 530 | int16_t pMvd[4] = {0}; |
| 531 | int8_t iRef[2] = {0}; |
| 532 | int32_t iPartIdx; |
| 533 | int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv; |
| 534 | int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv; |
| 535 | pRefCount[0] = pSliceHeader->uiRefCount[0]; |
| 536 | pRefCount[1] = pSliceHeader->uiRefCount[1]; |
| 537 | |
| 538 | bool bIsPending = GetThreadCount (pCtx) > 1; |
| 539 | |
| 540 | switch (pCurDqLayer->pDec->pMbType[iMbXy]) { |
| 541 | case MB_TYPE_16x16: { |
| 542 | iPartIdx = 0; |
| 543 | WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, 0, LIST_0, iPartIdx, pRefCount[0], 0, |
| 544 | iRef[0])); |
| 545 | if ((iRef[0] < 0) || (iRef[0] >= pRefCount[0]) || (ppRefPic[iRef[0]] == NULL)) { //error ref_idx |
| 546 | pCtx->bMbRefConcealed = true; |
| 547 | if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) { |
| 548 | iRef[0] = 0; |
| 549 | pCtx->iErrorCode |= dsBitstreamError; |
| 550 | } else { |
| 551 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX); |
| 552 | } |
| 553 | } |
| 554 | pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRef[0]] |
| 555 | && (ppRefPic[iRef[0]]->bIsComplete || bIsPending)); |
| 556 | PredMv (pMotionVector, pRefIndex, LIST_0, 0, 4, iRef[0], pMv); |
| 557 | WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0])); |
| 558 | WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1])); |
| 559 | pMv[0] += pMvd[0]; |
| 560 | pMv[1] += pMvd[1]; |
| 561 | WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv"); |
| 562 | UpdateP16x16MotionInfo (pCurDqLayer, LIST_0, iRef[0], pMv); |
| 563 | UpdateP16x16MvdCabac (pCurDqLayer, pMvd, LIST_0); |
| 564 | } |
| 565 | break; |
| 566 | case MB_TYPE_16x8: |
| 567 | for (i = 0; i < 2; i++) { |
| 568 | iPartIdx = i << 3; |
| 569 | WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, 0, LIST_0, iPartIdx, pRefCount[0], 0, |
| 570 | iRef[i])); |
| 571 | if ((iRef[i] < 0) || (iRef[i] >= pRefCount[0]) || (ppRefPic[iRef[i]] == NULL)) { //error ref_idx |
| 572 | pCtx->bMbRefConcealed = true; |
| 573 | if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) { |
| 574 | iRef[i] = 0; |
| 575 | pCtx->iErrorCode |= dsBitstreamError; |
| 576 | } else { |
| 577 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX); |
no test coverage detected