📄 downconvert.cpp
字号:
}
void
DownConvert::xUpsamplingData6tapBilin( int iInLength, int iOutLength )
{
int* Tmp1dBufferInHalfpel = m_aiTmp1dBufferInHalfpel;
int* Tmp1dBufferInQ1pel = m_aiTmp1dBufferInQ1pel;
int* Tmp1dBufferInQ3pel = m_aiTmp1dBufferInQ3pel;
int x, y, iTemp;
// half pel samples (6-tap: 1 -5 20 20 -5 1)
for( x = 0; x < iInLength; x++ )
{
y = x;
iTemp = m_paiTmp1dBuffer[y];
y = ( x+1 < iInLength ? x+1 : iInLength-1 );
iTemp += m_paiTmp1dBuffer[y];
iTemp = iTemp << 2;
y = ( x-1 >= 0 ? x-1 : 0 );
iTemp -= m_paiTmp1dBuffer[y];
y = ( x+2 < iInLength ? x+2 : iInLength-1 );
iTemp -= m_paiTmp1dBuffer[y];
iTemp += iTemp << 2;
y = ( x-2 >= 0 ? x-2 : 0);
iTemp += m_paiTmp1dBuffer[y];
y = ( x+3 < iInLength ? x+3 : iInLength-1 );
iTemp += m_paiTmp1dBuffer[y];
Tmp1dBufferInHalfpel[x] = iTemp;
}
// 1/4 pel samples
for( x = 0; x < iInLength-1; x++ )
{
Tmp1dBufferInQ1pel[x] = ( ( m_paiTmp1dBuffer[x ] << 5 ) + Tmp1dBufferInHalfpel[x] + 1 ) >> 1;
Tmp1dBufferInQ3pel[x] = ( ( m_paiTmp1dBuffer[x+1] << 5 ) + Tmp1dBufferInHalfpel[x] + 1 ) >> 1;
}
Tmp1dBufferInQ1pel[iInLength-1] = ( ( m_paiTmp1dBuffer[iInLength-1] << 5 ) + Tmp1dBufferInHalfpel[iInLength-1] + 1 ) >> 1;
Tmp1dBufferInQ3pel[iInLength-1] = Tmp1dBufferInHalfpel[iInLength-1];
// generic interpolation to nearest 1/4 pel position
for( int iout = 0; iout < iOutLength; iout++ )
{
double dpos0 = ( (double)iout * iInLength / iOutLength );
int ipos0 = (int)dpos0;
double rpos0 = dpos0 - ipos0;
int iIndex = (int)( 8 * rpos0 );
switch( iIndex )
{
case 0:
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer [ipos0] << 5; // original pel value
break;
case 1:
case 2:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInQ1pel [ipos0]; // 1/4 pel value
break;
case 3:
case 4:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInHalfpel [ipos0]; // half pel value
break;
case 5:
case 6:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInQ3pel [ipos0]; // 1/4 pel value
break;
case 7:
int ipos1 = ( ipos0 + 1 < iInLength ? ipos0 + 1 : ipos0 );
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer [ipos1] << 5; // original pel value
break;
}
}
}
void
DownConvert::xCompDownsamplingDyadic( int iCurrW, int iCurrH )
{
int iBaseW = iCurrW >> 1;
int iBaseH = iCurrH >> 1;
int aiFilter[13] = { 2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2 };
//========== horizontal downsampling ===========
{
for( int j = 0; j < iCurrH; j++ )
{
int* piSrc = &m_paiImageBuffer[j*m_iImageStride];
//----- down sample row -----
for( int i = 0; i < iBaseW; i++ )
{
m_paiTmp1dBuffer[i] = 0;
for( int k = 0; k < 13; k++ )
{
int m = xClip( 2*i + k - 6, 0, iCurrW - 1 );
m_paiTmp1dBuffer[i] += aiFilter[k] * piSrc[m];
}
}
//----- copy row back to image buffer -----
::memcpy( piSrc, m_paiTmp1dBuffer, iBaseW*sizeof(int) );
}
}
//=========== vertical downsampling ===========
{
for( int j = 0; j < iBaseW; j++ )
{
int* piSrc = &m_paiImageBuffer[j];
//----- down sample column -----
for( int i = 0; i < iBaseH; i++ )
{
m_paiTmp1dBuffer[i] = 0;
for( int k = 0; k < 13; k++ )
{
int m = xClip( 2*i + k - 6, 0, iCurrH - 1 );
m_paiTmp1dBuffer[i] += aiFilter[k] * piSrc[m*m_iImageStride];
}
}
//----- scale, clip, and copy back to image buffer -----
for( int n = 0; n < iBaseH; n++ )
{
int iS = ( m_paiTmp1dBuffer[n] + 2048 ) >> 12;
piSrc[n*m_iImageStride] = xClip( iS, 0, 255 );
}
}
}
}
void
DownConvert::xCompDownsampling( ResizeParameters* pcParameters, bool bChroma, bool bBotFlag, bool bVerticalDownsampling )
{
//===== set general parameters =====
int iBotField = ( bBotFlag ? 1 : 0 );
int iFactor = ( !bChroma ? 1 : 2 );
int iRefPhaseX = ( !bChroma ? 0 : pcParameters->m_iChromaPhaseX );
int iRefPhaseY = ( !bChroma ? 0 : pcParameters->m_iChromaPhaseY );
int iPhaseX = ( !bChroma ? 0 : pcParameters->m_iRefLayerChromaPhaseX );
int iPhaseY = ( !bChroma ? 0 : pcParameters->m_iRefLayerChromaPhaseY );
int iRefW = pcParameters->m_iFrameWidth / iFactor; // reference layer frame width
int iRefH = pcParameters->m_iFrameHeight / iFactor; // reference layer frame height
int iOutW = pcParameters->m_iScaledRefFrmWidth / iFactor; // scaled reference layer frame width
int iOutH = pcParameters->m_iScaledRefFrmHeight / iFactor; // scaled reference layer frame height
int iGlobalW = pcParameters->m_iRefLayerFrmWidth / iFactor; // current frame width
int iGlobalH = pcParameters->m_iRefLayerFrmHeight / iFactor; // current frame height
int iLeftOffset = pcParameters->m_iLeftFrmOffset / iFactor; // current left frame offset
int iTopOffset = pcParameters->m_iTopFrmOffset / iFactor; // current top frame offset
//===== set input/output size =====
int iBaseField = ( pcParameters->m_bRefLayerFrameMbsOnlyFlag ? 0 : 1 );
int iCurrField = ( pcParameters->m_bRefLayerFrameMbsOnlyFlag && pcParameters->m_bFrameMbsOnlyFlag ? 0 : 1 );
int iBaseW = iRefW;
int iBaseH = iRefH >> iBaseField;
int iCurrW = iGlobalW;
int iCurrH = iGlobalH >> iCurrField;
int iLOffset = iLeftOffset;
int iTOffset = iTopOffset >> iCurrField;
int iROffset = iCurrW - iLOffset - iOutW;
int iBOffset = iCurrH - iTOffset - ( iOutH >> iCurrField );
//===== set position calculation parameters =====
int iScaledW = iOutW;
int iScaledH = ( ! pcParameters->m_bRefLayerFrameMbsOnlyFlag || pcParameters->m_bFrameMbsOnlyFlag ? iOutH : iOutH / 2 );
int iShiftX = ( pcParameters->m_iLevelIdc <= 30 ? 16 : 31 - CeilLog2( iScaledW ) );
int iShiftY = ( pcParameters->m_iLevelIdc <= 30 ? 16 : 31 - CeilLog2( iScaledH ) );
int iScaleX = ( ( (unsigned int)iScaledW << iShiftX ) + ( iRefW >> 1 ) ) / iRefW;
int iScaleY = ( ( (unsigned int)iScaledH << iShiftY ) + ( iRefH >> 1 ) ) / iRefH;
if( ! pcParameters->m_bFrameMbsOnlyFlag || ! pcParameters->m_bRefLayerFrameMbsOnlyFlag )
{
if( pcParameters->m_bRefLayerFrameMbsOnlyFlag )
{
iPhaseY = iPhaseY + 4 * iBotField + ( 3 - iFactor );
iRefPhaseY = 2 * iRefPhaseY + 2;
}
else
{
iPhaseY = iPhaseY + 4 * iBotField;
iRefPhaseY = iRefPhaseY + 4 * iBotField;
}
}
int iAddX = ( ( ( iScaledW * ( 2 + iRefPhaseX ) ) << ( iShiftX - 2 ) ) + ( iRefW >> 1 ) ) / iRefW + ( 1 << ( iShiftX - 5 ) );
int iAddY = ( ( ( iScaledH * ( 2 + iRefPhaseY ) ) << ( iShiftY - 2 ) ) + ( iRefH >> 1 ) ) / iRefH + ( 1 << ( iShiftY - 5 ) );
int iDeltaX = 4 * ( 2 + iPhaseX ) - ( iLeftOffset << 4 );
int iDeltaY = 4 * ( 2 + iPhaseY ) - ( iTopOffset << 4 );
if( ! pcParameters->m_bFrameMbsOnlyFlag || ! pcParameters->m_bRefLayerFrameMbsOnlyFlag )
{
iAddY = ( ( ( iScaledH * ( 2 + iRefPhaseY ) ) << ( iShiftY - 3 ) ) + ( iRefH >> 1 ) ) / iRefH + ( 1 << ( iShiftY - 5 ) );
iDeltaY = 2 * ( 2 + iPhaseY ) - ( iTopOffset << 3 );
}
//===== vertical downsampling to generate a field signal from a progressive frame =====
if( bVerticalDownsampling )
{
xVertDownsampling( iCurrW, iCurrH, bBotFlag );
}
//===== basic downsampling of a frame or field =====
xBasicDownsampling( iBaseW, iBaseH, iCurrW, iCurrH,
iLOffset, iTOffset, iROffset, iBOffset,
iShiftX, iShiftY, iScaleX, iScaleY,
iAddX, iAddY, iDeltaX, iDeltaY );
}
void
DownConvert::xVertDownsampling( int iBaseW,
int iBaseH,
bool bBotFlag )
{
int aiVertFilter[13] = { 2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2 };
int iBotField = ( bBotFlag ? 1 : 0 );
int iCurrW = iBaseW;
int iCurrH = iBaseH << 1;
//===== vertical downsampling =====
for( int j = 0; j < iCurrW; j++ )
{
int* piSrc = &m_paiImageBuffer[j];
for( int i = 0; i < iBaseH; i++ )
{
m_paiTmp1dBuffer[i] = 0;
for( int k = 0; k < 13; k++ )
{
int m = xClip( 2 * i + iBotField + k - 6, 0, iCurrH - 1 );
m_paiTmp1dBuffer[i] += aiVertFilter[k] * piSrc[m*m_iImageStride];
}
m_paiTmp1dBuffer[i] = ( m_paiTmp1dBuffer[i] + 32 ) >> 6;
}
//--- clip and copy back to image buffer ---
for( int n = 0; n < iBaseH; n++ )
{
piSrc[n*m_iImageStride] = xClip( m_paiTmp1dBuffer[n], 0, 255 );
}
}
}
void
DownConvert::xBasicDownsampling( int iBaseW, int iBaseH, int iCurrW, int iCurrH,
int iLOffset, int iTOffset, int iROffset, int iBOffset,
int iShiftX, int iShiftY, int iScaleX, int iScaleY,
int iAddX, int iAddY, int iDeltaX, int iDeltaY )
{
const int filter16[8][16][12] =
{
{ // D = 1
{ 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 2, -6, 127, 7, -2, 0, 0, 0, 0 },
{ 0, 0, 0, 3, -12, 125, 16, -5, 1, 0, 0, 0 },
{ 0, 0, 0, 4, -16, 120, 26, -7, 1, 0, 0, 0 },
{ 0, 0, 0, 5, -18, 114, 36, -10, 1, 0, 0, 0 },
{ 0, 0, 0, 5, -20, 107, 46, -12, 2, 0, 0, 0 },
{ 0, 0, 0, 5, -21, 99, 57, -15, 3, 0, 0, 0 },
{ 0, 0, 0, 5, -20, 89, 68, -18, 4, 0, 0, 0 },
{ 0, 0, 0, 4, -19, 79, 79, -19, 4, 0, 0, 0 },
{ 0, 0, 0, 4, -18, 68, 89, -20, 5, 0, 0, 0 },
{ 0, 0, 0, 3, -15, 57, 99, -21, 5, 0, 0, 0 },
{ 0, 0, 0, 2, -12, 46, 107, -20, 5, 0, 0, 0 },
{ 0, 0, 0, 1, -10, 36, 114, -18, 5, 0, 0, 0 },
{ 0, 0, 0, 1, -7, 26, 120, -16, 4, 0, 0, 0 },
{ 0, 0, 0, 1, -5, 16, 125, -12, 3, 0, 0, 0 },
{ 0, 0, 0, 0, -2, 7, 127, -6, 2, 0, 0, 0 }
},
{ // D = 1.5
{ 0, 2, 0, -14, 33, 86, 33, -14, 0, 2, 0, 0 },
{ 0, 1, 1, -14, 29, 85, 38, -13, -1, 2, 0, 0 },
{ 0, 1, 2, -14, 24, 84, 43, -12, -2, 2, 0, 0 },
{ 0, 1, 2, -13, 19, 83, 48, -11, -3, 2, 0, 0 },
{ 0, 0, 3, -13, 15, 81, 53, -10, -4, 3, 0, 0 },
{ 0, 0, 3, -12, 11, 79, 57, -8, -5, 3, 0, 0 },
{ 0, 0, 3, -11, 7, 76, 62, -5, -7, 3, 0, 0 },
{ 0, 0, 3, -10, 3, 73, 65, -2, -7, 3, 0, 0 },
{ 0, 0, 3, -9, 0, 70, 70, 0, -9, 3, 0, 0 },
{ 0, 0, 3, -7, -2, 65, 73, 3, -10, 3, 0, 0 },
{ 0, 0, 3, -7, -5, 62, 76, 7, -11, 3, 0, 0 },
{ 0, 0, 3, -5, -8, 57, 79, 11, -12, 3, 0, 0 },
{ 0, 0, 3, -4, -10, 53, 81, 15, -13, 3, 0, 0 },
{ 0, 0, 2, -3, -11, 48, 83, 19, -13, 2, 1, 0 },
{ 0, 0, 2, -2, -12, 43, 84, 24, -14, 2, 1, 0 },
{ 0, 0, 2, -1, -13, 38, 85, 29, -14, 1, 1, 0 }
},
{ // D = 2
{ 2, 0, -10, 0, 40, 64, 40, 0, -10, 0, 2, 0 },
{ 2, 1, -9, -2, 37, 64, 42, 2, -10, -1, 2, 0 },
{ 2, 1, -9, -3, 34, 64, 44, 4, -10, -1, 2, 0 },
{ 2, 1, -8, -5, 31, 63, 47, 6, -10, -2, 3, 0 },
{ 1, 2, -8, -6, 29, 62, 49, 8, -10, -2, 3, 0 },
{ 1, 2, -7, -7, 26, 61, 52, 10, -10, -3, 3, 0 },
{ 1, 2, -6, -8, 23, 60, 54, 13, -10, -4, 3, 0 },
{ 1, 2, -6, -9, 20, 59, 56, 15, -10, -4, 3, 1 },
{ 1, 2, -5, -9, 18, 57, 57, 18, -9, -5, 2, 1 },
{ 1, 3, -4, -10, 15, 56, 59, 20, -9, -6, 2, 1 },
{ 0, 3, -4, -10, 13, 54, 60, 23, -8, -6, 2, 1 },
{ 0, 3, -3, -10, 10, 52, 61, 26, -7, -7, 2, 1 },
{ 0, 3, -2, -10, 8, 49, 62, 29, -6, -8, 2, 1 },
{ 0, 3, -2, -10, 6, 47, 63, 31, -5, -8, 1, 2 },
{ 0, 2, -1, -10, 4, 44, 64, 34, -3, -9, 1, 2 },
{ 0, 2, -1, -10, 2, 42, 64, 37, -2, -9, 1, 2 }
},
{ // D = 2.5
{ 0, -4, -7, 11, 38, 52, 38, 11, -7, -4, 0, 0 },
{ 0, -4, -7, 9, 37, 51, 40, 13, -6, -7, 2, 0 },
{ 0, -3, -7, 8, 35, 51, 41, 14, -5, -7, 1, 0 },
{ 0, -2, -8, 6, 33, 51, 42, 16, -5, -7, 2, 0 },
{ 0, -2, -8, 5, 32, 50, 43, 18, -4, -8, 2, 0 },
{ 0, -2, -8, 4, 30, 50, 45, 19, -3, -8, 1, 0 },
{ 0, -1, -8, 2, 28, 49, 46, 21, -2, -8, 1, 0 },
{ 0, -1, -8, 1, 26, 49, 47, 23, -1, -8, 0, 0 },
{ 0, 0, -8, 0, 24, 48, 48, 24, 0, -8, 0, 0 },
{ 0, 0, -8, -1, 23, 47, 49, 26, 1, -8, -1, 0 },
{ 0, 1, -8, -2, 21, 46, 49, 28, 2, -8, -1, 0 },
{ 0, 1, -8, -3, 19, 45, 50, 30, 4, -8, -2, 0 },
{ 0, 2, -8, -4, 18, 43, 50, 32, 5, -8, -2, 0 },
{ 0, 2, -7, -5, 16, 42, 51, 33, 6, -8, -2, 0 },
{ 0, 1, -7, -5, 14, 41, 51, 35, 8, -7, -3, 0 },
{ 0, 2, -7, -6, 13, 40, 51, 37, 9, -7, -4, 0 }
},
{ // D = 3
{ -2, -7, 0, 17, 35, 43, 35, 17, 0, -7, -5, 2 },
{ -2, -7, -1, 16, 34, 43, 36, 18, 1, -7, -5, 2 },
{ -1, -7, -1, 14, 33, 43, 36, 19, 1, -6, -5, 2 },
{ -1, -7, -2, 13, 32, 42, 37, 20, 3, -6, -5, 2 },
{ 0, -7, -3, 12, 31, 42, 38, 21, 3, -6, -5, 2 },
{ 0, -7, -3, 11, 30, 42, 39, 23, 4, -6, -6, 1 },
{ 0, -7, -4, 10, 29, 42, 40, 24, 5, -6, -6, 1 },
{ 1, -7, -4, 9, 27, 41, 40, 25, 6, -5, -6, 1 },
{ 1, -6, -5, 7, 26, 41, 41, 26, 7, -5, -6, 1 },
{ 1, -6, -5, 6, 25, 40, 41, 27, 9, -4, -7, 1 },
{ 1, -6, -6, 5, 24, 40, 42, 29, 10, -4, -7, 0 },
{ 1, -6, -6, 4, 23, 39, 42, 30, 11, -3, -7, 0 },
{ 2, -5, -6, 3, 21, 38, 42, 31, 12, -3, -7, 0 },
{ 2, -5, -6, 3, 20, 37, 42, 32, 13, -2, -7, -1 },
{ 2, -5, -6, 1, 19, 36,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -