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 + -
显示快捷键?