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

📄 fgssubbanddecoder.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  pcMbDataAccessEL->getMbData().setMbCbp( (uiMbCbp & 0x0F) | (m_uiLastChromaCbp << 4) );
  m_uiChromaCbpRun --;

  return Err::m_nOK;
}

ErrVal
RQFGSDecoder::xDecodeMbHeader( MbDataAccess*      pcMbDataAccessBL,
                               MbDataAccess*      pcMbDataAccessEL,
                               MbFGSCoefMap       &rcMbFGSCoefMap,
                               Int&               riLastQp )
{
  UInt    uiMbX = pcMbDataAccessBL->getMbX();
  UInt    uiMbY = pcMbDataAccessBL->getMbY();
  UInt    uiCbpBit;
  MbSymbolReadIf* pcMbHeaderReader;

  pcMbHeaderReader =  m_pcSymbolReader->RQactivateFragment( 0 );

  const Bool    bMbAff   = m_pcSliceHeader->isMbAff   ();// TMM_INTERLACE
  if( m_pcSliceHeader->getAdaptivePredictionFlag() &&
    ! pcMbDataAccessBL->getMbData().isIntra() )
  {
    // the error is not handled if it is termnated early
    RNOKS( m_pcMbParser ->readMotion( *pcMbDataAccessEL, pcMbDataAccessBL ) );
    RNOK ( m_pcMbDecoder->calcMv    ( *pcMbDataAccessEL, pcMbDataAccessBL ) );

    if( ! pcMbDataAccessEL->getMbData().getBLSkipFlag() && ! pcMbDataAccessEL->getMbData().getResidualPredFlag( PART_16x16 ) )
    {
      //----- motion refinement without residual prediction ===> clear base layer coeffs -----
      UInt            uiLayer         = m_pcSliceHeader->getLayerId();
      YuvBufferCtrl*  pcYuvBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
      RNOK( pcYuvBufferCtrl->initMb( uiMbY, uiMbX, bMbAff ) );
      RNOK( xClearBaseCoeffs( *pcMbDataAccessEL, pcMbDataAccessBL ) );
    }
  }

  //===== CBP =====
  if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() ) {
    RNOKS( xDecodeLumaCbpVlc   ( uiMbX, uiMbY ) );
    RNOKS( xDecodeChromaCbpVlc ( uiMbX, uiMbY ) );

    // restore pcMbDataAccessBL and pcMbDataAccessEL, may not be necessary
    RNOK( m_pcCurrMbDataCtrl ->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
    RNOK( m_cMbDataCtrlEL     .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
  }

  // Luma CBP in CABAC, need also for CAVLC to update the CBP in buffer
  {
    for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx ++ )
    RNOKS( pcMbHeaderReader->RQdecodeCBP_8x8( *pcMbDataAccessEL, *pcMbDataAccessBL, c8x8Idx ) );
  }

  // CHROMA CBP in CABAC, need also for CAVLC to update the CBP in buffer
  RNOKS( pcMbHeaderReader->RQdecodeCBP_Chroma( *pcMbDataAccessEL, *pcMbDataAccessBL, uiCbpBit ) );
  if( uiCbpBit )
    RNOKS( pcMbHeaderReader->RQdecodeCBP_ChromaAC( *pcMbDataAccessEL, *pcMbDataAccessBL, uiCbpBit ) );

  // transform size
  if( ( pcMbDataAccessBL->getMbData().getMbCbp() & 15 ) &&
    ! ( rcMbFGSCoefMap.getMbMap() & TRANSFORM_SPECIFIED ) ) {
    RNOKS( pcMbHeaderReader->RQdecode8x8Flag( *pcMbDataAccessEL, *pcMbDataAccessBL ) );
    rcMbFGSCoefMap.getMbMap() |= TRANSFORM_SPECIFIED;
  }

  // delta QP and transform flag
  if( pcMbDataAccessBL->getMbData().getMbCbp() != 0 ) {
    if( ! ( rcMbFGSCoefMap.getMbMap() & SIGNIFICANT ) ) {
      pcMbDataAccessEL->setLastQp( riLastQp );
      RNOKS( pcMbHeaderReader->RQdecodeDeltaQp( *pcMbDataAccessEL ) );
      riLastQp = pcMbDataAccessEL->getMbData().getQp();

      rcMbFGSCoefMap.getMbMap() |= SIGNIFICANT;
    }
  }

  // Luma BCBP
  {
    for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx ++ ) {
      Bool bSigBCBP = ( ( pcMbDataAccessEL->getMbData().getMbCbp() >> c8x8Idx.b8x8Index() ) & 1 ? 1 : 0 );
      Bool b8x8     = pcMbDataAccessBL->getMbData().isTransformSize8x8();

      // 8x8 in VLC mode is de-interleaved into 4 4x4 blocks
      // 8x8 in CABAC mode is encoded in native 8x8 zigzag order, and no BCBP is needed
      if( bSigBCBP && (! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() || ! b8x8 ) ) {
        for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx ++ )
          RNOKS( pcMbHeaderReader->RQdecodeBCBP_4x4( *pcMbDataAccessEL, *pcMbDataAccessBL, b8x8, cIdx, uiCbpBit ) );
      }
      else
      {
        S4x4Idx cIdx (c8x8Idx);

        rcMbFGSCoefMap.getLumaScanPos( cIdx+1 ) = 64; 
      }
    }
  }

  // do not track the number of coefficients in the decoder
  xUpdateMbMaps( pcMbDataAccessBL, pcMbDataAccessEL, rcMbFGSCoefMap, 0 );

  return Err::m_nOK;
}

const UChar g_aucLinearScan[16] =
{
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15
};


ErrVal
RQFGSDecoder::xResidualBlock        ( MbDataAccess&   rcMbDataAccess,
                                      MbDataAccess&   rcMbDataAccessBase,
                                      ResidualMode    eResidualMode,
                                      UInt            uiStride,
                                      UInt            uiBlkIdx,
                                      UInt&           uiBcbp,
                                      Bool            bDecodeBcbpInside,
                                      Int*            piMaxPos, 
                                      RefCtx*         pcRefCtx, 
                                      UInt&           ruiNumFrags,
                                      UInt&           ruiCoeffsDecoded )
{
  UInt      uiStart, uiStop, uiCycle, uiFragIdx, uiNumCoeffs;
  Bool      bFirstSigRunCode, bEndOfBlock;
  UInt      uiRun;
  TCoeff    iCoeff;
  TCoeff*   piCoeff;
  TCoeff*   piCoeffBase;
  UInt      uiLastScanIdx;
  ErrVal    eStatus;
  MbSymbolReadIf*   pcFragmentReader;
  const UChar*      pucScan;

  TCoeff    aiCoeffTemp[16];
  TCoeff    aiCoeffBaseTemp[16];
  UInt      uiBlkX, uiBlkY, uiB8x8, uiB4x4IdxInB8x8;
  Par8x8    ePar8x8 = Par8x8(0);

  uiB4x4IdxInB8x8 = 0;
  if( eResidualMode == LUMA_SCAN && uiStride == 1 ) {
    // the normal 4x4 block
    piCoeff         = rcMbDataAccess    .getMbTCoeffs().get( B4x4Idx( uiBlkIdx ) );
    piCoeffBase     = rcMbDataAccessBase.getMbTCoeffs().get( B4x4Idx( uiBlkIdx ) );
    pucScan         = g_aucFrameScan;
  }
  else if ( eResidualMode == LUMA_8X8 || uiStride == 4 ) {
    uiBlkX  = uiBlkIdx % 4;
    uiBlkY  = uiBlkIdx / 4;
    uiB8x8  = (uiBlkY / 2) * 2 + uiBlkX / 2;
    ePar8x8 = Par8x8(uiB8x8);

    uiB4x4IdxInB8x8 = (uiBlkY % 2) * 2 + (uiBlkX % 2);
    piCoeffBase     = rcMbDataAccessBase.getMbTCoeffs().get8x8( B8x8Idx( ePar8x8 ) );

    if( uiStride == 4) {
      // 4x4 block within 8x8 block, deinteleave piCoeffBase to aiCoeffBaseTemp
      for( uiCycle = 0; uiCycle < 16; uiCycle ++ )
        aiCoeffBaseTemp[ uiCycle ] = piCoeffBase[ g_aucFrameScan64[uiCycle * 4 + uiB4x4IdxInB8x8] ];

      piCoeffBase   = aiCoeffBaseTemp;

      memset( aiCoeffTemp, 0, 16 * sizeof(TCoeff) );
      piCoeff       = aiCoeffTemp;
      pucScan       = g_aucLinearScan;
    }
    else {
      // cabac uses native 8x8 zigzag scan
      piCoeff       = rcMbDataAccess    .getMbTCoeffs().get8x8( B8x8Idx( ePar8x8 ) );
      pucScan       = g_aucFrameScan64;

      // a dirty fix
      // in "-pd 0" path, it is set in RQdecodeNewTCoeff_8x8, should be in higher level
      if( uiBcbp ) {
        B8x8Idx c8x8Idx( ePar8x8 );
        rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4(),   1 );
        rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+1, 1 );
        rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+4, 1 );
        rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+5, 1 );
      }
    }
  }
  else {
    piCoeff         = rcMbDataAccess    .getMbTCoeffs().get( CIdx( uiBlkIdx ) );
    piCoeffBase     = rcMbDataAccessBase.getMbTCoeffs().get( CIdx( uiBlkIdx ) );
    pucScan         = eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : g_aucFrameScan;
  }

  uiStart           = ( eResidualMode == CHROMA_AC ) ? 1 : 0;
  uiStop            = ( eResidualMode == CHROMA_DC ) ? 4 : ( ( eResidualMode == LUMA_8X8 ) ? 64 : 16 );

  bFirstSigRunCode  = true;
  bEndOfBlock       = ( uiBcbp == 0 ) ? 1 : 0;
  pcFragmentReader  = m_pcSymbolReader->RQactivateFragment( 0 );

  uiNumCoeffs       = 0;
  uiRun             = 0;
  eStatus           = Err::m_nOK;

  // last possible coefficient in the block
  for( uiLastScanIdx = uiStop - 1; uiLastScanIdx >= uiStart; uiLastScanIdx -- ) {
    if( ! piCoeffBase[pucScan[uiLastScanIdx]] )
      break;
  }

  for( uiFragIdx = 0, uiCycle = uiStart; uiCycle < uiStop; uiCycle ++ ) {
    UInt uiMaxPos;
    
    uiMaxPos = ( eResidualMode == LUMA_8X8 ) ? ( piMaxPos[uiFragIdx] * 4  +3 ) : piMaxPos[uiFragIdx];
    while( uiCycle > uiMaxPos ) {
      if( uiFragIdx == ruiNumFrags - 1 ) {
        pcFragmentReader = 0;
        break;
      }
      else {
        uiFragIdx ++;
        pcFragmentReader = m_pcSymbolReader->RQactivateFragment( uiFragIdx );
        uiMaxPos = ( eResidualMode == LUMA_8X8 ) ? ( piMaxPos[uiFragIdx] * 4  +3 ) : piMaxPos[uiFragIdx];
      }
    }

    // no more data for this block
    if( pcFragmentReader == 0 && uiRun == 0 )
      break;

    if( piCoeffBase[pucScan[uiCycle]] ) {
      if( pcFragmentReader ) {
        eStatus = pcFragmentReader->RQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiCycle, pcRefCtx[uiCycle] );
        if( eStatus != Err::m_nOK )
          break;

        Int iXCoeff; 
        //if( eResidualMode == LUMA_SCAN && uiStride == 1 )
        {
          iXCoeff = piCoeff[pucScan[uiCycle]];
          if( piCoeffBase[pucScan[uiCycle]] < 0 )
            iXCoeff = -iXCoeff;
        }
#if 0
        else if(eRedisualMode == LUMA_8x8 || uiStride == 4) 
        {
          iCoeff = pcMbDataAccessEL->getMbTCoeffs().get8x8( c8x8Idx )[g_aucFrameScan64[uiCycle]];
          if( pcMbDataAccessBL->getMbTCoeffs().get8x8( c8x8Idx )[g_aucFrameScan64[uiCycle]] < 0 )
            iCoeff = -iCoeff;
        }
#endif
        pcRefCtx[uiCycle] <<= 2;
        if( iXCoeff < 0 )
          pcRefCtx[uiCycle]+= 2;
        else if( iXCoeff > 0 )
          pcRefCtx[uiCycle]++;

       uiNumCoeffs ++;
      }
    }
    else {
      if( bDecodeBcbpInside && pcFragmentReader ) {
        // luma BCBP is currently decoded outside
        if( eResidualMode == CHROMA_AC )
          eStatus = pcFragmentReader->RQdecodeBCBP_ChromaAC( rcMbDataAccess, rcMbDataAccessBase, CIdx( uiBlkIdx ), uiBcbp );
        else
          eStatus = pcFragmentReader->RQdecodeBCBP_ChromaDC( rcMbDataAccess, rcMbDataAccessBase, CIdx( uiBlkIdx ), uiBcbp );

        if( eStatus != Err::m_nOK )
          break;

        bDecodeBcbpInside = false;
        bEndOfBlock       = ( uiBcbp == 0 ) ? 1 : 0;
      }

      if( uiRun > 0 )
        uiRun --;
      else if( ! bEndOfBlock && pcFragmentReader ) {
        iCoeff = 0;

        eStatus = pcFragmentReader->RQdecodeSigCoeff
          ( piCoeff, piCoeffBase, eResidualMode, pucScan, bFirstSigRunCode, uiCycle, uiStart, uiLastScanIdx, bEndOfBlock, iCoeff, uiRun );

        if( eStatus != Err::m_nOK )
          break;

        if( iCoeff != 0 )
        {
          uiNumCoeffs += uiRun + 1;
        }

        bFirstSigRunCode = false;
      }

      // bEndOfBlock indicates there is no significant coefficients
      // but there may be refinement coefficients to be decoded
      if( uiRun == 0 && ! bEndOfBlock )
      {
        piCoeff[pucScan[uiCycle]] = iCoeff;
        if(iCoeff)
          pcRefCtx[uiCycle] = 1;
      }
    }
  }
  if( uiStride == 4) {
    // de-interleaved 4x4 block, put decoded coefficients in the interleaved order
    piCoeff         = rcMbDataAccess    .getMbTCoeffs().get8x8( B8x8Idx( ePar8x8 ) );
    for( uiCycle = 0; uiCycle < 16; uiCycle ++ )
      piCoeff[ g_aucFrameScan64[uiCycle * 4 + uiB4x4IdxInB8x8] ] = aiCoeffTemp[ uiCycle ];
  }

  if( eStatus == Err::m_nEndOfStream ) {
    ruiNumFrags = uiFragIdx;
  }
  else {
    if( bEndOfBlock )
      uiNumCoeffs = uiStop - uiStart;
  }

  ruiCoeffsDecoded += uiNumCoeffs;

  return Err::m_nOK;
}


ErrVal
RQFGSDecoder::xResidualBlock    ( MbDataAccess&   rcMbDataAccess,
                                  MbDataAccess&   rcMbDataAccessBase,
                                  LumaIdx         cIdx, 
                                  ResidualMode    eResidualMode,
                                  UInt            uiStride,
                                  Int*            piMaxPos, 
                                  UInt&           ruiNumFrags,
                                  MbFGSCoefMap &  rcMbFGSCoefMap, 
                                  UInt&           ruiCoeffsDecoded )
{
  UInt          uiBcbp;
  RefCtx        *pcRefCtx;  
  B8x8Idx c8x8Idx( cIdx );

  if( eResidualMode == LUMA_8X8 )
  {
    uiBcbp    = ( rcMbDataAccess  .getMbData().getMbCbp() >> ( (cIdx.y()/2)*2 + cIdx.x()/2 ) ) & 1;
    pcRefCtx = rcMbFGSCoefMap.getRefCtx( c8x8Idx );
  }
  else
  { 
    UInt uiOffset = (cIdx.x()%2) + (cIdx.y()%2) * 2; 
    S4x4Idx c4x4Idx ( c8x8Idx );  
    c4x4Idx = c4x4Idx + uiOffset; 
    uiBcbp    = rcMbDataAccess    .getMbData().getBCBP( cIdx.b4x4() );
    pcRefCtx = rcMbFGSCoefMap.getRefCtx( c4x4Idx );
  }

  RNOKS( xResidualBlock( rcMbDataAccess, rcMbDataAccessBase, eResidualMode, uiStride, cIdx,
    uiBcbp, false, piMaxPos, pcRefCtx, ruiNumFrags, ruiCoeffsDecoded ) );

  return Err::m_nOK;
}


ErrVal

⌨️ 快捷键说明

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