📄 umc_h264_dec_decode_mb.cpp
字号:
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); GetLeftLocationForCurrentMBLumaMBAFF(&Left); GetTopLocationForCurrentMBLumaMBAFF(&Top,0); GetTopRightLocationForCurrentMBLumaMBAFF(&TopRight); GetTopLeftLocationForCurrentMBLumaMBAFF(&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]; GetLeftLocationForCurrentMBLumaMBAFF(&Left); GetTopLocationForCurrentMBLumaMBAFF(&Top,0); GetTopRightLocationForCurrentMBLumaMBAFF(&TopRight); GetTopLeftLocationForCurrentMBLumaMBAFF(&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]; lbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))>0; lbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Left.mb_num]))<0; } // 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]; tbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))>0; tbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[Top.mb_num]))<0; } // 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]; rbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopLeft.mb_num]))>0; rbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopLeft.mb_num]))<0; } } else { sr = &MVs[TopRight.mb_num].MotionVectors[TopRight.block_num]; pRefIxr = &RefIdxs[TopRight.mb_num].RefIdxs[TopRight.block_num]; rbls=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopRight.mb_num]))>0; rbrs=(pGetMBFieldDecodingFlag(m_cur_mb.GlobalMacroblockInfo)-GetMBFieldDecodingFlag(gmbs[TopRight.mb_num]))<0; } // 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+((sl->mvy<0)&&lbls))<<lbrs)>>lbls; } 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. Ipp32s ls,rs; if (((*pRefIxl<<lbls)>>lbrs) != RefIndex) uSameRefPicCount--; else { sonly = sl; ls=lbls; rs=lbrs; } if (((*pRefIxa<<tbls)>>tbrs) != RefIndex) uSameRefPicCount--; else { sonly = sa; ls=tbls; rs=tbrs; } if (((*pRefIxr<<rbls)>>rbrs) != RefIndex) uSameRefPicCount--; else { sonly = sr; ls=rbls; rs=rbrs; } 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+((sl->mvy<0)&&lbls))<<lbrs)>>lbls; py1 = ((sa->mvy+((sa->mvy<0)&&tbls))<<tbrs)>>tbls; py2 = ((sr->mvy+((sr->mvy<0)&&rbls))<<rbrs)>>rbls; *pMVy = MEDIAN_OF_3(py0, py1, py2); } else { // return MV at sonly *pMVx = sonly->mvx; *pMVy = ((sonly->mvy+((sonly->mvy<0)&&ls))<<rs)>>ls; } } } else { switch (m_cur_mb.GlobalMacroblockInfo->mbtype) { case MBTYPE_FORWARD: case MBTYPE_BACKWARD: case MBTYPE_BIDIR: case MBTYPE_SKIPPED: VM_ASSERT(block == 0); Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0]; Top = m_cur_mb.CurrentBlockNeighbours.mb_above; TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right; TopLeft= m_cur_mb.CurrentBlockNeighbours.mb_above_left; isRightUnavailable = (TopRight.mb_num<0); isLeftUnavailable = (TopLeft.mb_num<0); break; case MBTYPE_INTER_16x8: VM_ASSERT(block >= 0 && block <= 1); // First check for availability of directional predictor which is // just used if available. if (block == 0) { // upper half, use predictor from above Top= m_cur_mb.CurrentBlockNeighbours.mb_above; if (Top.mb_num>=0) { if (IS_INTER_MBTYPE(gmbs[Top.mb_num].mbtype) && (((RefIdxs[Top.mb_num].RefIdxs[Top.block_num])) == RefIndex)) { *pMVx = MVs[Top.mb_num].MotionVectors[Top.block_num].mvx; *pMVy = MVs[Top.mb_num].MotionVectors[Top.block_num].mvy; goto done; } else { goto median16x8_0; } } else {median16x8_0: Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0]; TopRight = m_cur_mb.CurrentBlockNeighbours.mb_above_right; TopLeft = m_cur_mb.CurrentBlockNeighbours.mb_above_left; // init vars for median prediction isRightUnavailable = (TopRight.mb_num<0); if (isRightUnavailable) isLeftUnavailable = (TopLeft.mb_num<0); } } else { Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[2]; // lower half, use predictor from left if ( Left.mb_num>=0) { if (IS_INTER_MBTYPE(gmbs[Left.mb_num].mbtype) && (((RefIdxs[Left.mb_num].RefIdxs[Left.block_num])) == RefIndex)) { *pMVx = MVs[Left.mb_num].MotionVectors[Left.block_num].mvx; *pMVy = MVs[Left.mb_num].MotionVectors[Left.block_num].mvy; goto done; } else { goto median_16x8_1; } } else {median_16x8_1: Top.mb_num = m_CurMBAddr; Top.block_num = 4; TopLeft.block_num = 8; GetTopLeftLocationForCurrentMBLumaNonMBAFF(&TopLeft); // init vars for median prediction isRightUnavailable = 1; isLeftUnavailable = (Left.mb_num<0); } } break; case MBTYPE_INTER_8x16: VM_ASSERT(block >= 0 && block <= 1); // First check for availability of directional predictor which is // just used if available. if (block == 0) { // left half, use predictor from left //LeftBlockNum = block; //LeftMB=GetLeftBlock(pMBInfo,LeftBlockNum); Left = m_cur_mb.CurrentBlockNeighbours.mbs_left[0]; if (Left.mb_num>=0) { if (IS_INTER_MBTYPE(gmbs[Left.mb_num].mbtype) && (((RefIdxs[Left.mb_num].RefIdxs[Left.block_num])) == RefIndex)) { *pMVx = MVs[Left.mb_num].MotionVectors[Left.block_num].mvx; *pMVy = MVs[Left.mb_num].MotionVectors[Left.block_num].mvy; goto done; } else { goto median_8x16_0; } } else {median_8x16_0: /* TopBlockNum=0; TopLeftBlockNum=0; TopRightBlockNum=1; TopMB=GetTopBlock(pMBInfo,TopBlockNum); TopLeftMB=GetTopLeftBlock(pMBInfo,TopLeftBlockNum);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -