📄 intraprediction.cpp
字号:
Void IntraPrediction::xSet8x8AvailableMask( B8x8Idx cIdx )
{
B4x4Idx c4x4Idx( cIdx );
UInt uiM1 = xGetAvailableMask( c4x4Idx );
c4x4Idx++;
UInt uiM2 = xGetAvailableMask( c4x4Idx );
m_uiAvailable = 0;
m_uiAvailable |= uiM2&8;
m_uiAvailable |= uiM1&7;
m_bSpecial = ( cIdx.b8x8Index() == 1 );
}
ErrVal IntraPrediction::predictLuma8x8Block( XPel* puc, Int iStride, UInt uiPredMode, B8x8Idx cIdx )
{
xSet8x8AvailableMask( cIdx );
switch( uiPredMode )
{
case 0:
{
xPredLum8x8Mode0Vert( puc, iStride );
ROFRS( xIsAboveRef(), Err::m_nDataNotAvailable );
break;
}
case 1:
{
xPredLum8x8Mode1Horiz( puc, iStride );
ROFRS( xIsLeftRef(), Err::m_nDataNotAvailable );
break;
}
case 2:
{
xPredLum8x8Mode2Dc( puc, iStride );
break;
}
case 3:
{
xPredLum8x8Mode3DiagDownLeft( puc, iStride );
ROFRS( xIsAboveRef(), Err::m_nDataNotAvailable );
break;
}
case 4:
{
xPredLum8x8Mode4DiagDownRight( puc, iStride );
ROFRS( xIsAllLeftAboveRef(), Err::m_nDataNotAvailable );
break;
}
case 5:
{
xPredLum8x8Mode5VertRight( puc, iStride );
ROFRS( xIsAllLeftAboveRef(), Err::m_nDataNotAvailable );
break;
}
case 6:
{
xPredLum8x8Mode6HorizDown( puc, iStride );
ROFRS( xIsAllLeftAboveRef(), Err::m_nDataNotAvailable );
break;
}
case 7:
{
xPredLum8x8Mode7VertLeft( puc, iStride );
ROFRS( xIsAboveRef(), Err::m_nDataNotAvailable );
break;
}
case 8:
{
xPredLum8x8Mode8HorizUp( puc, iStride );
ROFRS( xIsLeftRef(), Err::m_nDataNotAvailable );
break;
}
default:
{
assert( 0 );
return Err::m_nInvalidParameter;
}
}
return Err::m_nOK;
}
Void IntraPrediction::xLoadHorPred8x8( XPel* puc, Int iStride )
{
if( xIsAboveLeftRef() )
{
m_pucHor[0] = (puc[-iStride-1] + 2*puc[-iStride] + puc[-iStride+1] + 2) >> 2;
}
else
{
m_pucHor[0] = (3*puc[-iStride] + puc[-iStride+1] + 2) >> 2;
}
for( Int x = 1; x < 7; x++ )
{
const Int iOffset = x-iStride;
m_pucHor[x] = (puc[iOffset-1] + 2*puc[iOffset] + puc[iOffset+1] + 2) >> 2;
}
if( ! xIsAboveRightRef() )
{
m_pucHor[7] = (puc[6-iStride] + 3*puc[7-iStride] + 2) >> 2;
for( Int x = 8; x < 16; x++ )
{
m_pucHor[x] = puc[7-iStride];
}
}
else
{
m_pucHor[7] = (puc[6-iStride] + 2*puc[7-iStride] + puc[8-iStride] + 2) >> 2;
AOT( ! xIsAboveRef() )
if( ! m_bSpecial)
{
m_pucHor[ 8] = (puc[ 7-iStride] + 2*puc[ 8-iStride] + puc[ 9-iStride] + 2) >> 2;
m_pucHor[ 9] = (puc[ 8-iStride] + 2*puc[ 9-iStride] + puc[10-iStride] + 2) >> 2;
m_pucHor[10] = (puc[ 9-iStride] + 2*puc[10-iStride] + puc[11-iStride] + 2) >> 2;
m_pucHor[11] = (puc[10-iStride] + 2*puc[11-iStride] + puc[12-iStride] + 2) >> 2;
m_pucHor[12] = (puc[11-iStride] + 2*puc[12-iStride] + puc[13-iStride] + 2) >> 2;
m_pucHor[13] = (puc[12-iStride] + 2*puc[13-iStride] + puc[14-iStride] + 2) >> 2;
m_pucHor[14] = (puc[13-iStride] + 2*puc[14-iStride] + puc[15-iStride] + 2) >> 2;
m_pucHor[15] = (puc[14-iStride] + 3*puc[15-iStride] + 2) >> 2;
}
else
{
m_pucHor[ 8] = (puc[ 7-iStride] + 2*puc[ 8-iStride] + puc[ 9-iStride] + 2) >> 2;
m_pucHor[ 9] = (puc[ 8-iStride] + 2*puc[ 9-iStride] + puc[10-iStride] + 2) >> 2;
m_pucHor[10] = (puc[ 9-iStride] + 2*puc[10-iStride] + puc[11-iStride] + 2) >> 2;
m_pucHor[11] = (puc[10-iStride] + 2*puc[11-iStride] + puc[8 ] + 2) >> 2;
m_pucHor[12] = (puc[11-iStride] + 2*puc[8 ] + puc[9 ] + 2) >> 2;
m_pucHor[13] = (puc[8 ] + 2*puc[9 ] + puc[10 ] + 2) >> 2;
m_pucHor[14] = (puc[9 ] + 2*puc[10 ] + puc[11 ] + 2) >> 2;
m_pucHor[15] = (puc[10] + 3*puc[11] + 2) >> 2;
}
}
}
Void IntraPrediction::xLoadXPred8x8( XPel* puc, Int iStride )
{
if( xIsAboveLeftRef() )
{
if( xIsAboveRef() )
{
if( xIsLeftRef() )
{
m_pucHor[-1] = m_pucVer[-1] = (puc[-1] + 2 * puc[-iStride-1] + puc[-iStride] + 2 )>>2;
}
else
{
m_pucHor[-1] = m_pucVer[-1] = (3 * puc[-iStride-1] + puc[-iStride] + 2 )>>2;
}
}
else
{
if( xIsLeftRef() )
{
m_pucHor[-1] = m_pucVer[-1] = (puc[-1] + 3 * puc[-iStride-1] )>>2;
}
else
{
m_pucHor[-1] = m_pucVer[-1] = puc[-iStride-1];
}
}
}
}
Void IntraPrediction::xLoadVerPred8x8( XPel* puc, Int iStride )
{
if( xIsLeftRef() )
{
if( xIsAboveLeftRef() )
{
m_pucVer[0] = (puc[-iStride-1] + 2 * puc[-1] + puc[iStride-1] + 2 )>>2;
}
else
{
m_pucVer[0] = ( 3 * puc[-1] + puc[iStride-1] + 2 )>>2;
}
for( Int y = 1; y < 7; y++ )
{
const Int iOffset = y*iStride-1;
m_pucVer[y] = (puc[iOffset-iStride] + 2*puc[iOffset] + puc[iOffset+iStride] + 2) >> 2;
}
m_pucVer[7] = ( puc[6*iStride-1] + 3*puc[7*iStride-1] + 2 )>>2;
}
}
Void IntraPrediction::xPredLum8x8Mode0Vert( XPel* puc, Int iStride )
{
AOF_DBG( xIsAboveRef() );
xLoadHorPred8x8( puc, iStride );
for( Int n = 0; n < 8; n++ )
{
::memcpy( puc, m_pucHor, 8*sizeof(XPel) );
puc += iStride;
}
}
Void IntraPrediction::xPredLum8x8Mode1Horiz( XPel* puc, Int iStride )
{
AOF_DBG( xIsLeftRef() );
xLoadVerPred8x8( puc, iStride );
for( Int n = 0; n < 8; n++ )
{
for( Int m = 0; m < 8; m++ )
{
puc[m] = m_pucVer[n];
}
puc += iStride;
}
}
Void IntraPrediction::xPredLum8x8Mode2Dc( XPel* puc, Int iStride )
{
UInt uiDcValue = 4;
if( ! xIsLeftRef() )
{
if( ! xIsAboveRef() )
{
uiDcValue = 0x80;
}
else
{
xLoadHorPred8x8( puc, iStride );
for( Int x = 0; x < 8; x++ )
{
uiDcValue += m_pucHor[x];
}
uiDcValue >>= 3;
}
}
else
{
xLoadVerPred8x8( puc, iStride );
if( ! xIsAboveRef() )
{
for( Int y = 0; y < 8; y++ )
{
uiDcValue += m_pucVer[y];
}
uiDcValue >>= 3;
}
else
{
xLoadHorPred8x8( puc, iStride );
uiDcValue = 8;
for( Int x = 0; x < 8; x++ )
{
uiDcValue += m_pucHor[x];
}
for( Int y = 0; y < 8; y++ )
{
uiDcValue += m_pucVer[y];
}
uiDcValue >>= 4;
}
}
for( Int n = 0; n < 8; n++ )
{
for( Int m = 0; m < 8; m++ )
{
puc[m] = uiDcValue;
}
puc += iStride;
}
}
Void IntraPrediction::xPredLum8x8Mode3DiagDownLeft( XPel* puc, Int iStride ) // Diagonal Down Left Pred
{
AOF_DBG( xIsAboveRef() );
xLoadHorPred8x8( puc, iStride );
for( Int y = 0; y < 8; y++ )
{
for( Int x = 0; x < 8; x++ )
{
puc[x] = (m_pucHor[x+y] + 2*m_pucHor[x+y+1] + m_pucHor[x+y+2] + 2 ) >> 2;
}
puc += iStride;
}
puc[7-iStride] = (m_pucHor[14] + 3*m_pucHor[15] + 2)>>2;
}
Void IntraPrediction::xPredLum8x8Mode4DiagDownRight( XPel* puc, Int iStride ) // Diagonal Down Right Pred
{
AOF_DBG( xIsAllLeftAboveRef() );
xLoadHorPred8x8( puc, iStride );
xLoadVerPred8x8( puc, iStride );
xLoadXPred8x8 ( puc, iStride );
for( Int y = 0; y < 8; y++ )
{
for( Int x = 0; x < 8; x++ )
{
if(x > y)
{
const Int iOffset = x-y;
puc[x] = (m_pucHor[iOffset-2] + 2*m_pucHor[iOffset-1] + m_pucHor[iOffset] + 2)>>2;
}
else if(x < y)
{
const Int iOffset = y-x;
puc[x] = (m_pucVer[iOffset-2] + 2*m_pucVer[iOffset-1] + m_pucVer[iOffset] + 2)>>2;
}
else
{
puc[x] = (m_pucHor[0] + 2*m_pucVer[-1] + m_pucVer[0] + 2)>>2;
}
}
puc += iStride;
}
}
Void IntraPrediction::xPredLum8x8Mode5VertRight( XPel* puc, Int iStride ) // Vertical Right Pred
{
AOF_DBG( xIsAllLeftAboveRef() );
xLoadHorPred8x8( puc, iStride );
xLoadVerPred8x8( puc, iStride );
xLoadXPred8x8 ( puc, iStride );
for( Int y = 0; y < 8; y++ )
{
for( Int x = 0; x < 8; x++ )
{
Int iZVR = 2 * x - y;
if( iZVR >= 0 )
{
Int iOffset = x-(y>>1);
if( iZVR & 1)
{
puc[x] = ( m_pucHor[iOffset-2] + 2*m_pucHor[iOffset-1] + m_pucHor[iOffset] + 2 ) >> 2;
}
else
{
puc[x] = ( m_pucHor[iOffset-1] + m_pucHor[iOffset] + 1 ) >> 1;
}
}
else
{
if( iZVR == -1)
{
puc[x] = (m_pucHor[0] + 2*m_pucVer[-1] + m_pucVer[0] + 2)>>2;
}
else
{
Int iOffset = y-2*x;
puc[x] = (m_pucVer[iOffset-1] + 2*m_pucVer[iOffset-2] + m_pucVer[iOffset-3] + 2)>>2;
}
}
}
puc += iStride;
}
}
Void IntraPrediction::xPredLum8x8Mode6HorizDown( XPel* puc, Int iStride ) // Horizontal DownPred
{
AOF_DBG( xIsAllLeftAboveRef() );
xLoadXPred8x8( puc, iStride );
xLoadHorPred8x8( puc, iStride );
xLoadVerPred8x8( puc, iStride );
for( Int y = 0; y < 8; y++ )
{
for( Int x = 0; x < 8; x++ )
{
Int iZHD = 2 * y - x;
if( iZHD >= 0 )
{
Int iOffset = y-(x>>1);
if( iZHD & 1)
{
puc[x] = ( m_pucVer[iOffset-2] + 2*m_pucVer[iOffset-1] + m_pucVer[iOffset] + 2 ) >> 2;
}
else
{
puc[x] = ( m_pucVer[iOffset-1] + m_pucVer[iOffset] + 1 ) >> 1;
}
}
else
{
if( iZHD == -1)
{
puc[x] = (m_pucHor[0] + 2*m_pucVer[-1] + m_pucVer[0] + 2)>>2;
}
else
{
Int iOffset = x - 2*y;
puc[x] = ( m_pucHor[iOffset-1] + 2*m_pucHor[iOffset-2] + m_pucHor[iOffset-3] + 2 ) >> 2;
}
}
}
puc += iStride;
}
}
Void IntraPrediction::xPredLum8x8Mode7VertLeft( XPel* puc, Int iStride ) // Vertical Left Pred
{
AOF_DBG( xIsAboveRef() ); //!!!
xLoadHorPred8x8( puc, iStride );
for( Int y = 0; y < 8; y+=2 )
{
for( Int x1 = 0; x1 < 8; x1++ )
{
Int iOffset = x1 + ( y >> 1 );
puc[x1] = ( m_pucHor[iOffset] + m_pucHor[iOffset+1] + 1 ) >> 1;
}
puc += iStride;
for( Int x2 = 0; x2 < 8; x2++ )
{
Int iOffset = x2 + ( y >> 1 );
puc[x2] = ( m_pucHor[iOffset] + 2*m_pucHor[iOffset+1] + m_pucHor[iOffset+2] + 2 ) >> 2;
}
puc += iStride;
}
}
Void IntraPrediction::xPredLum8x8Mode8HorizUp( XPel* puc, Int iStride ) // Horizontal Up Pred
{
AOF_DBG( xIsLeftRef() ); //!!!
xLoadVerPred8x8( puc, iStride );
UInt uiEqual13 = (m_pucVer[6]+ 3*m_pucVer[7] + 2) >> 2;
UInt uiGreater13 = m_pucVer[7];
for( Int y = 0; y < 8; y++ )
{
for( Int x = 0; x < 8; x++ )
{
Int iZHU = x + 2 * y;
if( iZHU < 13 )
{
Int iOffset = y+(x>>1);
if( iZHU & 1)
{
puc[x] = ( m_pucVer[iOffset] + 2*m_pucVer[iOffset+1] + m_pucVer[iOffset+2] + 2 ) >> 2;
}
else
{
puc[x] = ( m_pucVer[iOffset] + m_pucVer[iOffset+1] + 1 ) >> 1;
}
}
else
{
if( iZHU == 13 )
{
puc[x] = uiEqual13;
}
else
{
puc[x] = uiGreater13;
}
}
}
puc += iStride;
}
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -