⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loopfilter.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
  {
    if( !b8x8 || ( ( cIdx.x() & 1 ) == 0 ) )
    {
      m_aaaucBs[VER][cIdx.x()][cIdx.y()]  = xGetVerFilterStrength( rcMbDataAccess, cIdx, iFilterIdc );
    }
    else
    {
      m_aaaucBs[VER][cIdx.x()][cIdx.y()]  = 0;
    }
    if( !b8x8 || ( ( cIdx.y() & 1 ) == 0 ) )
    {
      m_aaaucBs[HOR][cIdx.x()][cIdx.y()]  = xGetHorFilterStrength( rcMbDataAccess, cIdx, iFilterIdc );
    }
    else
    {
      m_aaaucBs[HOR][cIdx.x()][cIdx.y()]  = 0;
    }
  }

  m_bHorMixedMode  = m_bHorMixedMode && bCurrFrame;

  if( m_apcIntYuvBuffer[ FRAME ] )
  {
    const PicType ePicType = rcMbDataAccess.getMbPicType();
    RNOK( xLumaVerFiltering(   rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
    RNOK( xLumaHorFiltering(   rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
//V032 of FSL for disabling chroma deblocking in enh. layer
	if (!enhancedLayerFlag || (enhancedLayerFlag && (iFilterIdc !=3 && iFilterIdc != 4)) ) 
	{ 
		RNOK( xChromaVerFiltering( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
		RNOK( xChromaHorFiltering( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
	}
    return Err::m_nOK;
  }

  const SliceHeader& rcSH = rcMbDataAccess.getSH();
  const PicType ePicType = ( rcSH.getFieldPicFlag() ) ? rcSH.getPicType() : rcMbDataAccess.getMbPicType();
  YuvPicBuffer* pcYuvBuffer = m_pcRecFrameUnit->getPic( ePicType )->getFullPelYuvBuffer();

  RNOK( xLumaVerFiltering(   rcMbDataAccess, rcDFP, pcYuvBuffer ) );
  RNOK( xLumaHorFiltering(   rcMbDataAccess, rcDFP, pcYuvBuffer ) );
  //V032 of FSL for disabling chroma deblocking in enh. layer
  if (!enhancedLayerFlag || (enhancedLayerFlag && (iFilterIdc !=3 && iFilterIdc != 4)) ) 
  { 
     RNOK( xChromaVerFiltering( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
     RNOK( xChromaHorFiltering( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
  }
  return Err::m_nOK;
}


__inline ErrVal LoopFilter::xFilterMb_RCDO( const MbDataAccess& rcMbDataAccess )
{
  const DFP&  rcDFP       = rcMbDataAccess.getDeblockingFilterParameter( m_eLFMode & LFM_NO_INTER_FILTER );
  Int         iFilterIdc  = rcDFP.getDisableDeblockingFilterIdc();

  ROTRS( (m_eLFMode & LFM_NO_INTER_FILTER) && ! rcMbDataAccess.getMbData().isIntra(), Err::m_nOK );
  ROTRS( iFilterIdc == 1, Err::m_nOK );

  Bool  bFieldFlag  = rcMbDataAccess.getMbData().getFieldFlag();
  m_bVerMixedMode   = ( bFieldFlag != rcMbDataAccess.getMbDataLeft().getFieldFlag() );
  m_bHorMixedMode   = ( bFieldFlag ? ( bFieldFlag != rcMbDataAccess.getMbDataAboveAbove().getFieldFlag() ) 
                                   : ( bFieldFlag != rcMbDataAccess.getMbDataAbove     ().getFieldFlag() ) );

  if( m_apcIntYuvBuffer[ FRAME ] )
  {
    const PicType ePicType = rcMbDataAccess.getMbPicType();
    RNOK( xLumaVerFiltering_H241RCDO(   rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ], &rcMbDataAccess, NULL, NULL ) );
    RNOK( xLumaHorFiltering_H241RCDO(   rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ], &rcMbDataAccess, NULL, NULL ) );
    RNOK( xChromaVerFiltering_H241RCDO( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
    RNOK( xChromaHorFiltering_H241RCDO( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
    return Err::m_nOK;
  }

  const SliceHeader&  rcSliceHeader = rcMbDataAccess.getSH();
  const PicType       ePicType      = ( rcSliceHeader.getFieldPicFlag() ? rcSliceHeader.getPicType() : rcMbDataAccess.getMbPicType() );
  YuvPicBuffer*       pcYuvBuffer   = m_pcRecFrameUnit->getPic( ePicType )->getFullPelYuvBuffer();
  RNOK( xLumaVerFiltering_H241RCDO(   rcMbDataAccess, rcDFP, pcYuvBuffer ) );
  RNOK( xLumaHorFiltering_H241RCDO(   rcMbDataAccess, rcDFP, pcYuvBuffer ) );
  RNOK( xChromaVerFiltering_H241RCDO( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
  RNOK( xChromaHorFiltering_H241RCDO( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
  return Err::m_nOK;
}


__inline Void LoopFilter::xFilter( Pel* pFlt, const Int& iOffset, const Int& iIndexA, const Int& iIndexB, const UChar& ucBs, const Bool& bLum )
{
  const Int iAlpha = g_acAlphaClip[ iIndexA ].ucAlpha;

  Int P0 = pFlt[-iOffset];
  Int Q0 = pFlt[       0];

  Int iDelta = Q0 - P0;
  Int iAbsDelta  = abs( iDelta  );

  AOF_DBG( ucBs );

  ROFVS( iAbsDelta < iAlpha );


  const Int iBeta = g_aucBetaTab [ iIndexB ];

  Int P1  = pFlt[-2*iOffset];
  Int Q1  = pFlt[   iOffset];

  ROFVS( (abs(P0 - P1) < iBeta) && (abs(Q0 - Q1) < iBeta) );

  if( ucBs < 4 )
  {
    Int C0 = g_acAlphaClip[ iIndexA ].aucClip[ucBs];

    if( bLum )
    {
      Int P2 = pFlt[-3*iOffset] ;
      Int Q2 = pFlt[ 2*iOffset] ;
      Int aq = (( abs( Q2 - Q0 ) < iBeta ) ? 1 : 0 );
      Int ap = (( abs( P2 - P0 ) < iBeta ) ? 1 : 0 );

      if( ap )
      {
        pFlt[-2*iOffset] = P1 + gClipMinMax((P2 + ((P0 + Q0 + 1)>>1) - (P1<<1)) >> 1, -C0, C0 );
      }

      if( aq  )
      {
        pFlt[   iOffset] = Q1 + gClipMinMax((Q2 + ((P0 + Q0 + 1)>>1) - (Q1<<1)) >> 1, -C0, C0 );
      }

      C0 += ap + aq -1;
    }

    C0++;
    Int iDiff      = gClipMinMax(((iDelta << 2) + (P1 - Q1) + 4) >> 3, -C0, C0 ) ;
    pFlt[-iOffset] = gClip( P0 + iDiff );
    pFlt[       0] = gClip( Q0 - iDiff );
    return;
  }


  if( ! bLum )
  {
    pFlt[         0] = ((Q1 << 1) + Q0 + P1 + 2) >> 2;
    pFlt[  -iOffset] = ((P1 << 1) + P0 + Q1 + 2) >> 2;
  }
  else
  {
    Int P2 = pFlt[-3*iOffset] ;
    Int Q2 = pFlt[ 2*iOffset] ;
    Bool bEnable  = (iAbsDelta < ((iAlpha >> 2) + 2));
    Bool aq       = bEnable & ( abs( Q2 - Q0 ) < iBeta );
    Bool ap       = bEnable & ( abs( P2 - P0 ) < iBeta );
    Int PQ0 = P0 + Q0;

    if( aq )
    {
      pFlt[         0] = (P1 + ((Q1 + PQ0) << 1) +  Q2 + 4) >> 3;
      pFlt[   iOffset] = (PQ0 +Q1 + Q2 + 2) >> 2;
      pFlt[ 2*iOffset] = (((pFlt[ 3*iOffset] + Q2) <<1) + Q2 + Q1 + PQ0 + 4) >> 3;
    }
    else
    {
      pFlt[         0] = ((Q1 << 1) + Q0 + P1 + 2) >> 2;
    }

    if( ap )
    {
      pFlt[  -iOffset] = (Q1 + ((P1 + PQ0) << 1) +  P2 + 4) >> 3;
      pFlt[-2*iOffset] = (PQ0 +P1 + P2 + 2) >> 2;
      pFlt[-3*iOffset] = (((pFlt[-4*iOffset] + P2) <<1) + pFlt[-3*iOffset] + P1 + PQ0 + 4) >> 3;
    }
    else
    {
      pFlt[  -iOffset] = ((P1 << 1) + P0 + Q1 + 2) >> 2;
    }
  }
}


#define Clip1Y(a)          ((a)>255 ? 255 :((a)<0?0:(a)))
#define Clip1C(a)          ((a)>255 ? 255 :((a)<0?0:(a)))
#define Clip3(mn,mx,val)   (((val)<(mn))?(mn):(((val)>(mx))?(mx):(val)))


__inline Void LoopFilter::xFilter_H241RCDO( Pel* pFlt, const Int& iOffset, const Int& iIndexA, const Int& iIndexB, const Int& blk_pos, const Bool& bLum )
{
  const Int iTc   = g_aucTcTab_H241RCDO   [ iIndexA ];
  Int       P2    = pFlt[-3*iOffset];
  Int       P1    = pFlt[-2*iOffset];
  Int       P0    = pFlt[-1*iOffset];
  Int       Q0    = pFlt[         0];
  Int       Q1    = pFlt[ 1*iOffset];
  Int       Q2    = pFlt[ 2*iOffset];
  Int       iDelta;

  if( bLum )
  {
    if( blk_pos ) // not on macroblock edge
    {
      iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( ( P2 + Q1 ) >> 1 ) ) >> 1 ) - ( ( P0 + ( ( Q2 + P1 ) >> 1 ) ) >> 1 ) );
    }
    else
    {
      iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( Q1 >> 1 ) ) >> 1 ) - ( ( P0 + ( Q2 >> 1 ) ) >> 1 ) );
    }

    pFlt[-2*iOffset] = Clip1Y(P1 +(iDelta/2));
    pFlt[-1*iOffset] = Clip1Y(P0 + iDelta    );
    pFlt[         0] = Clip1Y(Q0 - iDelta    );
    pFlt[ 1*iOffset] = Clip1Y(Q1 -(iDelta/2));
  }
  else
  {
    iDelta           = Clip3 ( -iTc, iTc, ( ( ( ( Q0 - P0 ) << 2 ) + P1 - Q1 + 4 ) >> 3 ) );
    pFlt[-iOffset]   = Clip1C( P0 + iDelta );
    pFlt[       0]   = Clip1C( Q0 - iDelta );
  }
}


__inline Void LoopFilter::xFilter_H241RCDO( XPel* pFlt, const Int& iOffset, const Int& iIndexA, const Int& iIndexB, const Int& blk_pos, const Bool& bLum )
{
  const Int iTc   = g_aucTcTab_H241RCDO   [ iIndexA ];
  Int       P2    = pFlt[-3*iOffset];
  Int       P1    = pFlt[-2*iOffset];
  Int       P0    = pFlt[-1*iOffset];
  Int       Q0    = pFlt[         0];
  Int       Q1    = pFlt[ 1*iOffset];
  Int       Q2    = pFlt[ 2*iOffset];
  Int       iDelta;

  if( bLum )
  {
    if( blk_pos ) // not on macroblock edge
    {
      iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( ( P2 + Q1 ) >> 1 ) ) >> 1 ) - ( ( P0 + ( ( Q2 + P1 ) >> 1 ) ) >> 1 ) );
    }
    else
    {
      iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( Q1 >> 1 ) ) >> 1 ) - ( ( P0 + ( Q2 >> 1 ) ) >> 1 ) );
    }

    pFlt[-2*iOffset] = Clip1Y(P1 +(iDelta/2));
    pFlt[-1*iOffset] = Clip1Y(P0 + iDelta    );
    pFlt[         0] = Clip1Y(Q0 - iDelta    );
    pFlt[ 1*iOffset] = Clip1Y(Q1 -(iDelta/2));
  }
  else
  {
    iDelta           = Clip3 ( -iTc, iTc, ( ( ( ( Q0 - P0 ) << 2 ) + P1 - Q1 + 4 ) >> 3 ) );
    pFlt[-iOffset]   = Clip1C( P0 + iDelta );
    pFlt[       0]   = Clip1C( Q0 - iDelta );
  }
}


__inline ErrVal LoopFilter::xLumaVerFiltering_H241RCDO( const MbDataAccess& rcMbDataAccess, const DFP& rcDFP, YuvPicBuffer* pcYuvBuffer )
{
  Int   iCurrQp = rcMbDataAccess.getMbDataCurr().getQpLF();
  Int   iStride = pcYuvBuffer->getLStride();
  Pel*  pPelLum = pcYuvBuffer->getMbLumAddr();

  Bool  b8x8            = rcMbDataAccess.getMbData().isTransformSize8x8();
  Bool  filterBlockEdge = false;
  Bool  bFilterTopOnly  = false;
  Bool  bFilterBotOnly  = false;
  Short sHorMvThr       = 4;
  Short sVerMvThr       = ( FRAME == rcMbDataAccess.getMbPicType() ? 4 : 2 );

  Int   CheckMVandRefVal;
  Int   xBlk, yBlk, iLeftQp = 0, iLeftQpTop = 0, iLeftQpBot = 0;



  //===== LEFT MACROBLOCK EDGE =====
  B4x4Idx cIdx=0;
  for( yBlk = 0; yBlk <= 8; yBlk+=8 )
  {
    filterBlockEdge       = rcMbDataAccess.isLeftMbExisting();
    bFilterTopOnly        = false;
    bFilterBotOnly        = false;
    if( filterBlockEdge )
    {
      Bool  bLeftIntra    = rcMbDataAccess.getMbDataLeft().isIntra();
      iLeftQp             = rcMbDataAccess.getMbDataLeft().getQpLF();
      if( m_bVerMixedMode )
      {
        if      ( rcMbDataAccess.getMbData().getFieldFlag() && yBlk == 0 )
        {
          bLeftIntra      = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().isIntra() : rcMbDataAccess.getMbDataAboveLeft().isIntra() );
          iLeftQp         = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().getQpLF() : rcMbDataAccess.getMbDataAboveLeft().getQpLF() );
        }
        else if ( rcMbDataAccess.getMbData().getFieldFlag() )
        {
          bLeftIntra      = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().isIntra() : rcMbDataAccess.getMbDataLeft().isIntra() );
          iLeftQp         = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().getQpLF() : rcMbDataAccess.getMbDataLeft().getQpLF() );
        }
        else // current pair is frame, left pair is field
        {
          Bool bLI_Top    = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().isIntra() : rcMbDataAccess.getMbDataAboveLeft().isIntra() );
          Bool bLI_Bot    = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().isIntra() : rcMbDataAccess.getMbDataLeft().isIntra() );
          iLeftQpTop      = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().getQpLF() : rcMbDataAccess.getMbDataAboveLeft().getQpLF() );
          iLeftQpBot      = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().getQpLF() : rcMbDataAccess.getMbDataLeft().getQpLF() );
          if( ( bLI_Top ^ bLI_Bot ) && LFM_DEFAULT_FILTER != m_eLFMode )
          {
            bLeftIntra    = true;
            bFilterTopOnly= bLI_Top;
            bFilterBotOnly= bLI_Bot;
          }
          else
          {

⌨️ 快捷键说明

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