quarterpelfilter.cpp
来自「JVT-S203 contains the JSVM 6 reference s」· C++ 代码 · 共 1,567 行 · 第 1/3 页
CPP
1,567 行
{
Int iTempX;
iTempX = pucSrcX[x - 0];
iTempX += pucSrcX[x + 1];
iTempX = iTempX << 2;
iTempX -= pucSrcX[x - 1];
iTempX -= pucSrcX[x + 2];
iTempX += iTempX << 2;
iTempX += pucSrcX[x - 2];
iTempX += pucSrcX[x + 3];
iTempX = gClip( (iTempX + 16) / 32 );
Int iTempY;
iTempY = pucSrcY[x - 0*iSrcStride];
iTempY += pucSrcY[x + 1*iSrcStride];
iTempY = iTempY << 2;
iTempY -= pucSrcY[x - 1*iSrcStride];
iTempY -= pucSrcY[x + 2*iSrcStride];
iTempY += iTempY << 2;
iTempY += pucSrcY[x - 2*iSrcStride];
iTempY += pucSrcY[x + 3*iSrcStride];
iTempY = gClip( (iTempY + 16) / 32 );
pucDest[x] = (iTempX + iTempY + 1) >> 1;
}
pucDest += iDestStride;
pucSrcX += iSrcStride;
pucSrcY += iSrcStride;
}
}
ErrVal QuarterPelFilter::filterFrame( IntYuvPicBuffer *pcPelBuffer, IntYuvPicBuffer *pcHalfPelBuffer )
{
ROT( NULL == pcPelBuffer );
ROT( NULL == pcHalfPelBuffer );
XPel* pucSrc = pcPelBuffer->getMbLumAddr ();
Int iHeight = pcPelBuffer->getLHeight ();
Int iWidth = pcPelBuffer->getLWidth ();
Int iStride = pcPelBuffer->getLStride ();
Int iMargin = pcPelBuffer->getLXMargin ();
UInt uiTmpXSize = (iMargin + iWidth + iMargin) * 2;
UInt uiTmpYSize = iMargin + iHeight + iMargin;
Int iMarginNew = iMargin-4;
Int x, y;
XXPel* psTemp = new XXPel[uiTmpXSize * uiTmpYSize];
ROT( NULL == psTemp )
XXPel* ps = &psTemp[ iMargin * uiTmpXSize + 2*iMargin ]; // fix provided by Shijun Sun
for( y = 0; y < iHeight; y++ )
{
for( x = -iMarginNew; x < iWidth+iMarginNew; x++ )
{
Int iTemp;
iTemp = pucSrc[x - 0];
iTemp += pucSrc[x + 1];
iTemp = iTemp << 2;
iTemp -= pucSrc[x - 1];
iTemp -= pucSrc[x + 2];
iTemp += iTemp << 2;
iTemp += pucSrc[x - 2];
iTemp += pucSrc[x + 3];
ps[2*x] = pucSrc[x]<<5;
ps[2*x+1] = iTemp;
}
ps += uiTmpXSize;
pucSrc += iStride;
}
// bot
ps -= iMargin*2; // fix provided by Shijun Sun
for( y = 0; y < iMargin; y++ ) // fix provided by Shijun Sun
{
::memcpy( &ps[y*uiTmpXSize], &ps[(y-1)*uiTmpXSize], uiTmpXSize*sizeof(XXPel) );
}
//top
ps = &psTemp[ iMargin * uiTmpXSize ]; // fix provided by Shijun Sun
for( y = 0; y < iMargin; y++ ) // fix provided by Shijun Sun
{
::memcpy( &ps[-(y+1)*uiTmpXSize], &ps[-y*uiTmpXSize], uiTmpXSize*sizeof(XXPel) );
}
ps = &psTemp[ 4*uiTmpXSize + 2*iMargin ]; // fix provided by Shijun Sun
iStride = uiTmpXSize;
Int iDesStrideHP = pcHalfPelBuffer->getLStride();
XPel* pucDesHP = pcHalfPelBuffer->getMbLumAddr();
pucDesHP -= (iMarginNew*iDesStrideHP)<<1;
for( y = -iMarginNew; y < iHeight+iMarginNew; y++ )
{
for( x = -2*iMarginNew; x < 2*(iWidth+iMarginNew); x++ )
{
Int iTemp;
iTemp = ps[x - 0*iStride];
iTemp += ps[x + 1*iStride];
iTemp = iTemp << 2;
iTemp -= ps[x - 1*iStride];
iTemp -= ps[x + 2*iStride];
iTemp += iTemp << 2;
iTemp += ps[x - 2*iStride];
iTemp += ps[x + 3*iStride];
pucDesHP[x] = xClip( ( ps[x] + 16) / 32);
pucDesHP[x+iDesStrideHP] = xClip( ( iTemp + 512) / 1024);
}
pucDesHP += iDesStrideHP<<1;
ps += iStride;
}
delete [] psTemp;
psTemp = NULL;
return Err::m_nOK;
}
Void QuarterPelFilter::xFilter1( Pel* pDes, Pel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int a = pSrc[-1];
Int b = pSrc[-iSrcStride];
Int c = pSrc[+1];
Int d = pSrc[iSrcStride];
Int o = pSrc[0];
pDes[0x000] = (a + b + 1) >> 1;
pDes[0x100] = (b + o + 1) >> 1;
pDes[0x200] = (b + c + 1) >> 1;
pDes[0x300] = (a + o + 1) >> 1;
pDes[0x500] = (c + o + 1) >> 1;
pDes[0x600] = (a + d + 1) >> 1;
pDes[0x700] = (d + o + 1) >> 1;
pDes[0x800] = (d + c + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::xXFilter1( XPel* pDes, XPel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int a = pSrc[-1];
Int b = pSrc[-iSrcStride];
Int c = pSrc[+1];
Int d = pSrc[iSrcStride];
Int o = pSrc[0];
pDes[0x000] = (a + b + 1) >> 1;
pDes[0x100] = (b + o + 1) >> 1;
pDes[0x200] = (b + c + 1) >> 1;
pDes[0x300] = (a + o + 1) >> 1;
pDes[0x500] = (c + o + 1) >> 1;
pDes[0x600] = (a + d + 1) >> 1;
pDes[0x700] = (d + o + 1) >> 1;
pDes[0x800] = (d + c + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::xFilter2( Pel* pDes, Pel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int o = pSrc[0];
pDes[0x000] = (o + pSrc[-iSrcStride-1] + 1) >> 1;
pDes[0x100] = (o + pSrc[-iSrcStride ] + 1) >> 1;
pDes[0x200] = (o + pSrc[-iSrcStride+1] + 1) >> 1;
pDes[0x300] = (o + pSrc[-1] + 1) >> 1;
pDes[0x500] = (o + pSrc[+1] + 1) >> 1;
pDes[0x600] = (o + pSrc[iSrcStride-1] + 1) >> 1;
pDes[0x700] = (o + pSrc[iSrcStride ] + 1) >> 1;
pDes[0x800] = (o + pSrc[iSrcStride+1] + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::xXFilter2( XPel* pDes, XPel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int o = pSrc[0];
pDes[0x000] = (o + pSrc[-iSrcStride-1] + 1) >> 1;
pDes[0x100] = (o + pSrc[-iSrcStride ] + 1) >> 1;
pDes[0x200] = (o + pSrc[-iSrcStride+1] + 1) >> 1;
pDes[0x300] = (o + pSrc[-1] + 1) >> 1;
pDes[0x500] = (o + pSrc[+1] + 1) >> 1;
pDes[0x600] = (o + pSrc[iSrcStride-1] + 1) >> 1;
pDes[0x700] = (o + pSrc[iSrcStride ] + 1) >> 1;
pDes[0x800] = (o + pSrc[iSrcStride+1] + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::xFilter3( Pel* pDes, Pel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int o = pSrc[0];
pDes[0x000] = (o + pSrc[-iSrcStride-1] + 1) >> 1;
pDes[0x100] = (o + pSrc[-iSrcStride ] + 1) >> 1;
pDes[0x200] = (o + pSrc[-iSrcStride+1] + 1) >> 1;
pDes[0x300] = (o + pSrc[-1] + 1) >> 1;
pDes[0x500] = (o + pSrc[+1] + 1) >> 1;
pDes[0x600] = (o + pSrc[iSrcStride-1] + 1) >> 1;
pDes[0x700] = (o + pSrc[iSrcStride ] + 1) >> 1;
pDes[0x800] = (o + pSrc[iSrcStride+1] + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::xXFilter3( XPel* pDes, XPel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int o = pSrc[0];
pDes[0x000] = (o + pSrc[-iSrcStride-1] + 1) >> 1;
pDes[0x100] = (o + pSrc[-iSrcStride ] + 1) >> 1;
pDes[0x200] = (o + pSrc[-iSrcStride+1] + 1) >> 1;
pDes[0x300] = (o + pSrc[-1] + 1) >> 1;
pDes[0x500] = (o + pSrc[+1] + 1) >> 1;
pDes[0x600] = (o + pSrc[iSrcStride-1] + 1) >> 1;
pDes[0x700] = (o + pSrc[iSrcStride ] + 1) >> 1;
pDes[0x800] = (o + pSrc[iSrcStride+1] + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::xFilter4( Pel* pDes, Pel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int a = pSrc[-1];
Int b = pSrc[-iSrcStride];
Int c = pSrc[+1];
Int d = pSrc[iSrcStride];
Int o = pSrc[0];
pDes[0x000] = (a + b + 1) >> 1;
pDes[0x100] = (b + o + 1) >> 1;
pDes[0x200] = (b + c + 1) >> 1;
pDes[0x300] = (a + o + 1) >> 1;
pDes[0x500] = (c + o + 1) >> 1;
pDes[0x600] = (a + d + 1) >> 1;
pDes[0x700] = (d + o + 1) >> 1;
pDes[0x800] = (c + d + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::xXFilter4( XPel* pDes, XPel* pSrc, Int iSrcStride, UInt uiXSize, UInt uiYSize )
{
UInt y, x;
for( y = 0; y < uiYSize; y++ )
{
for( x = 0; x < uiXSize; x++ )
{
Int a = pSrc[-1];
Int b = pSrc[-iSrcStride];
Int c = pSrc[+1];
Int d = pSrc[iSrcStride];
Int o = pSrc[0];
pDes[0x000] = (a + b + 1) >> 1;
pDes[0x100] = (b + o + 1) >> 1;
pDes[0x200] = (b + c + 1) >> 1;
pDes[0x300] = (a + o + 1) >> 1;
pDes[0x500] = (c + o + 1) >> 1;
pDes[0x600] = (a + d + 1) >> 1;
pDes[0x700] = (d + o + 1) >> 1;
pDes[0x800] = (c + d + 1) >> 1;
pSrc += 2;
pDes++;
}
pSrc += 2*(iSrcStride - uiXSize);
pDes += 16 - uiXSize;
}
}
Void QuarterPelFilter::predBlkBilinear( IntYuvMbBuffer* pcDesBuffer, IntYuvPicBuffer* pcSrcBuffer, LumaIdx cIdx, Mv cMv, Int iSizeY, Int iSizeX)
{
XPel* pucDes = pcDesBuffer->getYBlk( cIdx );
XPel* pucSrc = pcSrcBuffer->getYBlk( cIdx );
Int iDesStride = pcDesBuffer->getLStride();
Int iSrcStride = pcSrcBuffer->getLStride();
Int iOffset = (cMv.getHor() >> 2) + (cMv.getVer() >> 2) * iSrcStride;
pucSrc += iOffset;
Int iDx = cMv.getHor() & 3;
Int iDy = cMv.getVer() & 3;
if( iDx == 0 && iDy == 0 )
{
for( Int y = 0; y < iSizeY; y++)
{
for( Int x = 0; x < iSizeX; x++ )
pucDes[x] = pucSrc[x];
pucDes += iDesStride;
pucSrc += iSrcStride;
}
}
else
{
for( Int y = 0; y < iSizeY; y++)
{
for( Int x = 0; x < iSizeX; x++ )
{
Int iSum =
(pucSrc[x] * (4 - iDx) + pucSrc[x + 1] * iDx) * (4 - iDy) +
(pucSrc[iSrcStride + x] * (4 - iDx) + pucSrc[iSrcStride + x + 1] * iDx) * iDy;
pucDes[x] = ( iSum >= 0 ) ? ( ( iSum + 8 ) >> 4 ) : -( ( -iSum + 8 ) >> 4 );
}
pucDes += iDesStride;
pucSrc += iSrcStride;
}
}
}
Void QuarterPelFilter::predBlk4Tap( IntYuvMbBuffer* pcDesBuffer, IntYuvPicBuffer* pcSrcBuffer, LumaIdx cIdx, Mv cMv, Int iSizeY, Int iSizeX)
{
XPel* pucDes = pcDesBuffer->getYBlk( cIdx );
XPel* pucSrc = pcSrcBuffer->getYBlk( cIdx );
Int iDesStride = pcDesBuffer->getLStride();
Int iSrcStride = pcSrcBuffer->getLStride();
Int iOffset = (cMv.getHor() >> 2) + (cMv.getVer() >> 2) * iSrcStride;
pucSrc += iOffset;
Int iDx = cMv.getHor() & 3;
Int iDy = cMv.getVer() & 3;
static int f4tap[4][4] = {
{ 0, 16, 0, 0},
{-2, 14, 5, -1},
{-2, 10, 10, -2},
{-1, 5, 14, -2}
};
for( Int y = 0; y < iSizeY; y++)
{
for( Int x = 0; x < iSizeX; x++ )
{
Int iTemp1[4], iTemp2;
int i, j;
for( i = 0; i < 4; i++ )
{
iTemp1[i] = 0;
for( j = 0; j < 4; j++ )
iTemp1[i] += pucSrc[x + (i - 1) * iSrcStride + j - 1] * f4tap[iDx][j];
}
iTemp2 = 0;
for(j=0;j<4;j++)
iTemp2 += iTemp1[j] * f4tap[iDy][j];
if( m_bClip )
pucDes[x] = xClip( (iTemp2 + 128) >> 8 );
else
pucDes[x] = (iTemp2 >= 0) ? ( (iTemp2 + 128) >> 8 ) : -( (-iTemp2 + 128) >> 8 );
}
pucDes += iDesStride;
pucSrc += iSrcStride;
}
}
Void QuarterPelFilter::predBlk( IntYuvMbBuffer* pcDesBuffer, IntYuvPicBuffer* pcSrcBuffer, LumaIdx cIdx, Mv cMv, Int iSizeY, Int iSizeX)
{
if( giInterpolationType == AR_FGS_MC_INTERP_BILINEAR )
{
predBlkBilinear(pcDesBuffer, pcSrcBuffer, cIdx, cMv, iSizeY, iSizeX);
return;
}
else if( giInterpolationType == AR_FGS_MC_INTERP_4_TAP )
{
predBlk4Tap(pcDesBuffer, pcSrcBuffer, cIdx, cMv, iSizeY, iSizeX);
return;
}
XPel* pucDes = pcDesBuffer->getYBlk( cIdx );
XPel* pucSrc = pcSrcBuffer->getYBlk( cIdx );
Int iDesStride = pcDesBuffer->getLStride();
Int iSrcStride = pcSrcBuffer->getLStride();
Int iOffset = (cMv.getHor() >> 2) + (cMv.getVer() >> 2) * iSrcStride;
pucSrc += iOffset;
Int iDx = cMv.getHor() & 3;
Int iDy = cMv.getVer() & 3;
if( iDy == 0)
{
if( iDx == 0 )
{
for( Int y = 0; y < iSizeY; y++)
{
for( Int x = 0; x < iSizeX; x++ )
{
pucDes[x] = pucSrc[x];
}
pucDes += iDesStride;
pucSrc += iSrcStride;
}
return;
}
if( iDx == 2 )
{
xPredDy0Dx2( pucDes, pucSrc, iDesStride, iSrcStride, iSizeY, iSizeX );
return;
}
// if( iDx == 1 || iDx == 3)
xPredDy0Dx13( pucDes, pucSrc, iDesStride, iSrcStride, iDx, iSizeY, iSizeX );
return;
}
if( iDx == 0)
{
if( iDy == 2 )
{
xPredDx0Dy2( pucDes, pucSrc, iDesStride, iSrcStride, iSizeY, iSizeX );
return;
}
// if( iDx == 1 || iDx == 3)
xPredDx0Dy13( pucDes, pucSrc, iDesStride, iSrcStride, iDx, iDy, iSizeY, iSizeX );
return;
}
if( iDx == 2)
{
if( iDy == 2 )
{
xPredDx2Dy2( pucDes, pucSrc, iDesStride, iSrcStride, iDx, iDy, iSizeY, iSizeX );
return;
}
// if( iDy == 1 || iDy == 3 )
xPredDx2Dy13( pucDes, pucSrc, iDesStride, iSrcStride, iDx, iDy, iSizeY, iSizeX );
return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?