motioncompensation.cpp

来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,966 行 · 第 1/5 页

CPP
1,966
字号
    if( NULL != pcRefBuffer )
    {
      const Mv cMv = rcMc8x8D.m_aacMv[n][eSParIdx];
      m_pcQuarterPelFilter->predBlk( apcTarBuffer[n], pcRefBuffer, cIdx, cMv, iSizeY, iSizeX );

      if( cMbIcp.getIcAct() )
        xIcForPredLuma( cMbIcp, apcTarBuffer[n], cIdx, iSizeY, iSizeX );
    }
  }
}

Void MotionCompensation::xPredLuma( MbIcp cMbIcp, IntYuvMbBuffer* pcRecBuffer, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D )
{
  IntYuvMbBuffer* apcTarBuffer[2];
  m_pcSampleWeighting->getTargetBuffers( apcTarBuffer, pcRecBuffer, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );

  for( Int n = 0; n < 2; n++ )
  {
    IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
    if( NULL != pcRefBuffer )
    {
      const Mv cMv = rcMc8x8D.m_aacMv[n][0];
      m_pcQuarterPelFilter->predBlk( apcTarBuffer[n], pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX );
    }
  }

  m_pcSampleWeighting->weightLumaSamples( pcRecBuffer, iSizeX, iSizeY, rcMc8x8D.m_cIdx, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );

  if( cMbIcp.getIcAct() )
    xIcForPredLuma( cMbIcp, pcRecBuffer, rcMc8x8D.m_cIdx, iSizeY, iSizeX );
}

Void MotionCompensation::xPredLuma( MbIcp cMbIcp, YuvMbBuffer* pcRecBuffer, Int iSizeX, Int iSizeY, MC8x8D& rcMc8x8D )
{
  YuvMbBuffer* apcTarBuffer[2];
  m_pcSampleWeighting->getTargetBuffers( apcTarBuffer, pcRecBuffer, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );

  for( Int n = 0; n < 2; n++ )
  {
    YuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
    if( NULL != pcRefBuffer )
    {
      const Mv cMv = rcMc8x8D.m_aacMv[n][0];
      m_pcQuarterPelFilter->predBlk( apcTarBuffer[n], pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX );
    }
  }

  m_pcSampleWeighting->weightLumaSamples( pcRecBuffer, iSizeX, iSizeY, rcMc8x8D.m_cIdx, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );

  if( cMbIcp.getIcAct() )
    xIcForPredLuma( cMbIcp, pcRecBuffer, rcMc8x8D.m_cIdx, iSizeY, iSizeX );

}

Void MotionCompensation::xIcForPredLuma( MbIcp  cMbIcp, IntYuvMbBuffer* pcDesBuffer, LumaIdx cIdx, Int iSizeY, Int iSizeX )
{
  XPel* pucDes    = pcDesBuffer->getYBlk( cIdx );
  Int iDesStride  = pcDesBuffer->getLStride();
  bool bClip = m_pcQuarterPelFilter->getClipMode();

  if (iSizeY<=8 && iSizeX<=8)
  {
    if ( cMbIcp.getIcAct(cIdx.y(), cIdx.x()) )
    {
      short sOffset = (XPel)cMbIcp.getIcp(cIdx.y(), cIdx.x()).getOffset();

      for (Int y=0; y < iSizeY; y++)
      {
        for (Int x=0; x < iSizeX; x++)
        {
          pucDes[x] = xClip( bClip, pucDes[x] + sOffset );
        }
        pucDes += iDesStride;
      }
    }
  }
  else
  {
    Int iblkY4x4;
    short sIcAct0, sIcAct1;
    short sOffset0, sOffset1;

    for (Int y=0; y < iSizeY; y++)
    {
      iblkY4x4 = (y>>2) + cIdx.y();
      sIcAct0    = cMbIcp.getIcAct(iblkY4x4, cIdx.x());

      if (sIcAct0)
      {
        sOffset0 = cMbIcp.getIcp(iblkY4x4, cIdx.x()).getOffset();

        pucDes[0 ] = xClip( bClip, pucDes[0 ] + sOffset0 );
        pucDes[1 ] = xClip( bClip, pucDes[1 ] + sOffset0 );
        pucDes[2 ] = xClip( bClip, pucDes[2 ] + sOffset0 );
        pucDes[3 ] = xClip( bClip, pucDes[3 ] + sOffset0 );
        pucDes[4 ] = xClip( bClip, pucDes[4 ] + sOffset0 );
        pucDes[5 ] = xClip( bClip, pucDes[5 ] + sOffset0 );
        pucDes[6 ] = xClip( bClip, pucDes[6 ] + sOffset0 );
        pucDes[7 ] = xClip( bClip, pucDes[7 ] + sOffset0 );
      }

      if (iSizeX==16)
      {
        sIcAct1    = cMbIcp.getIcAct(iblkY4x4, cIdx.x()+2);

        if (sIcAct1)
        {
          sOffset1 = cMbIcp.getIcp(iblkY4x4, cIdx.x()+2).getOffset();

          pucDes[8 ] = xClip( bClip, pucDes[8 ] + sOffset1 );
          pucDes[9 ] = xClip( bClip, pucDes[9 ] + sOffset1 );
          pucDes[10] = xClip( bClip, pucDes[10] + sOffset1 );
          pucDes[11] = xClip( bClip, pucDes[11] + sOffset1 );
          pucDes[12] = xClip( bClip, pucDes[12] + sOffset1 );
          pucDes[13] = xClip( bClip, pucDes[13] + sOffset1 );
          pucDes[14] = xClip( bClip, pucDes[14] + sOffset1 );
          pucDes[15] = xClip( bClip, pucDes[15] + sOffset1 );
        }
      }
      pucDes += iDesStride;
    }
  }

  return;
}


Void MotionCompensation::xIcForPredLuma( MbIcp  cMbIcp, YuvMbBuffer* pcDesBuffer, LumaIdx cIdx, Int iSizeY, Int iSizeX )
{
  Pel* pucDes     = pcDesBuffer->getYBlk( cIdx );
  Int iDesStride  = pcDesBuffer->getLStride();
  bool bClip = m_pcQuarterPelFilter->getClipMode();

  if( iSizeY<=8 && iSizeX<=8 )
  { // KJH: block size at most 8x8 : no change in ICP
    if( cMbIcp.getIcAct(cIdx.y(), cIdx.x()) )
    {
      short sOffset = (XPel)cMbIcp.getIcp(cIdx.y(), cIdx.x()).getOffset();

      for( Int y=0; y < iSizeY; y++ )
      {
        for( Int x=0; x < iSizeX; x++ )
        {
          pucDes[x] = xClip( bClip, pucDes[x] + sOffset );
        }
        pucDes += iDesStride;
      }
    }
  }
  else
  {
    Int iblkY4x4;
    short sIcAct0, sIcAct1;
    short sOffset0, sOffset1;

    for (Int y=0; y < iSizeY; y++)
    {
      iblkY4x4 = (y>>2) + cIdx.y();
      sIcAct0    = cMbIcp.getIcAct(iblkY4x4, cIdx.x());
      if (sIcAct0)
      {
        sOffset0 = cMbIcp.getIcp(iblkY4x4, cIdx.x()).getOffset();

        pucDes[0 ] = xClip( bClip, pucDes[0 ] + sOffset0 );
        pucDes[1 ] = xClip( bClip, pucDes[1 ] + sOffset0 );
        pucDes[2 ] = xClip( bClip, pucDes[2 ] + sOffset0 );
        pucDes[3 ] = xClip( bClip, pucDes[3 ] + sOffset0 );
        pucDes[4 ] = xClip( bClip, pucDes[4 ] + sOffset0 );
        pucDes[5 ] = xClip( bClip, pucDes[5 ] + sOffset0 );
        pucDes[6 ] = xClip( bClip, pucDes[6 ] + sOffset0 );
        pucDes[7 ] = xClip( bClip, pucDes[7 ] + sOffset0 );
      }
      if (iSizeX==16)
      {
        sIcAct1    = cMbIcp.getIcAct(iblkY4x4, cIdx.x()+2);
        if (sIcAct1)
        {
          sOffset1 = cMbIcp.getIcp(iblkY4x4, cIdx.x()+2).getOffset();

          pucDes[8 ] = xClip( bClip, pucDes[8 ] + sOffset1 );
          pucDes[9 ] = xClip( bClip, pucDes[9 ] + sOffset1 );
          pucDes[10] = xClip( bClip, pucDes[10] + sOffset1 );
          pucDes[11] = xClip( bClip, pucDes[11] + sOffset1 );
          pucDes[12] = xClip( bClip, pucDes[12] + sOffset1 );
          pucDes[13] = xClip( bClip, pucDes[13] + sOffset1 );
          pucDes[14] = xClip( bClip, pucDes[14] + sOffset1 );
          pucDes[15] = xClip( bClip, pucDes[15] + sOffset1 );
        }
      }
      pucDes += iDesStride;
    }
  }

  return;
}

Void MotionCompensation::xInverseDPCMIcp( MbDataAccess& rcMbDataAccess )
{
  Icp cIcp = rcMbDataAccess.getMbData().getMbIcp().getIcp();
  SChar scRefIdx0, scRefIdx1;

  if( rcMbDataAccess.getSH().isInterB() )
  {
    UInt uiBlockFwdBwd = rcMbDataAccess.getMbData().getBlockFwdBwd(B_8x8_0);

    if (uiBlockFwdBwd==1)
    {
      scRefIdx0 = rcMbDataAccess.getMbMotionData(LIST_0).getRefIdx(B_8x8_0);
      rcMbDataAccess.getIcpPredictor(cIcp, LIST_0, scRefIdx0);
    }
    else if (uiBlockFwdBwd==2)
    {
      scRefIdx1 = rcMbDataAccess.getMbMotionData(LIST_1).getRefIdx(B_8x8_0);
      rcMbDataAccess.getIcpPredictor(cIcp, LIST_1, scRefIdx1);
    }
    else if (uiBlockFwdBwd==3)
    {
      scRefIdx0 = rcMbDataAccess.getMbMotionData(LIST_0).getRefIdx(B_8x8_0);
      scRefIdx1 = rcMbDataAccess.getMbMotionData(LIST_1).getRefIdx(B_8x8_0);
      rcMbDataAccess.getIcpPredictor(cIcp, scRefIdx0, scRefIdx1);
    }
  }
  else
  {
    scRefIdx0 = rcMbDataAccess.getMbMotionData(LIST_0).getRefIdx(B_8x8_0);
    rcMbDataAccess.getIcpPredictor(cIcp, LIST_0, scRefIdx0);
  }

  short symOffset  = cIcp.getSymbolOffset();
  short predOffset = cIcp.getPredOffset();
  short recOffset  = symOffset + predOffset;
  cIcp.setSymbolOffset( symOffset );
  cIcp.setOffset( recOffset );

  rcMbDataAccess.getMbData().getMbIcp().setAllIcp(cIcp);
}
#endif

__inline Void MotionCompensation::xPredChromaPel( XPel* pucDest, Int iDestStride, XPel* pucSrc, Int iSrcStride, Mv cMv, Int iSizeY, Int iSizeX )
{
  Int xF1 = cMv.getHor();
  Int yF1 = cMv.getVer();

  xF1 &= 0x7;
  yF1 &= 0x7;

  Int x, y;
  if( 0 == xF1 )
  {
    if( 0 == yF1 )
    {
      for( y = 0; y < iSizeY; y++ )
      {
        for( x = 0; x < iSizeX; x++ )
        {
          pucDest[x  ] = pucSrc[x  ];
        }
        pucDest += iDestStride;
        pucSrc  += iSrcStride;
      }
      return;
    }

    Int yF0 = 8 - yF1;

    for( y = 0; y < iSizeY; y++ )
    {
      for( x = 0; x < iSizeX; x++ )
      {
#if AR_FGS_COMPENSATE_SIGNED_FRAME
        pucDest[x  ] = SIGNED_ROUNDING( yF0 * pucSrc[x  ] + yF1 * pucSrc[x+iSrcStride  ], 4, 3 );
#else
        pucDest[x  ] = (yF0 * pucSrc[x  ] + yF1 * pucSrc[x+iSrcStride  ] + 4) >> 3;
#endif
      }
      pucDest += iDestStride;
      pucSrc  += iSrcStride;
    }
    return;
  }


  if( 0 == yF1 )
  {
    Int xF0 = 8 - xF1;

    for( y = 0; y < iSizeY; y++ )
    {
      for( x = 0; x < iSizeX; x++ )
      {
#if AR_FGS_COMPENSATE_SIGNED_FRAME
        pucDest[x] = SIGNED_ROUNDING( xF0 * pucSrc[x] + xF1 * pucSrc[x+1], 4, 3 );
#else
        pucDest[x] = (xF0 * pucSrc[x] + xF1 * pucSrc[x+1] + 4) >> 3;
#endif
      }
      pucDest += iDestStride;
      pucSrc  += iSrcStride;
    }
    return;
  }

  Int xF0 = 8 - xF1;
  Int yF0 = 8 - yF1;
  for( y = 0; y < iSizeY; y++ )
  {
    Int a = xF0* ( yF0 * pucSrc[0] + yF1 * pucSrc[iSrcStride]);
    for( x = 0; x < iSizeX; x++ )
    {
      Int b = yF0 * pucSrc[x+1] + yF1 * pucSrc[iSrcStride+x+1];
      Int c = xF1 * b;
#if AR_FGS_COMPENSATE_SIGNED_FRAME
      pucDest[x]   = SIGNED_ROUNDING( a + c, 0x20, 6 );
#else
      pucDest[x]   = (a + c + 0x20) >> 6;
#endif
      a = (b<<3) - c;
    }
    pucDest += iDestStride;
    pucSrc  += iSrcStride;
  }
}

__inline Void MotionCompensation::xPredChroma( IntYuvMbBuffer* pcDesBuffer, IntYuvPicBuffer* pcSrcBuffer, LumaIdx cIdx, Mv cMv, Int iSizeY, Int iSizeX)
{
  const Int iDesStride  = pcDesBuffer->getCStride();
  const Int iSrcStride  = pcSrcBuffer->getCStride();

  cMv.limitComponents( m_cMin, m_cMax );

  const Int iOffset = (cMv.getHor() >> 3) + (cMv.getVer() >> 3) * iSrcStride;

  xPredChromaPel( pcDesBuffer->getUBlk( cIdx ),          iDesStride,
                  pcSrcBuffer->getUBlk( cIdx )+ iOffset, iSrcStride,
                  cMv, iSizeY, iSizeX );

  xPredChromaPel( pcDesBuffer->getVBlk( cIdx ),          iDesStride,
                  pcSrcBuffer->getVBlk( cIdx )+ iOffset, iSrcStride,
                  cMv, iSizeY, iSizeX );
}

Void MotionCompensation::xPredChroma( IntYuvMbBuffer* pcRecBuffer, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D )
{
  IntYuvMbBuffer* apcTarBuffer[2];
  m_pcSampleWeighting->getTargetBuffers( apcTarBuffer, pcRecBuffer, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );                                    

  for( Int n = 0; n < 2; n++ )
  {
    IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
    if( NULL != pcRefBuffer )
    {
      Mv cMv = rcMc8x8D.m_aacMv[n][0];
      xPredChroma( apcTarBuffer[n], pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX );
    }
  }
  m_pcSampleWeighting->weightChromaSamples( pcRecBuffer, iSizeX, iSizeY, rcMc8x8D.m_cIdx, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );
}

Void MotionCompensation::xPredChroma( IntYuvMbBuffer* apcTarBuffer[2], Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D, SParIdx4x4 eSParIdx )
{
  B4x4Idx cIdx( rcMc8x8D.m_cIdx + eSParIdx );

  for( Int n = 0; n < 2; n++ )
  {
    IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
    if( NULL != pcRefBuffer )
    {
      Mv cMv = rcMc8x8D.m_aacMv[n][eSParIdx];
      xPredChroma( apcTarBuffer[n], pcRefBuffer, cIdx, cMv, iSizeY, iSizeX );
    }
  }
}



ErrVal MotionCompensation::updateSubMb( B8x8Idx         c8x8Idx,
                                        MbDataAccess&   rcMbDataAccess,
                                        IntFrame*       pcMCFrame,
                                        IntFrame*       pcPrdFrame,
                                        ListIdx         eListPrd )
{
  m_curMbX = rcMbDataAccess.getMbX();
  m_curMbY = rcMbDataAccess.getMbY();
  xUpdateMb8x8Mode( c8x8Idx, rcMbDataAccess, pcMCFrame, pcPrdFrame, eListPrd );

  return Err::m_nOK;
}



Void MotionCompensation::xUpdateMb8x8Mode(    B8x8Idx         c8x8Idx,
                                              MbDataAccess&   rcMbDataAccess,
                                              IntFrame*       pcMCFrame,
                                              IntFrame*       pcPrdFrame,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?