📄 mbdatactrl.cpp
字号:
{
Int iBase8x8MbPartIdx = 0; // index of top-left 8x8 block that is covered by the macroblock partition
Int iBase4x4SubMbPartIdx = 0; // index of top-left 4x4 block that is covered by the sub-macroblock partition (inside 8x8 block)
Int iBaseMbIdx = MSYS_INT_MAX;
Int iXInsideBaseMb = MSYS_INT_MAX;
Int iYInsideBaseMb = MSYS_INT_MAX;
RNOK( xGetRefLayerMb( iXInsideCurrMb, iYInsideCurrMb, iBaseMbIdx, iXInsideBaseMb, iYInsideBaseMb ) );
//===== check whether available =====
if( iBaseMbIdx == MSYS_INT_MAX )
{
riPartIdc = -2; // not available
return Err::m_nOK;
}
//===== check whether intra =====
MbData& rcMbDataBase = m_rcMbDataCtrlBase.getMbDataByIndex( (UInt)iBaseMbIdx );
if( rcMbDataBase.isIntra() )
{
riPartIdc = -1; // intra
return Err::m_nOK;
}
Int iB8x8IdxBase = ( ( iYInsideBaseMb >> 3 ) << 1 ) + ( iXInsideBaseMb >> 3 );
Int iB4x4IdxBase = ( ( ( iYInsideBaseMb & 7 ) >> 2 ) << 1 ) + ( ( iXInsideBaseMb & 7 ) >> 2 );
MbMode eMbModeBase = rcMbDataBase.getMbMode ();
BlkMode eBlkModeBase = rcMbDataBase.getBlkMode( Par8x8( iB8x8IdxBase ) );
Bool bBSkipOrDirect = ( eMbModeBase == MODE_SKIP && rcMbDataBase.getSliceType() == B_SLICE );
ROT( rcMbDataBase.getSliceType() == NOT_SPECIFIED_SLICE ); // check whether slice type is set
if( bBSkipOrDirect )
{
//===== determine macroblock and sub-macroblock partition index for B_Skip and B_Direct_16x16 =====
if( m_iRefLayerDQId == 0 )
{
iBase8x8MbPartIdx = iB8x8IdxBase;
iBase4x4SubMbPartIdx = iB4x4IdxBase;
}
}
else
{
const UInt aauiNxNPartIdx[6][4] =
{
{ 0, 0, 0, 0 }, // MODE_SKIP (P Slice)
{ 0, 0, 0, 0 }, // MODE_16x16 or BLK_8x8
{ 0, 0, 2, 2 }, // MODE_16x8 or BLK_8x4
{ 0, 1, 0, 1 }, // MODE_8x16 or BLK_4x8
{ 0, 1, 2, 3 }, // MODE_8x8 or BLK_4x4
{ 0, 1, 2, 3 } // MODE_8x8ref0
};
//===== determine macroblock partition index =====
iBase8x8MbPartIdx = aauiNxNPartIdx[ eMbModeBase ][ iB8x8IdxBase ];
//===== determine sub-macroblock partition index =====
if( eMbModeBase == MODE_8x8 || eMbModeBase == MODE_8x8ref0 )
{
if( eBlkModeBase == BLK_SKIP )
{
if( m_iRefLayerDQId == 0 )
{
iBase4x4SubMbPartIdx = iB4x4IdxBase;
}
}
else
{
iBase4x4SubMbPartIdx = aauiNxNPartIdx[ eBlkModeBase - BLK_8x8 + 1 ][ iB4x4IdxBase ];
}
}
}
//===== set partition indication =====
Int iBase4x4BlkX = ( ( iBase8x8MbPartIdx & 1 ) << 1 ) + ( iBase4x4SubMbPartIdx & 1 );
Int iBase4x4BlkY = ( ( iBase8x8MbPartIdx >> 1 ) << 1 ) + ( iBase4x4SubMbPartIdx >> 1 );
Int iBase4x4BlkIdx = ( iBase4x4BlkY << 2 ) + iBase4x4BlkX;
riPartIdc = ( iBaseMbIdx << 4 ) + iBase4x4BlkIdx;
return Err::m_nOK;
}
//===== this function implements subclause G.8.6.1.1 =====
ErrVal
MotionUpsampling::xSetPartIdcArray()
{
ROFRS( m_bInCropWindow, Err::m_nOK );
//===== determine all 16 initial partition indexes =====
{
m_bIntraBL = true;
for( Int iY = 0; iY < 4; iY++ )
for( Int iX = 0; iX < 4; iX++ )
{
RNOK( xGetRefLayerPartIdc( ( iX << 2 ) + 1, ( iY << 2 ) + 1, m_aaiPartIdc[iX][iY] ) );
m_bIntraBL = ( m_bIntraBL && ( m_aaiPartIdc[iX][iY] == -1 ) );
}
if( m_bIntraBL )
{
m_eMbMode = INTRA_BL;
}
}
ROTRS( m_bIntraBL, Err::m_nOK );
ROTRS( m_cPosCalc.m_bRSChangeFlag, Err::m_nOK );
//===== replace values of "-1" on a 4x4 block basis =====
{
for( Int iYP = 0; iYP < 2; iYP++ )
for( Int iXP = 0; iXP < 2; iXP++ )
{
Bool aabProcI4x4Blk[2][2] = { { false, false }, { false, false } };
for( Int iYS = 0; iYS < 2; iYS++ )
for( Int iXS = 0; iXS < 2; iXS++ )
{
Int iYC = ( iYP << 1 ) + iYS;
Int iXC = ( iXP << 1 ) + iXS;
if( m_aaiPartIdc[iXC][iYC] == -1 )
{
Int iYSInv = 1 - iYS;
Int iXSInv = 1 - iXS;
Int iYCInv = ( iYP << 1 ) + iYSInv;
Int iXCInv = ( iXP << 1 ) + iXSInv;
aabProcI4x4Blk[iXS][iYS] = true;
if( ! aabProcI4x4Blk[iXSInv][iYS] && m_aaiPartIdc[iXCInv][iYC] != -1 )
{
m_aaiPartIdc[iXC][iYC] = m_aaiPartIdc[iXCInv][iYC];
}
else if( ! aabProcI4x4Blk[iXS][iYSInv] && m_aaiPartIdc[iXC][iYCInv] != -1 )
{
m_aaiPartIdc[iXC][iYC] = m_aaiPartIdc[iXC][iYCInv];
}
else if( ! aabProcI4x4Blk[iXSInv][iYSInv] && m_aaiPartIdc[iXCInv][iYCInv] != -1 )
{
m_aaiPartIdc[iXC][iYC] = m_aaiPartIdc[iXCInv][iYCInv];
}
}
}
}
}
//===== replace values of "-1" on an 8x8 block basis =====
{
Bool aabProcI8x8Blk[2][2] = { { false, false }, { false, false } };
for( Int iYP = 0; iYP < 2; iYP++ )
for( Int iXP = 0; iXP < 2; iXP++ )
{
Int iYPInv = 1 - iYP;
Int iXPInv = 1 - iXP;
Int iYO = ( iYP << 1 );
Int iXO = ( iXP << 1 );
Int iYOInv = ( 2 - iYP );
Int iXOInv = ( 2 - iXP );
if( m_aaiPartIdc[iXO][iYO] == -1 )
{
aabProcI8x8Blk[iXP][iYP] = true;
if( ! aabProcI8x8Blk[iXPInv][iYP] && m_aaiPartIdc[iXOInv][iYO] != -1 )
{
m_aaiPartIdc[iXO ][iYO ] = m_aaiPartIdc[iXOInv][iYO ];
m_aaiPartIdc[iXO+1][iYO ] = m_aaiPartIdc[iXOInv][iYO ];
m_aaiPartIdc[iXO ][iYO+1] = m_aaiPartIdc[iXOInv][iYO+1];
m_aaiPartIdc[iXO+1][iYO+1] = m_aaiPartIdc[iXOInv][iYO+1];
}
else if( ! aabProcI8x8Blk[iXP][iYPInv] && m_aaiPartIdc[iXO][iYOInv] != -1 )
{
m_aaiPartIdc[iXO ][iYO ] = m_aaiPartIdc[iXO ][iYOInv];
m_aaiPartIdc[iXO+1][iYO ] = m_aaiPartIdc[iXO+1][iYOInv];
m_aaiPartIdc[iXO ][iYO+1] = m_aaiPartIdc[iXO ][iYOInv];
m_aaiPartIdc[iXO+1][iYO+1] = m_aaiPartIdc[iXO+1][iYOInv];
}
else if( ! aabProcI8x8Blk[iXPInv][iYPInv] && m_aaiPartIdc[iXOInv][iYOInv] != -1 )
{
m_aaiPartIdc[iXO ][iYO ] = m_aaiPartIdc[iXOInv][iYOInv];
m_aaiPartIdc[iXO+1][iYO ] = m_aaiPartIdc[iXOInv][iYOInv];
m_aaiPartIdc[iXO ][iYO+1] = m_aaiPartIdc[iXOInv][iYOInv];
m_aaiPartIdc[iXO+1][iYO+1] = m_aaiPartIdc[iXOInv][iYOInv];
}
}
}
}
return Err::m_nOK;
}
//===== this function implements the reference index and motion vector scaling of subclause G.8.6.1.2 =====
ErrVal
MotionUpsampling::xGetInitialBaseRefIdxAndMv( Int i4x4BlkX,
Int i4x4BlkY,
ListIdx eListIdx,
Int iPartIdc,
Int& riRefIdx,
Mv& rcMv )
{
Int iMbIdxBase = iPartIdc >> 4;
B4x4Idx c4x4IdxBase = iPartIdc & 15;
MbData& rcMbDataBase = m_rcMbDataCtrlBase.getMbDataByIndex ( (UInt)iMbIdxBase );
Int iCurrFieldMb = ( m_bCurrFieldMb ? 1 : 0 );
Int iBaseFieldMb = ( rcMbDataBase .getFieldFlag() ? 1 : 0 );
MbMotionData& rcMotionDataBase = rcMbDataBase .getMbMotionData ( eListIdx );
Int iRefIdxBase = rcMotionDataBase.getRefIdx ( c4x4IdxBase );
const Mv& rcMvBase = rcMotionDataBase.getMv ( c4x4IdxBase );
if( iRefIdxBase < 1 )
{
riRefIdx = BLOCK_NOT_PREDICTED;
rcMv = Mv::ZeroMv();
return Err::m_nOK;
}
//===== set reference index and convert motion vector to frame motion vector =====
riRefIdx = ( ( ( iRefIdxBase - 1 ) << ( iCurrFieldMb - m_cMvScale.m_iCurrField ) ) >> ( iBaseFieldMb - m_cMvScale.m_iBaseField ) ) + 1;
Int iMvX = rcMvBase.getHor();
Int iMvY = rcMvBase.getVer() * ( 1 + iBaseFieldMb );
//===== get motion vector scaling factors =====
Bool bCropChange = ( m_cMvScale.m_bCropChangeFlag && riRefIdx <= m_cMvScale.m_aiNumActive[eListIdx] );
Int idOX = 0;
Int idOY = 0;
Int idSW = 0;
Int idSH = 0;
Int iScaleX = m_cMvScale.m_iScaleX;
Int iScaleY = m_cMvScale.m_iScaleY;
if( bCropChange )
{
idOX = m_cMvScale.m_aaidOX[eListIdx][riRefIdx-1];
idOY = m_cMvScale.m_aaidOY[eListIdx][riRefIdx-1];
idSW = m_cMvScale.m_aaidSW[eListIdx][riRefIdx-1];
idSH = m_cMvScale.m_aaidSH[eListIdx][riRefIdx-1];
iScaleX = ( ( ( m_cMvScale.m_iScaledW + idSW ) << 16 ) + ( m_cMvScale.m_iRefW >> 1 ) ) / m_cMvScale.m_iRefW;
iScaleY = ( ( ( m_cMvScale.m_iScaledH + idSH ) << 16 ) + ( m_cMvScale.m_iRefH >> 1 ) ) / m_cMvScale.m_iRefH;
}
//===== get scaled motion vector components =====
iMvX = ( iMvX * iScaleX + 32768 ) >> 16;
iMvY = ( iMvY * iScaleY + 32768 ) >> 16;
//===== add correction vector =====
if( bCropChange )
{
Int iFldInFrame = ( m_cMvScale.m_iCurrMbAff && m_bCurrFieldMb ? 1 : 0 );
Int iMbPosX = ( m_iMbXCurr << 4 );
Int iMbPosY = ( ( m_iMbYCurr >> iFldInFrame ) << ( 4 + iFldInFrame ) ) + ( m_iMbYCurr & iFldInFrame );
Int iXFrm = iMbPosX + ( ( i4x4BlkX << 2 ) + 1 );
Int iYFrm = ( iMbPosY + ( ( ( i4x4BlkX << 2 ) + 1 ) << ( iCurrFieldMb - m_cMvScale.m_iCurrField ) ) ) << m_cMvScale.m_iCurrField;
Int iX = iXFrm - m_cMvScale.m_iOffsetX;
Int iY = iYFrm - m_cMvScale.m_iOffsetY;
iScaleX = ( ( ( 4 * idSW ) << 16 ) + ( m_cMvScale.m_iScaledW >> 1 ) ) / m_cMvScale.m_iScaledW;
iScaleY = ( ( ( 4 * idSH ) << 16 ) + ( m_cMvScale.m_iScaledH >> 1 ) ) / m_cMvScale.m_iScaledH;
iMvX += ( ( iX * iScaleX + 32768 ) >> 16 ) - 4 * idOX;
iMvY += ( ( iY * iScaleY + 32768 ) >> 16 ) - 4 * idOY;
}
//===== set mv predictor (scale to field vector when required) =====
rcMv.set( (Short)iMvX, (Short)( iMvY / ( 1 + iCurrFieldMb ) ) );
return Err::m_nOK;
}
//===== this function implements the function MinPositive() specified in subclause G.8.6.1.2 =====
Int
MotionUpsampling::xGetMinRefIdx( Int iRefIdxA, Int iRefIdxB )
{
ROTRS( iRefIdxA < 1, iRefIdxB );
ROTRS( iRefIdxB < 1, iRefIdxA );
return min( iRefIdxA, iRefIdxB );
}
//===== this function implements the first part of subclause G.8.6.1.2 =====
ErrVal
MotionUpsampling::xGetRefIdxAndInitialMvPred( ListIdx eListIdx )
{
//===== get initial predictors for reference indices and motion vectors =====
{
for( Int i4x4BlkY = 0; i4x4BlkY < 4; i4x4BlkY++ )
for( Int i4x4BlkX = 0; i4x4BlkX < 4; i4x4BlkX++ )
{
RNOK( xGetInitialBaseRefIdxAndMv( i4x4BlkX, i4x4BlkY, eListIdx, m_aaiPartIdc[i4x4BlkX][i4x4BlkY],
m_aaiRefIdxTemp[i4x4BlkX][i4x4BlkY], m_aaacMv[eListIdx][i4x4BlkX][i4x4BlkY] ) );
}
}
//===== set reference indices =====
m_aaaiRefIdx[eListIdx][0][0] = m_aaiRefIdxTemp[0][0];
m_aaaiRefIdx[eListIdx][0][1] = m_aaiRefIdxTemp[0][2];
m_aaaiRefIdx[eListIdx][1][0] = m_aaiRefIdxTemp[2][0];
m_aaaiRefIdx[eListIdx][1][1] = m_aaiRefIdxTemp[2][2];
ROTRS( m_cMvScale.m_bRSChangeFlag, Err::m_nOK );
//===== merge reference indices and modify motion vectors accordingly =====
for( Int i8x8BlkY = 0; i8x8BlkY < 2; i8x8BlkY++ )
for( Int i8x8BlkX = 0; i8x8BlkX < 2; i8x8BlkX++ )
{
//----- determine reference indices -----
for( Int i4x4BlkY = 0; i4x4BlkY < 2; i4x4BlkY++ )
for( Int i4x4BlkX = 0; i4x4BlkX < 2; i4x4BlkX++ )
{
Int iY = ( i8x8BlkY << 1 ) + i4x4BlkY;
Int iX = ( i8x8BlkX << 1 ) + i4x4BlkX;
m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] = xGetMinRefIdx( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY], m_aaiRefIdxTemp[iX][iY] );
}
//----- update motion vectors -----
for( Int iYS = 0; iYS < 2; iYS++ )
for( Int iXS = 0; iXS < 2; iXS++ )
{
Int iY = ( i8x8BlkY << 1 ) + iYS;
Int iX = ( i8x8BlkX << 1 ) + iXS;
if( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] != m_aaiRefIdxTemp[iX][iY] )
{
Int iYInv = ( i8x8BlkY << 1 ) + 1 - iYS;
Int iXInv = ( i8x8BlkX << 1 ) + 1 - iXS;
if( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] == m_aaiRefIdxTemp[iXInv][iY] )
{
m_aaacMv[eListIdx][iX][iY] = m_aaacMv[eListIdx][iXInv][iY];
}
else if( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] == m_aaiRefIdxTemp[iX][iYInv] )
{
m_aaacMv[eListIdx][iX][iY] = m_aaacMv[eListIdx][iX][iYInv];
}
else
{
ROF( m_aaaiRefIdx[eListIdx][i8x8BlkX][i8x8BlkY] == m_aaiRefIdxTemp[iXInv][iYInv] );
m_aaacMv[eListIdx][iX][iY] = m_aaacMv[eListIdx][iXInv][iYInv];
}
}
}
}
return Err::m_nOK;
}
//===== this function implements the function mvDiff specified in subclause G.8.6.1.2 =====
Int
MotionUpsampling::xMvDiff( const Mv& rcMvA, const Mv& rcMbB )
{
return rcMvA.getAbsHorDiff( rcMbB ) + rcMvA.getAbsVerDiff( rcMbB );
}
//===== this function implements subclause G.8.6.1.2 =====
ErrVal
MotionUpsampling::xDeriveBlockModeAndUpdateMv( Int i8x8BlkIdx )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -