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

📄 fgssubbandencoder.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {
      ui++;
      m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1]+uiGroupingSize;
    }
  }
  else
  {
    //vector specified
    ui = 0;
    m_auiScanPosVectLuma[ui] = m_pcSliceHeader->getPosVect(ui) - 1;
    while( m_auiScanPosVectLuma[ui] < 15)
    {
      ui++;
      m_auiScanPosVectLuma[ui] = m_auiScanPosVectLuma[ui-1] + m_pcSliceHeader->getPosVect(ui);
    }
  }

  try
  {
    UInt uiScanPos;
    UInt iStartCycle = 0, iCycle = 0;
    UInt iLastBitsLuma   = 0;
    UInt iLastBitsChroma = 0;
    UInt iBitsLuma       = 0;
    UInt iBitsChroma     = 0;
    UInt iLumaScanIdx     = 0;
    UInt iChromaDCScanIdx = 0;
    UInt iChromaACScanIdx = 1;
    UInt uiPass;
    UInt uiPassStart;

    m_uiFirstMbInSlice  = m_pcSliceHeader->getFirstMbInSlice();
    UInt uiLastMbInSlice  = m_pcSliceHeader->getLastMbInSlice();

    //--ICU/ETRI FMO Implementation : start
    UInt uiFirstMbY = (UInt) ( m_uiFirstMbInSlice / m_uiWidthInMB );
    UInt uiFirstMbX = m_uiFirstMbInSlice % m_uiWidthInMB;
    uiLastMbY  = (UInt) ( ( uiLastMbInSlice+1) / m_uiWidthInMB );
    uiLastMbX  = ( uiLastMbInSlice+1) % m_uiWidthInMB;


      if(!uiFracNb) //FIX_FRAG_CAVLC
      {
      // Pre-scan frame to find VLC positions
      UInt  auiEobShift[16];
      UInt  auiHighMagHist[16];
      UInt  auiBestCodeTabMap[16];
      UInt* pauiHistLuma    = new UInt[16*16*16];
      UInt* pauiHistChroma  = new UInt[16*16*16];

      ::memset(pauiHistLuma  , 0x00, 16*16*16*sizeof(UInt));
      ::memset(pauiHistChroma, 0x00, 16*16*16*sizeof(UInt));
      ::memset(auiHighMagHist, 0x00,       16*sizeof(UInt));

      for(UInt uiMbAddress=m_uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice ;)
	  {
        UInt uiMbYIdx = uiMbAddress / m_uiWidthInMB;
        UInt uiMbXIdx = uiMbAddress % m_uiWidthInMB;
        MbDataAccess *pcMbDataAccessCurr = NULL;
        RNOK( m_cMbDataCtrlEL    .initMb( pcMbDataAccessCurr, uiMbYIdx, uiMbXIdx ) );
        const Bool bFrame = (FRAME == pcMbDataAccessCurr->getMbPicType());

      {
        //===== LUMA =====
        for( UInt uiB8YIdx = 2 * uiMbYIdx; uiB8YIdx < 2 * uiMbYIdx + 2; uiB8YIdx++ )
        for( UInt uiB8XIdx = 2 * uiMbXIdx; uiB8XIdx < 2 * uiMbXIdx + 2; uiB8XIdx++ )
        {
          for( UInt uiBlockYIdx = 2 * uiB8YIdx; uiBlockYIdx < 2 * uiB8YIdx + 2; uiBlockYIdx++ )
          for( UInt uiBlockXIdx = 2 * uiB8XIdx; uiBlockXIdx < 2 * uiB8XIdx + 2; uiBlockXIdx++ )
          {
          RNOK( xVLCParseLuma( uiBlockYIdx, uiBlockXIdx, pauiHistLuma, auiHighMagHist, bFrame ) );
          } // 4x4 block iteration
        } // 8x8 block iteration
        // ===== CHROMA AC =====
        for( UInt uiPlane = 0; uiPlane  < 2; uiPlane ++ )
        for( UInt uiB8YIdx = 2 * uiMbYIdx; uiB8YIdx < 2 * uiMbYIdx + 2; uiB8YIdx++ )
        for( UInt uiB8XIdx = 2 * uiMbXIdx; uiB8XIdx < 2 * uiMbXIdx + 2; uiB8XIdx++ ) {
          RNOK( xVLCParseChromaAC( uiPlane, uiB8YIdx, uiB8XIdx, pauiHistChroma, bFrame ) );
        } 
      } // macroblock iteration

		//--ICU/ETRI FMO Implementation
        uiMbAddress = m_pcSliceHeader->getFMO()->getNextMBNr(uiMbAddress );
	  }
      
      RNOK( m_cMbDataCtrlEL    .initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );
      RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );

      // Tally over base pos to find EOB shift
      for (uiScanPos=0; uiScanPos<16; uiScanPos++)
      {
        auiEobShift[uiScanPos] = 0;
        for (UInt uiHpos=1; uiHpos<16; uiHpos++) {
          UInt uiTotal = 0;
          for (UInt uiBase=0; uiBase<16; uiBase++)
            uiTotal += pauiHistLuma[(uiScanPos*16+uiBase)*16+uiHpos];
          if (uiTotal < auiHighMagHist[uiScanPos])
            break;
          if (uiScanPos > 0 && auiEobShift[uiScanPos] == auiEobShift[uiScanPos-1])
            break;
          auiEobShift[uiScanPos]++;
        }
      }
      // 'Outlier' removal
      if (auiEobShift[0] > auiEobShift[1] + 8)
        auiEobShift[0] = 15;

      RNOK( m_pcSymbolWriter->RQencodeEobOffsets_Luma( auiEobShift ) );

        UInt uiTempCodeLenCycleBase[][16] = {
        {1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16}, // unary          0
        {2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9}, // flat 2         1
        {2, 2, 2, 4, 4, 4, 6, 6, 6, 8, 8, 8,10,10,10,11}, // flat 3         2
        {1, 3, 3, 3, 5, 5, 5, 7, 7, 7, 9, 9, 9,11,11,11}, // S3 cutoff 0    3
        {1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,9, 9, 9}}; //    
        UInt *pauiHistLumaNoBase = new UInt[16*16];
        UInt uiTotalNumCodeTable = 5;
        UInt uiTotalRunCost = 0;
        UInt uiCycle=0;

        // tally histogram without LEBL index
        memset(pauiHistLumaNoBase, 0, sizeof(UInt)*16*16);
        for(uiCycle = 0; uiCycle < 16; uiCycle++)
        {
          for(ui = 0; ui < 16; ui++)
            for(UInt uiBase = 0; uiBase < 16; uiBase++)
              pauiHistLumaNoBase[uiCycle*16+ui] += pauiHistLuma[(uiCycle*16+uiBase)*16+ui];
            }

          uiCycle = 0;
          UInt uiBestTable; 
          UInt uiCost[5], uiBestCost;
          UInt uiTableIdx;

          // find the cost of using each table 
          for(uiTableIdx = 0; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
          {
            UInt *uiTable = uiTempCodeLenCycleBase[uiTableIdx];

            uiCost[uiTableIdx] = 0;
            for(ui = 1; ui < 16; ui++)
            {
              UInt uiCodeLen = uiTable[ui-1];

              uiCost[uiTableIdx] += pauiHistLumaNoBase[ui]*uiCodeLen;
            }
          }

          // find the best table with lowest cost 
          uiBestTable = 0;
          uiBestCost = uiCost[0];
          for(uiTableIdx = 1; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
          {
            if(uiCost[uiTableIdx] < uiBestCost)
            {
              uiBestTable = uiTableIdx;
              uiBestCost = uiCost[uiTableIdx];
            }
          }

          auiBestCodeTabMap[uiCycle] = uiBestTable;
          uiTotalRunCost += uiBestCost;

        for(uiCycle = 1; uiCycle < 16; uiCycle++)
        {
          // find the cost of using each table 
          for( uiTableIdx = 0; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
          {
            UInt *uiTable = uiTempCodeLenCycleBase[uiTableIdx];

            uiCost[uiTableIdx] = 0;
            for(ui = 0; ui < 16; ui++)
            {
              UInt uiSymbol; 
              if(ui == 0)
              {
                uiSymbol = auiEobShift[uiCycle];
              }
              else
              {
                uiSymbol = (ui <= auiEobShift[uiCycle])? ui-1:ui;
              }
              UInt uiCodeLen = uiTable[uiSymbol];
              uiCost[uiTableIdx] += pauiHistLumaNoBase[(uiCycle*16)+ui]*uiCodeLen;
            }
          }

          // find the best table with lowest cost 
          uiBestTable = 0;
          uiBestCost = uiCost[0];
          for(uiTableIdx = 1; uiTableIdx < uiTotalNumCodeTable; uiTableIdx++)
          {
            if(uiCost[uiTableIdx] < uiBestCost)
            {
              uiBestTable = uiTableIdx;
              uiBestCost = uiCost[uiTableIdx];
            }
          }

          auiBestCodeTabMap[uiCycle] = uiBestTable;
          uiTotalRunCost += uiBestCost;
        }
        delete pauiHistLumaNoBase;

      // Tally over base pos to find EOB shift
    for (uiScanPos=0; uiScanPos<16; uiScanPos++)
    {
        auiEobShift[uiScanPos] = 0;
        UInt uiEobTotal = 0;
        for (UInt uiBase=0; uiBase<16; uiBase++)
          uiEobTotal += pauiHistChroma[(uiScanPos*16+uiBase)*16];
      for (UInt uiHpos=1; uiHpos<16; uiHpos++)
      {
          UInt uiTotal = 0;
          for (int uiBase=0; uiBase<16; uiBase++)
            uiTotal += pauiHistChroma[(uiScanPos*16+uiBase)*16+uiHpos];
          if (uiTotal < uiEobTotal)
            break;
          if (uiScanPos > 0 && auiEobShift[uiScanPos] == auiEobShift[uiScanPos-1])
            break;
          auiEobShift[uiScanPos]++;
        }
      }
      // 'Outlier' removal
      if (auiEobShift[0] > auiEobShift[1] + 8)
        auiEobShift[0] = 15;

      RNOK( m_pcSymbolWriter->RQencodeEobOffsets_Chroma( auiEobShift ) );
      RNOK( m_pcSymbolWriter->RQencodeBestCodeTableMap( auiBestCodeTabMap, 16 ) );
      delete pauiHistLuma;
      delete pauiHistChroma;
      } //FIX_FRAG_CAVLC

    uiLumaCbpBitCount    = 0;
    uiLumaCbpNextMbX     = uiFirstMbX;
    uiLumaCbpNextMbY     = uiFirstMbY;
    uiLumaCbpNext8x8Idx  = 0;
    uiChromaCbpBitCount  = 0;
    uiChromaCbpNextMbX   = uiFirstMbX;
    uiChromaCbpNextMbY   = uiFirstMbY;

      if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() && !uiFracNb)
      {
      xEncodeLumaCbpVlcStart( uiLumaCbpNextMbX, uiLumaCbpNextMbY, uiLumaCbpNext8x8Idx,
          uiLastMbX, uiLastMbY, uiLumaCbpBitCount);

        xEncodeChromaCbpVlcStart(uiFirstMbX, uiFirstMbY, uiChromaCbpBitCount);
      }

    ruiNumPDFrags     = 0;
    puiPDFragBits[0]  = 0;

    // chroma cycle frequency. 
    // hard-coded for now, should this be moved to the slice header
    iStartCycle = ( m_eSliceType == B_SLICE ) ? 2 : 3;
    if( !uiFracNb )
    {
    m_pcSymbolWriter->RQencodeCycleSymbol( iStartCycle-1 );
    }

    UInt  uiNumFrags;
    Int   aiMaxPosLuma[16], aiMaxPosChromaAC[16], aiMaxPosChromaDC[16];

    uiFragIdx = 0;
    uiNumFrags = xDeriveComponentPosVectors( m_auiScanPosVectLuma, 
      aiMaxPosLuma, aiMaxPosChromaAC, aiMaxPosChromaDC, iStartCycle );

    while (iLumaScanIdx < 16 || iChromaDCScanIdx < 4 || iChromaACScanIdx < 16)
    {
      UInt bAllowChromaDC, bAllowChromaAC;

      UInt uiMaxPosLuma;
      UInt uiMaxPosChromaAC;
      UInt uiMaxPosChromaDC;

        if(!uiFracNb)
        {
          // start values for loops
          m_uiMbYIdx    = uiFirstMbY;
          m_uiMbXIdx    = ( m_uiMbYIdx == uiFirstMbY ? uiFirstMbX : 0 );
        m_c8x8Idx     = B8x8Idx();
        m_cIdx        = S4x4Idx();
          m_uiFGSPart   = 0;
          uiPassStart   = 0;
        }
        else
        {
          if(bRestore)
          {
            bCheck = false;
            // restore status
            xRestoreFGSState(iLumaScanIdx, iChromaDCScanIdx, iChromaACScanIdx, iStartCycle,
                            iCycle, uiPassStart, uiFragIdx, 
                            iLastBitsLuma,
                            iLastQP);

            // restore the cbp-related coding states 
            uiLumaCbpNextMbX    = m_uiLumaCbpNextMbX;
            uiLumaCbpNextMbY    = m_uiLumaCbpNextMbY;
            uiLumaCbpNext8x8Idx = m_uiLumaCbpNext8x8Idx;
            uiChromaCbpNextMbX  = m_uiChromaCbpNextMbX;
            uiChromaCbpNextMbY  = m_uiChromaCbpNextMbY;
            bRestore = false;
          }
          else
          {
            uiPassStart = 0;
          }
        }
        uiPass = uiPassStart; 

     uiMaxPosLuma      = aiMaxPosLuma    [uiFragIdx];
      uiMaxPosChromaAC  = aiMaxPosChromaAC[uiFragIdx];
      uiMaxPosChromaDC  = aiMaxPosChromaDC[uiFragIdx];

      if( uiFragIdx == 0 )
      {
        bAllowChromaDC = true;
        bAllowChromaAC = aiMaxPosChromaAC[0] > 0;
      }
      else
      {
        bAllowChromaDC = (Int) uiMaxPosChromaDC > aiMaxPosChromaDC[uiFragIdx - 1];
        bAllowChromaAC = (Int) uiMaxPosChromaAC > aiMaxPosChromaAC[uiFragIdx - 1];
      }

      // flush the bitstream, and send the re-sync marker
      if( m_pcSliceHeader->getFGSCycleAlignedFragment() )
      {
        // any more fragment to follow?
        if( iLumaScanIdx > 0 )
        {
          // do not know why the reader can not have enough bits
          RNOK( m_pcSymbolWriter->RQencodeTermBit( 1 ) );
          RNOK( m_pcSymbolWriter->RQencodeTermBit( 1 ) );
          RNOK( m_pcSymbolWriter->finishSlice() );

          // byte-aligned, same as NalUnitEncoder::xWriteTrailingBits
          RNOK( m_pcSymbolWriter->getWriteBuffer()->write( 1 ) );
          RNOK( m_pcSymbolWriter->getWriteBuffer()->writeAlignZero() );

          // do not have to flush the buffer as more fragments will be coded
          // record the end of the segment
          puiPDFragBits[uiFragIdx] = m_pcSymbolWriter->getWriteBuffer()->getNumberOfWrittenBits();

          m_pcSliceHeader->setSliceType( m_eSliceType );
          m_pcSymbolWriter->RQreset( *m_pcSliceHeader );
          m_pcSliceHeader->setSliceType( F_SLICE );
        }
      }

		    for(UInt uiMbAddress=m_uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice;)
		    {
        const UInt uiMbYIdx = uiMbAddress / m_uiWidthInMB;
        const UInt uiMbXIdx = uiMbAddress % m_uiWidthInMB;
			    
			     MbDataAccess *pcMbDataAccess = NULL;
          RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccess, uiMbYIdx, uiMbXIdx ) );
          const Bool bFrame = (FRAME == pcMbDataAccess->getMbPicType());

			    {
            if( ! m_pcSliceHeader->getPPS().getEntropyCodingModeFlag() )
            {
              Bool bFirstPassPrescan = bFirstPass;
              UInt uiB8YInit, uiB8XInit, uiBlockYInit, uiBlockXInit;
            uiB8YInit = m_uiMbYIdx*2 + m_c8x8Idx.y()/2;
            uiB8XInit = m_uiMbXIdx*2 + m_c8x8Idx.x()/2;
              uiBlockYInit = 2*uiB8YInit;
              uiBlockXInit = 2*uiB8XInit;
            if(!bFirstPassPrescan)
            {
                uiB8YInit = 2*uiMbYIdx;
                uiB8XInit = 2*uiMbXIdx;
              }

              /* refinement coefficients pre-scan */
              //===== LUMA =====
            if( (m_uiFGSPart == 0) || (!bFirstPassPrescan) )
            {
              for( UInt uiB8YIdx = uiB8YInit; uiB8YIdx < 2 * uiMbYIdx + 2; uiB8YIdx++ )
              {
                for( UInt uiB8XIdx = uiB8XInit; uiB8XIdx < 2 * uiMbXIdx + 2; uiB8XIdx++ )
                {
                  if(!bFirstPassPrescan

⌨️ 快捷键说明

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