📄 umc_h264_dec_decode_mb.cpp
字号:
TopRightMB=GetTopRightBlock(pMBInfo,TopRightBlockNum);*/ Top = m_cur_mb.CurrentBlockNeighbours.mb_above; TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above; TopLeft= m_cur_mb.CurrentBlockNeighbours.mb_above_left; TopRight.block_num+=2; // init vars for median prediction isRightUnavailable = (Top.mb_num<0); if (isRightUnavailable) isLeftUnavailable = (TopLeft.mb_num<0); } } else { // right half, use predictor from above right unless unavailable, // then try above left //TopRightBlockNum=3; //TopRightMB=GetTopRightBlock(pMBInfo,TopRightBlockNum); //TopBlockNum=2; //TopMB=GetTopBlock(pMBInfo,TopBlockNum); TopRight= m_cur_mb.CurrentBlockNeighbours.mb_above_right; Top= m_cur_mb.CurrentBlockNeighbours.mb_above; Top.block_num+=2; if ( TopRight.mb_num>=0) { if (IS_INTER_MBTYPE(gmbs[TopRight.mb_num].mbtype) && (((RefIdxs[TopRight.mb_num].RefIdxs[TopRight.block_num])) == RefIndex)) { *pMVx = MVs[TopRight.mb_num].MotionVectors[TopRight.block_num].mvx; *pMVy = MVs[TopRight.mb_num].MotionVectors[TopRight.block_num].mvy; goto done; } } else if ( Top.mb_num>=0) { if (IS_INTER_MBTYPE(gmbs[Top.mb_num].mbtype) && (((RefIdxs[Top.mb_num].RefIdxs[Top.block_num-1])) == RefIndex)) { *pMVx = MVs[Top.mb_num].MotionVectors[Top.block_num-1].mvx; *pMVy = MVs[Top.mb_num].MotionVectors[Top.block_num-1].mvy; goto done; } } //LeftBlockNum=2; //LeftMB=GetLeftBlock(pMBInfo,LeftBlockNum); Left.mb_num=m_CurMBAddr; Left.block_num=1; TopLeft=m_cur_mb.CurrentBlockNeighbours.mb_above; TopLeft.block_num++; // init vars for median prediction isRightUnavailable = (TopRight.mb_num<0); if (isRightUnavailable) isLeftUnavailable = (Top.mb_num<0); } // diff = 2; break; case MBTYPE_INTER_8x8: case MBTYPE_INTER_8x8_REF0: // Each 8x8 block of a macroblock can be subdivided into subblocks, // each having its own MV. The parameter 'block' has block and // subblock information: // block 0..3, bits 2-3 // subblock 0..3, bits 0-1 Ipp32s left_edge_block, top_edge_block, right_edge_block; switch (m_cur_mb.GlobalMacroblockInfo->sbtype[block>>2]) { case SBTYPE_8x8: Top.block_num= Left.block_num= TopLeft.block_num= block2lin[block]; TopRight.block_num= block2lin[block]+1; GetLeftLocationForCurrentMBLumaNonMBAFF(&Left); GetTopLocationForCurrentMBLumaNonMBAFF(&Top); GetTopRightLocationForCurrentMBLumaNonMBAFF(&TopRight); GetTopLeftLocationForCurrentMBLumaNonMBAFF(&TopLeft); switch (block>>2) { case 0: left_edge_block = 1; top_edge_block = 1; isRightUnavailable = (Top.mb_num<0); isLeftUnavailable = (TopLeft.mb_num<0); break; case 1: left_edge_block = 0; top_edge_block = 1; isRightUnavailable = (TopRight.mb_num<0); isLeftUnavailable = (Top.mb_num<0); break; case 2: left_edge_block = 1; top_edge_block = 0; isRightUnavailable = 0; break; case 3: left_edge_block = 0; top_edge_block = 0; isRightUnavailable = 1; isLeftUnavailable = 0; break; } // block right_edge_block = left_edge_block == 0 ? 1 : 0; break; case SBTYPE_8x4: Top.block_num= Left.block_num= TopLeft.block_num= block2lin[block&(-4)]+4*(block&1); TopRight.block_num= block2lin[block&(-4)]+4*(block&1)+1; GetLeftLocationForCurrentMBLumaNonMBAFF(&Left); GetTopLocationForCurrentMBLumaNonMBAFF(&Top); GetTopRightLocationForCurrentMBLumaNonMBAFF(&TopRight); GetTopLeftLocationForCurrentMBLumaNonMBAFF(&TopLeft); left_edge_block = left_edge_tab16_8x4[block]; top_edge_block = top_edge_tab16_8x4[block]; right_edge_block = right_edge_tab16_8x4[block]; if (!top_edge_block) { isRightUnavailable = (above_right_avail_8x4[block] == 0); if (isRightUnavailable) if (left_edge_block) isLeftUnavailable = (Left.mb_num<0); else isLeftUnavailable = 0; } else { // top edge of 8x4 if (!right_edge_block) { isRightUnavailable = (Top.mb_num<0); isLeftUnavailable = (TopLeft.mb_num<0); } else { isRightUnavailable = (TopRight.mb_num<0); isLeftUnavailable = (Top.mb_num<0); } } break; case SBTYPE_4x8: Top.block_num= Left.block_num= TopLeft.block_num= block2lin[block&(-4)]+(block&1); TopRight.block_num= block2lin[block&(-4)]+(block&1); GetLeftLocationForCurrentMBLumaNonMBAFF(&Left); GetTopLocationForCurrentMBLumaNonMBAFF(&Top); GetTopRightLocationForCurrentMBLumaNonMBAFF(&TopRight); GetTopLeftLocationForCurrentMBLumaNonMBAFF(&TopLeft); // diff = 1; left_edge_block = left_edge_tab16_4x8[block]; top_edge_block = top_edge_tab16_4x8[block]; right_edge_block = right_edge_tab16_4x8[block]; if (!top_edge_block) { isRightUnavailable = (above_right_avail_4x8[block] == 0); isLeftUnavailable = 0; // always, when above right not available } else { if (!right_edge_block) isRightUnavailable = (Top.mb_num<0); else isRightUnavailable = (TopRight.mb_num<0); if (isRightUnavailable) { if (!left_edge_block) isLeftUnavailable = (Top.mb_num<0); else isLeftUnavailable = (TopLeft.mb_num<0); } } break; case SBTYPE_4x4: Top.block_num= Left.block_num= TopLeft.block_num= TopRight.block_num= block2lin[block]; GetLeftLocationForCurrentMBLumaNonMBAFF(&Left); GetTopLocationForCurrentMBLumaNonMBAFF(&Top); GetTopRightLocationForCurrentMBLumaNonMBAFF(&TopRight); GetTopLeftLocationForCurrentMBLumaNonMBAFF(&TopLeft); VM_ASSERT(block >= 0 && block <= 15); // diff = 1; left_edge_block = left_edge_tab16[block]; top_edge_block = top_edge_tab16[block]; right_edge_block = right_edge_tab16[block]; if (!top_edge_block) isRightUnavailable = (above_right_avail_4x4[block] == 0); else { if (!right_edge_block) isRightUnavailable = (Top.mb_num<0); else isRightUnavailable = (TopRight.mb_num<0); } if (isRightUnavailable) { // When not on top edge of MB, for blocks for which right may not // be available, left is always available. if (top_edge_block == 0) isLeftUnavailable = 0; else { if (!left_edge_block) isLeftUnavailable = (Top.mb_num<0); else isLeftUnavailable = (TopLeft.mb_num<0); } } break; } break; default: *pMVx = 0; *pMVy = 0; goto done; } // correct for left edge if (Left.mb_num<0) { sl = &null; pRefIxl = &nullRefIx; } else { sl = &MVs[Left.mb_num].MotionVectors[Left.block_num]; pRefIxl = &RefIdxs[Left.mb_num].RefIdxs[Left.block_num]; } // correct for top edge if (Top.mb_num<0) { sa = &null; pRefIxa = &nullRefIx; } else { sa = &MVs[Top.mb_num].MotionVectors[Top.block_num]; pRefIxa = &RefIdxs[Top.mb_num].RefIdxs[Top.block_num]; } // correct for upper right if (isRightUnavailable) { // replace with block above left if available if (isLeftUnavailable) { sr = &null; pRefIxr = &nullRefIx; } else { sr = &MVs[TopLeft.mb_num].MotionVectors[TopLeft.block_num]; pRefIxr = &RefIdxs[TopLeft.mb_num].RefIdxs[TopLeft.block_num]; } } else { sr = &MVs[TopRight.mb_num].MotionVectors[TopRight.block_num]; pRefIxr = &RefIdxs[TopRight.mb_num].RefIdxs[TopRight.block_num]; } // If above AND right are unavailable AND left is available, use left if ((sa == &null) && (sr == &null) && (sl != &null)) { // return MV at sl *pMVx = sl->mvx; *pMVy = sl->mvy; } else { // Check for more than one predictor from different reference frame // If there is only one predictor from this ref frame, then sonly will // be pointing to it. if ((*pRefIxl) != RefIndex) uSameRefPicCount--; else { sonly = sl; } if ((*pRefIxa) != RefIndex) uSameRefPicCount--; else { sonly = sa; } if ((*pRefIxr) != RefIndex) uSameRefPicCount--; else { sonly = sr; } if (uSameRefPicCount != 1) { // "normal" median prediction px0 = sl->mvx; px1 = sa->mvx; px2 = sr->mvx;#define MEDIAN_OF_3(a, b, c) (MIN((a),(b))) ^ (MIN((b),(c))) ^ (MIN((c),(a))) *pMVx = MEDIAN_OF_3(px0, px1, px2); py0 = sl->mvy; py1 = sa->mvy; py2 = sr->mvy; *pMVy = MEDIAN_OF_3(py0, py1, py2); } else { // return MV at sonly *pMVx = sonly->mvx; *pMVy = sonly->mvy; } } }done: return;} // ComputeMotionVectorPredictors////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -