📄 intraprediction.cpp
字号:
Void IntraPrediction::xPredMode2Dc( XPel* puc, Int iStride ) // DC Prediction
{
UInt uiDcValue;
if( ! xIsLeftRef() )
{
if( ! xIsAboveRef() )
{
uiDcValue = 0x80;
}
else
{
// uiDcValue = (A + B + C + D + 2) >> 2;
uiDcValue = puc[-iStride];
uiDcValue += puc[1-iStride];
uiDcValue += puc[2-iStride];
uiDcValue += puc[3-iStride];
uiDcValue += 2;
uiDcValue >>= 2;
}
}
else
{
if( ! xIsAboveRef() )
{
// uiDcValue = (I + J + K + L + 2) >> 2;
uiDcValue = puc[-1];
uiDcValue += puc[iStride-1];
uiDcValue += puc[2*iStride-1];
uiDcValue += puc[3*iStride-1];
uiDcValue += 2;
uiDcValue >>= 2;
}
else
{
// uiDcValue = ( A + B + C + D + I + J + K + L + 4) >> 3;
uiDcValue = puc[-iStride];
uiDcValue += puc[1-iStride];
uiDcValue += puc[2-iStride];
uiDcValue += puc[3-iStride];
uiDcValue += puc[-1];
uiDcValue += puc[iStride-1];
uiDcValue += puc[2*iStride-1];
uiDcValue += puc[3*iStride-1];
uiDcValue += 4;
uiDcValue >>= 3;
}
}
Int n;
for( n=0; n<4; n++ ) puc[n] = uiDcValue;
puc += iStride;
for( n=0; n<4; n++ ) puc[n] = uiDcValue;
puc += iStride;
for( n=0; n<4; n++ ) puc[n] = uiDcValue;
puc += iStride;
for( n=0; n<4; n++ ) puc[n] = uiDcValue;
}
Void IntraPrediction::xPredMode3DiagDownLeft( XPel* puc, Int iStride ) // Diagonal Down Left Pred
{
AOF( xIsAboveRef() );
UInt A,B,C,D;
UInt E,F,G,H;
xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
xLoadPredictorsEFGH ( puc, iStride, E, F, G, H );
puc[0] = (A + 2*B + C + 2) >> 2;
puc[1] = puc[iStride+0] = (B + 2*C + D + 2) >> 2;
puc[2] = puc[iStride+1] = puc[2*iStride+0] = (C + 2*D + E + 2) >> 2;
puc[3] = puc[iStride+2] = puc[2*iStride+1] = puc[3*iStride+0] = (D + 2*E + F + 2) >> 2;
puc[iStride+3] = puc[2*iStride+2] = puc[3*iStride+1] = (E + 2*F + G + 2) >> 2;
puc[2*iStride+3] = puc[3*iStride+2] = (F + 2*G + H + 2) >> 2;
puc[3*iStride+3] = (G + 2*H + H + 2) >> 2;
}
Void IntraPrediction::xPredMode4DiagDownRight( XPel* puc, Int iStride ) // Diagonal Down Right Pred
{
AOF( xIsAllLeftAboveRef() )
UInt A,B,C,D;
UInt I,J,K,L;
UInt X;
xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );
xLoadPredictorsX ( puc, iStride, X );
puc[3] = (B + 2 * C + D + 2)/4;
puc[2] = puc[iStride+3] = (A + 2 * B + C + 2)/4;
puc[1] = puc[iStride+2] = puc[2*iStride+3] = (X + 2 * A + B + 2)/4;
puc[0] = puc[iStride+1] = puc[2*iStride+2] = puc[3*iStride+3] = (A + 2 * X + I + 2)/4;
puc[iStride+0] = puc[2*iStride+1] = puc[3*iStride+2] = (X + 2 * I + J + 2)/4;
puc[2*iStride+0] = puc[3*iStride+1] = (I + 2 * J + K + 2)/4;
puc[3*iStride+0] = (J + 2 * K + L + 2)/4;
}
Void IntraPrediction::xPredMode5VertRight( XPel* puc, Int iStride ) // Vertical Right Pred
{
AOF( xIsAllLeftAboveRef() )
UInt A,B,C,D;
UInt I,J,K,L;
UInt X;
xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );
xLoadPredictorsX ( puc, iStride, X );
puc[0] = puc[2*iStride+1] = (X + A + 1) >> 1;
puc[1] = puc[2*iStride+2] = (A + B + 1) >> 1;
puc[2] = puc[2*iStride+3] = (B + C + 1) >> 1;
puc[3] = (C + D + 1) >> 1;
puc[iStride+0] = puc[3*iStride+1] = (I + 2*X + A + 2) >> 2;
puc[iStride+1] = puc[3*iStride+2] = (X + 2*A + B + 2) >> 2;
puc[iStride+2] = puc[3*iStride+3] = (A + 2*B + C + 2) >> 2;
puc[iStride+3] = (B + 2*C + D + 2) >> 2;
puc[2*iStride] = (X + 2*I + J + 2) >> 2;
puc[3*iStride] = (I + 2*J + K + 2) >> 2;
}
Void IntraPrediction::xPredMode6HorizDown( XPel* puc, Int iStride ) // Horizontal DownPred
{
AOF( xIsAllLeftAboveRef() )
UInt A,B,C,D;
UInt I,J,K,L;
UInt X;
xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );
xLoadPredictorsX ( puc, iStride, X );
puc[0] = puc[iStride+2] = (X + I + 1) >> 1;
puc[1] = puc[iStride+3] = (I + 2*X + A + 2) >> 2;
puc[2] = (X + 2*A + B + 2) >> 2;
puc[3] = (A + 2*B + C + 2) >> 2;
puc[iStride+0] = puc[2*iStride+2] = (I + J + 1) >> 1;
puc[iStride+1] = puc[2*iStride+3] = (X + 2*I + J + 2) >> 2;
puc[2*iStride+0] = puc[3*iStride+2] = (J + K + 1) >> 1;
puc[2*iStride+1] = puc[3*iStride+3] = (I + 2*J + K + 2) >> 2;
puc[3*iStride+0] = (K + L + 1) >> 1;
puc[3*iStride+1] = (J + 2*K + L + 2) >> 2;
}
Void IntraPrediction::xPredMode7VertLeft( XPel* puc, Int iStride ) // Vertical Left Pred
{
AOF( xIsAboveRef() ); //!!!
UInt A,B,C,D;
UInt E,F,G,H;
xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
xLoadPredictorsEFGH ( puc, iStride, E, F, G, H );
puc[0] = (A + B + 1) >> 1;
puc[1] = puc[2*iStride+0] = (B + C + 1) >> 1;
puc[2] = puc[2*iStride+1] = (C + D + 1) >> 1;
puc[3] = puc[2*iStride+2] = (D + E + 1) >> 1;
puc[2*iStride+3] = (E + F + 1) >> 1;
puc[iStride+0] = (A + 2*B + C + 2) >> 2;
puc[iStride+1] = puc[3*iStride+0] = (B + 2*C + D + 2) >> 2;
puc[iStride+2] = puc[3*iStride+1] = (C + 2*D + E + 2) >> 2;
puc[iStride+3] = puc[3*iStride+2] = (D + 2*E + F + 2) >> 2;
puc[3*iStride+3] = (E + 2*F + G + 2) >> 2;
}
Void IntraPrediction::xPredMode8HorizUp( XPel* puc, Int iStride ) // Horizontal Up Pred
{
AOF( xIsLeftRef() ); //!!!
UInt I,J,K,L;
xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );
puc[0] = (I + J + 1) >> 1;
puc[1] = (I + 2*J + K + 2) >> 2;
puc[2] = puc[iStride + 0] = (J + K + 1) >> 1;
puc[3] = puc[iStride + 1] = (J + 2*K + L + 2) >> 2;
puc[iStride + 2] = puc[2*iStride + 0] = (K + L + 1) >> 1;
puc[iStride + 3] = puc[2*iStride + 1] = (K + 2*L + L + 2) >> 2;
puc[2*iStride + 2] = puc[3*iStride + 0] =
puc[2*iStride + 3] = puc[3*iStride + 1] =
puc[3*iStride + 2] = puc[3*iStride + 3] = L;
}
Void IntraPrediction::xPred8x8IMode2Vert( XPel* puc, Int iStride ) // vertical
{
AOF( xIsAboveRef() );
for( UInt n = 0; n < 8; n++ )
{
::memcpy( puc, puc - iStride, 8*sizeof(XPel) );
puc += iStride;
}
}
Void IntraPrediction::xPred8x8IMode1Hori( XPel* puc, Int iStride ) // horizontal
{
AOF( xIsLeftRef() );
for( UInt n = 0; n < 8; n++ )
{
for( UInt m = 0; m < 8; m++ )
{
puc[m] = puc[m-1];
}
puc += iStride;
}
}
Void IntraPrediction::xPred8x8IMode0DC( XPel* puc, Int iStride ) // DC prediction
{
UInt uiA, uiB, uiC, uiD;
if( ! xIsAboveRef() )
{
if( m_uiAvailableMaskMb & 0x1 ) // top
{
uiA = uiB = 0x80;
}
else
{
uiA = uiB = (xGetS2( puc, iStride ) + 2) / 4;
}
if( m_uiAvailableMaskMb & 0x10 ) // bot
{
uiC = uiD = 0x80;
}
else
{
uiC = uiD = (xGetS3( puc, iStride ) + 2) / 4;
}
}
else
{
UInt uiS0 = xGetS0( puc, iStride );
UInt uiS1 = xGetS1( puc, iStride );
if( m_uiAvailableMaskMb & 0x1 ) // top
{
uiA = (uiS0 + 2)/4;
uiB = (uiS1 + 2)/4;
}
else
{
UInt uiS2 = xGetS2( puc, iStride );
uiA = (uiS0 + uiS2 + 4)/8;
uiB = (uiS1 + 2)/4;
}
if( m_uiAvailableMaskMb & 0x10 ) // bot
{
uiC = (uiS0 + 2)/4;
uiD = (uiS1 + 2)/4;
}
else
{
UInt uiS3 = xGetS3( puc, iStride );
uiC = (uiS3 + 2)/4;
uiD = (uiS1 + uiS3 + 4)/8;
}
}
Int pos;
XPel* pucDes = puc;
for( pos = 0; pos < 4; pos++)
{
pucDes[pos] = uiA;
pucDes[pos + 4] = uiB;
}
for( Int n1 = 0; n1 < 3; n1 ++ )
{
memcpy( pucDes + iStride, pucDes, 8 * sizeof( XPel ) );
pucDes += iStride;
}
pucDes += iStride;
for( pos = 0; pos < 4; pos++)
{
pucDes[pos] = uiC;
pucDes[pos + 4] = uiD;
}
for( Int n2 = 0; n2 < 3; n2 ++ )
{
memcpy( pucDes + iStride, pucDes, 8 * sizeof( XPel ) );
pucDes += iStride;
}
}
Void IntraPrediction::xPred8x8IMode3Plane( XPel* puc, Int iStride ) // plane prediction
{
Int n, m;
Int iH = 0;
Int iV = 0;
AOF( xIsAllLeftAboveRef() );
XPel* pucDes = puc;
puc += 3 - iStride;
for( n = 1; n < 5; n++ )
{
iH += n * (Int)(puc[n] - puc[-n]);
}
puc += (iStride << 2) - 4;
for( m = iStride, n = 1; n < 5; n++, m += iStride)
{
iV += n * (Int)(puc[m] - puc[-m]);
}
puc -= 3 * iStride - 1;
Int iB = (17 * iH + 16) >> 5;
Int iC = (17 * iV + 16) >> 5;
Int iA = 16 * (Int)(puc[(iStride << 3) - (iStride + 1)] + puc[ 7 - iStride ]);
Int x, y;
for( y = 0; y < 8; y++ )
{
Int iYSum = iA + (y-3) * iC + 16;
for( x = 0; x < 8; x++ )
{
pucDes[x] = gClip((iYSum + (x-3) * iB) >> 5);
}
pucDes += iStride;
}
}
ErrVal IntraPrediction::predictLumaBlock( XPel* puc, Int iStride, UInt uiPredMode, LumaIdx cIdx )
{
m_uiAvailable = xGetAvailableMask( cIdx );
switch( uiPredMode )
{
case 0:
{
xPredMode0Vert( puc, iStride );
break;
}
case 1:
{
xPredMode1Horiz( puc, iStride );
break;
}
case 2:
{
xPredMode2Dc( puc, iStride );
break;
}
case 3:
{
xPredMode3DiagDownLeft( puc, iStride );
break;
}
case 4:
{
xPredMode4DiagDownRight( puc, iStride );
break;
}
case 5:
{
xPredMode5VertRight( puc, iStride );
break;
}
case 6:
{
xPredMode6HorizDown( puc, iStride );
break;
}
case 7:
{
xPredMode7VertLeft( puc, iStride );
break;
}
case 8:
{
xPredMode8HorizUp( puc, iStride );
break;
}
default:
{
assert( 0 );
return Err::m_nERR;
}
}
return Err::m_nOK;
}
ErrVal IntraPrediction::predictLumaMb( XPel* puc, Int iStride, UInt uiPredMode )
{
m_uiAvailable = ( m_uiAvailableMaskMb >> 4 ) | m_uiAvailableMaskMb;
switch( uiPredMode & 0xf )
{
case 0:
{
xPred16x16IMode0Vert ( puc, iStride );
break;
}
case 1:
{
xPred16x16IMode1Hori ( puc, iStride );
break;
}
case 2:
{
xPred16x16IMode2DC ( puc, iStride );
break;
}
case 3:
{
xPred16x16IMode3Plane ( puc, iStride );
break;
}
default:
{
assert( 0 );
return Err::m_nERR;
}
}
return Err::m_nOK;
}
ErrVal IntraPrediction::predictChromaBlock( XPel* pucCb, XPel* pucCr, Int iStride, UInt uiPredMode )
{
m_uiAvailable = ( m_uiAvailableMaskMb >> 4 ) | m_uiAvailableMaskMb;
switch( uiPredMode )
{
case 0:
{
xPred8x8IMode0DC ( pucCb, iStride );
xPred8x8IMode0DC ( pucCr, iStride );
break;
}
case 1:
{
xPred8x8IMode1Hori ( pucCb, iStride );
xPred8x8IMode1Hori ( pucCr, iStride );
break;
}
case 2:
{
xPred8x8IMode2Vert ( pucCb, iStride );
xPred8x8IMode2Vert ( pucCr, iStride );
break;
}
case 3:
{
xPred8x8IMode3Plane ( pucCb, iStride );
xPred8x8IMode3Plane ( pucCr, iStride );
break;
}
default:
{
assert( 0 );
return Err::m_nERR;
}
}
return Err::m_nOK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -