📄 umc_h264_segment_decoder_decode_mb.cpp
字号:
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;
return;
}
else
{
goto median_8x16_0;
}
}
else
{
median_8x16_0:
/* TopBlockNum=0;
TopLeftBlockNum=0;
TopRightBlockNum=1;
TopMB=GetTopBlock(pMBInfo,TopBlockNum);
TopLeftMB=GetTopLeftBlock(pMBInfo,TopLeftBlockNum);
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;
return;
}
}
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;
return;
}
}
//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 = 0, top_edge_block = 0, right_edge_block = 0;
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;
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];
}
// 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -