📄 umc_h264_segment_decoder_decode_mb.cpp
字号:
block2lin[block&(-4)]+4*(block&1);
TopRight.block_num=
block2lin[block&(-4)]+4*(block&1)+1;
GetLeftLocationForCurrentMBLumaMBAFF(&Left);
GetTopLocationForCurrentMBLumaMBAFF(&Top,0);
GetTopRightLocationForCurrentMBLumaMBAFF(&TopRight);
GetTopLeftLocationForCurrentMBLumaMBAFF(&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);
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;
return; // DEBUG : may be throw ???
}
// 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 = 0, rs = 0;
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) (IPP_MIN((a),(b))) ^ (IPP_MIN((b),(c))) ^ (IPP_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;
return;
}
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;
return;
}
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -