📄 downconvert.cpp
字号:
}
//===== constrained intra resampling =====
MyList<unsigned int> cSliceIdList;
//--- initialization ---
pcFrame->setZero();
xInitBaseModeAllowedFlags( pcParameters, pabBaseModeAllowedFlagArrayFrm, pabBaseModeAllowedFlagArrayFld );
xInitSliceIdList ( cSliceIdList, pcParameters, pcMbDataCtrlBase );
//--- loop over slices ---
while( !cSliceIdList.empty() )
{
unsigned int uiSliceId = cSliceIdList.popFront();
//--- basic resampling ---
pcTempBaseFrame ->copy ( pcBaseFrame, ePicType );
pcReconstructionBypass->padRecFrame ( pcTempBaseFrame, pcMbDataCtrlBase, pcParameters, uiSliceId );
xIntraUpsampling( pcTempFrame, pcTempBaseFrame, pcParameters );
//--- generate mb maps for slice and update intra BL maps ---
xGenerateMbMapsForSliceId ( pcParameters, pcMbDataCtrlBase, pcMbDataCtrlPredFrm, pcMbDataCtrlPredFld, uiSliceId );
xUpdateBaseModeAllowedFlags ( pcParameters, pabBaseModeAllowedFlagArrayFrm, pabBaseModeAllowedFlagArrayFld );
//--- copy prediction data for current slice id ---
xUpdateIntraPredFrame( pcFrame, pcTempFrame, pcParameters );
}
}
void
DownConvert::residualUpsampling( Frame* pcFrame,
Frame* pcBaseFrame,
ResizeParameters* pcParameters,
MbDataCtrl* pcMbDataCtrlBase )
{
if( pcParameters->getSpatialResolutionChangeFlag() )
{
xResidualUpsampling ( pcFrame, pcBaseFrame, pcParameters, pcMbDataCtrlBase );
}
else if( pcParameters->getCroppingFlag() )
{
xCrop ( pcFrame, pcBaseFrame, pcParameters, 0 );
}
}
#endif
//======================================================
//
// G E N E R A L H E L P E R F U N C T I O N S
//
//======================================================
void
DownConvert::xDestroy()
{
delete [] m_paiImageBuffer;
delete [] m_paiTmp1dBuffer;
#ifdef DOWN_CONVERT_STATIC
delete [] m_padFilter;
delete [] m_aiTmp1dBufferInHalfpel;
delete [] m_aiTmp1dBufferInQ1pel;
delete [] m_aiTmp1dBufferInQ3pel;
delete [] m_paiTmp1dBufferOut;
#else
delete [] m_paiTransBlkIdc;
delete [] m_paeMbMapFrm;
delete [] m_paeMbMapFld;
#endif
m_paiImageBuffer = 0;
m_paiTmp1dBuffer = 0;
#ifdef DOWN_CONVERT_STATIC
m_padFilter = 0;
m_aiTmp1dBufferInHalfpel = 0;
m_aiTmp1dBufferInQ1pel = 0;
m_aiTmp1dBufferInQ3pel = 0;
m_paiTmp1dBufferOut = 0;
#else
m_paiTransBlkIdc = 0;
m_paeMbMapFrm = 0;
m_paeMbMapFld = 0;
#endif
}
int
DownConvert::xClip( int iValue, int imin, int imax )
{
ROTRS( iValue < imin, imin );
ROTRS( iValue > imax, imax );
return iValue;
}
void
DownConvert::xCompIntraUpsampling( ResizeParameters* pcParameters, bool bChroma, bool bBotFlag, bool bVerticalInterpolation )
{
//===== set general parameters =====
int iBotField = ( bBotFlag ? 1 : 0 );
int iFactor = ( !bChroma ? 1 : 2 );
int iRefPhaseX = ( !bChroma ? 0 : pcParameters->m_iRefLayerChromaPhaseX );
int iRefPhaseY = ( !bChroma ? 0 : pcParameters->m_iRefLayerChromaPhaseY );
int iPhaseX = ( !bChroma ? 0 : pcParameters->m_iChromaPhaseX );
int iPhaseY = ( !bChroma ? 0 : pcParameters->m_iChromaPhaseY );
int iRefW = pcParameters->m_iRefLayerFrmWidth / iFactor; // reference layer frame width
int iRefH = pcParameters->m_iRefLayerFrmHeight / 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_iFrameWidth / iFactor; // current frame width
int iGlobalH = pcParameters->m_iFrameHeight / 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 );
int iYBorder = ( bVerticalInterpolation ? ( bChroma ? 1 : 2 ) : 0 );
//===== 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( iRefW ) );
int iShiftY = ( pcParameters->m_iLevelIdc <= 30 ? 16 : 31 - CeilLog2( iRefH ) );
int iScaleX = ( ( (unsigned int)iRefW << iShiftX ) + ( iScaledW >> 1 ) ) / iScaledW;
int iScaleY = ( ( (unsigned int)iRefH << iShiftY ) + ( iScaledH >> 1 ) ) / iScaledH;
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 iOffsetX = iLeftOffset;
Int iOffsetY = iTopOffset;
Int iAddX = ( ( ( iRefW * ( 2 + iPhaseX ) ) << ( iShiftX - 2 ) ) + ( iScaledW >> 1 ) ) / iScaledW + ( 1 << ( iShiftX - 5 ) );
Int iAddY = ( ( ( iRefH * ( 2 + iPhaseY ) ) << ( iShiftY - 2 ) ) + ( iScaledH >> 1 ) ) / iScaledH + ( 1 << ( iShiftY - 5 ) );
Int iDeltaX = 4 * ( 2 + iRefPhaseX );
Int iDeltaY = 4 * ( 2 + iRefPhaseY );
if( ! pcParameters->m_bFrameMbsOnlyFlag || ! pcParameters->m_bRefLayerFrameMbsOnlyFlag )
{
iOffsetY = iTopOffset / 2;
iAddY = ( ( ( iRefH * ( 2 + iPhaseY ) ) << ( iShiftY - 3 ) ) + ( iScaledH >> 1 ) ) / iScaledH + ( 1 << ( iShiftY - 5 ) );
iDeltaY = 2 * ( 2 + iRefPhaseY );
}
//===== basic interpolation of a frame or a field =====
xBasicIntraUpsampling ( iBaseW, iBaseH, iCurrW, iCurrH,
iLOffset, iTOffset, iROffset, iBOffset,
iShiftX, iShiftY, iScaleX, iScaleY,
iOffsetX, iOffsetY, iAddX, iAddY,
iDeltaX, iDeltaY, iYBorder, bChroma );
//===== vertical interpolation for second field =====
if( bVerticalInterpolation )
{
xVertIntraUpsampling( iCurrW, iCurrH,
iLOffset, iTOffset, iROffset, iBOffset,
iYBorder, bBotFlag, bChroma );
}
}
void
DownConvert::xVertIntraUpsampling( int iBaseW, int iBaseH,
int iLOffset, int iTOffset, int iROffset, int iBOffset,
int iYBorder, bool bBotFlag, bool bChromaFilter )
{
AOT( !bChromaFilter && iYBorder < 2 );
AOT( bChromaFilter && iYBorder < 1 );
int iBotField = ( bBotFlag ? 1 : 0 );
int iCurrW = iBaseW;
int iCurrH = iBaseH << 1;
int iCurrLOffset = iLOffset;
int iCurrTOffset = iTOffset << 1;
int iCurrROffset = iROffset;
int iCurrBOffset = iBOffset << 1;
//========== vertical upsampling ===========
for( int j = 0; j < iCurrW; j++ )
{
int* piSrc = &m_paiImageBuffer[j];
//----- upsample column -----
for( int i = 0; i < iCurrH; i++ )
{
if( j < iCurrLOffset || j >= iCurrW - iCurrROffset ||
i < iCurrTOffset || i >= iCurrH - iCurrBOffset )
{
m_paiTmp1dBuffer[i] = 128; // set to mid gray
continue;
}
if( ( i % 2 ) == iBotField )
{
int iSrc = ( ( i >> 1 ) + iYBorder ) * m_iImageStride;
m_paiTmp1dBuffer[i] = piSrc[ iSrc ];
}
else
{
int iSrc = ( ( i >> 1 ) + iYBorder - iBotField ) * m_iImageStride;
if( bChromaFilter )
{
m_paiTmp1dBuffer[i] = ( piSrc[ iSrc ] + piSrc[ iSrc + m_iImageStride ] + 1 ) >> 1;
}
else
{
m_paiTmp1dBuffer[i] = 16;
m_paiTmp1dBuffer[i] += 19 * ( piSrc[ iSrc ] + piSrc[ iSrc + m_iImageStride ] );
m_paiTmp1dBuffer[i] -= 3 * ( piSrc[ iSrc - m_iImageStride ] + piSrc[ iSrc + 2 * m_iImageStride ] );
m_paiTmp1dBuffer[i] >>= 5;
m_paiTmp1dBuffer[i] = xClip( m_paiTmp1dBuffer[i], 0, 255 );
}
}
}
//----- copy back to image buffer -----
for( int n = 0; n < iCurrH; n++ )
{
piSrc[n*m_iImageStride] = m_paiTmp1dBuffer[n];
}
}
}
void
DownConvert::xBasicIntraUpsampling( 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 iOffsetX, int iOffsetY, int iAddX, int iAddY,
int iDeltaX, int iDeltaY, int iYBorder, bool bChromaFilter )
{
int filter16_luma[16][4] =
{
{ 0, 32, 0, 0 },
{ -1, 32, 2, -1 },
{ -2, 31, 4, -1 },
{ -3, 30, 6, -1 },
{ -3, 28, 8, -1 },
{ -4, 26, 11, -1 },
{ -4, 24, 14, -2 },
{ -3, 22, 16, -3 },
{ -3, 19, 19, -3 },
{ -3, 16, 22, -3 },
{ -2, 14, 24, -4 },
{ -1, 11, 26, -4 },
{ -1, 8, 28, -3 },
{ -1, 6, 30, -3 },
{ -1, 4, 31, -2 },
{ -1, 2, 32, -1 }
};
int filter16_chroma[16][2] =
{
{ 32, 0 },
{ 30, 2 },
{ 28, 4 },
{ 26, 6 },
{ 24, 8 },
{ 22, 10 },
{ 20, 12 },
{ 18, 14 },
{ 16, 16 },
{ 14, 18 },
{ 12, 20 },
{ 10, 22 },
{ 8, 24 },
{ 6, 26 },
{ 4, 28 },
{ 2, 30 }
};
//========== horizontal upsampling ===========
{
for( int j = 0; j < iBaseH; j++ )
{
int* piSrc = &m_paiImageBuffer[j*m_iImageStride];
for( int i = 0; i < iCurrW; i++ )
{
if( i < iLOffset || i >= iCurrW - iROffset )
{
m_paiTmp1dBuffer[i] = 128; // set to mid gray
continue;
}
m_paiTmp1dBuffer[i] = 0;
int iRefPos16 = ( ( ( i - iOffsetX ) * iScaleX + iAddX ) >> ( iShiftX - 4 ) ) - iDeltaX;
int iPhase = iRefPos16 & 15;
int iRefPos = iRefPos16 >> 4;
if( bChromaFilter )
{
for( int k = 0; k < 2; k++ )
{
int m = xClip( iRefPos + k, 0, iBaseW - 1 );
m_paiTmp1dBuffer[i] += filter16_chroma[iPhase][k] * piSrc[m];
}
}
else
{
for( int k = 0; k < 4; k++ )
{
int m = xClip( iRefPos + k - 1, 0, iBaseW - 1 );
m_paiTmp1dBuffer[i] += filter16_luma[iPhase][k] * piSrc[m];
}
}
}
//----- copy row back to image buffer -----
::memcpy( piSrc, m_paiTmp1dBuffer, iCurrW*sizeof(int) );
}
}
//========== vertical upsampling ===========
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -