Skip to content
Snippets Groups Projects
CABACWriter.cpp 99.9 KiB
Newer Older
  • Learn to ignore specific revisions
  •   }
      bool     codeLast = ( maxSymbol > symbol );
      unsigned bins     = 0;
      unsigned numBins  = 0;
      while( symbol-- )
      {
        bins   <<= 1;
        bins   ++;
        numBins++;
      }
      if( codeLast )
      {
        bins  <<= 1;
        numBins++;
      }
      CHECK(!( numBins <= 32 ), "Unspecified error");
      m_BinEncoder.encodeBinsEP( bins, numBins );
    }
    
    
    void CABACWriter::exp_golomb_eqprob( unsigned symbol, unsigned count )
    {
      unsigned bins    = 0;
      unsigned numBins = 0;
      while( symbol >= (unsigned)(1<<count) )
      {
        bins <<= 1;
        bins++;
        numBins++;
        symbol -= 1 << count;
        count++;
      }
      bins <<= 1;
      numBins++;
      bins = (bins << count) | symbol;
      numBins += count;
      CHECK(!( numBins <= 32 ), "Unspecified error");
      m_BinEncoder.encodeBinsEP( bins, numBins );
    }
    
    void CABACWriter::codeAlfCtuEnableFlags( CodingStructure& cs, ChannelType channel, AlfSliceParam* alfParam)
    {
      if( isLuma( channel ) )
      {
        if (alfParam->enabledFlag[COMPONENT_Y])
          codeAlfCtuEnableFlags( cs, COMPONENT_Y, alfParam );
      }
      else
      {
        if (alfParam->enabledFlag[COMPONENT_Cb])
          codeAlfCtuEnableFlags( cs, COMPONENT_Cb, alfParam );
        if (alfParam->enabledFlag[COMPONENT_Cr])
          codeAlfCtuEnableFlags( cs, COMPONENT_Cr, alfParam );
      }
    }
    void CABACWriter::codeAlfCtuEnableFlags( CodingStructure& cs, ComponentID compID, AlfSliceParam* alfParam)
    {
      uint32_t numCTUs = cs.pcv->sizeInCtus;
    
      for( int ctuIdx = 0; ctuIdx < numCTUs; ctuIdx++ )
      {
        codeAlfCtuEnableFlag( cs, ctuIdx, compID, alfParam );
      }
    }
    
    void CABACWriter::codeAlfCtuEnableFlag( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, AlfSliceParam* alfParam)
    {
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      const bool alfComponentEnabled = (alfParam != NULL) ? alfParam->enabledFlag[compIdx] : cs.slice->getTileGroupAlfEnabledFlag((ComponentID)compIdx);
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      if( cs.sps->getALFEnabledFlag() && alfComponentEnabled )
    
      {
        const PreCalcValues& pcv = *cs.pcv;
        int                 frame_width_in_ctus = pcv.widthInCtus;
        int                 ry = ctuRsAddr / frame_width_in_ctus;
        int                 rx = ctuRsAddr - ry * frame_width_in_ctus;
        const Position      pos( rx * cs.pcv->maxCUWidth, ry * cs.pcv->maxCUHeight );
        const uint32_t          curSliceIdx = cs.slice->getIndependentSliceIdx();
    
    Karsten Suehring's avatar
    Karsten Suehring committed
        const uint32_t      curTileIdx = cs.picture->brickMap->getBrickIdxRsMap( pos );
    
        bool                leftAvail = cs.getCURestricted( pos.offset( -(int)pcv.maxCUWidth, 0 ), pos, curSliceIdx, curTileIdx, CH_L ) ? true : false;
        bool                aboveAvail = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUHeight ), pos, curSliceIdx, curTileIdx, CH_L ) ? true : false;
    
    
        int leftCTUAddr = leftAvail ? ctuRsAddr - 1 : -1;
        int aboveCTUAddr = aboveAvail ? ctuRsAddr - frame_width_in_ctus : -1;
    
    
    Karsten Suehring's avatar
    Karsten Suehring committed
        uint8_t* ctbAlfFlag = cs.slice->getPic()->getAlfCtuEnableFlag( compIdx );
        int ctx = 0;
        ctx += leftCTUAddr > -1 ? ( ctbAlfFlag[leftCTUAddr] ? 1 : 0 ) : 0;
        ctx += aboveCTUAddr > -1 ? ( ctbAlfFlag[aboveCTUAddr] ? 1 : 0 ) : 0;
        m_BinEncoder.encodeBin( ctbAlfFlag[ctuRsAddr], Ctx::ctbAlfFlag( compIdx * 3 + ctx ) );
    
    void CABACWriter::code_unary_fixed( unsigned symbol, unsigned ctxId, unsigned unary_max, unsigned fixed )
    {
      bool unary = (symbol <= unary_max);
      m_BinEncoder.encodeBin( unary, ctxId );
      if( unary )
      {
        unary_max_eqprob( symbol, unary_max );
      }
      else
      {
        m_BinEncoder.encodeBinsEP( symbol - unary_max - 1, fixed );
      }
    }
    
    void CABACWriter::mip_flag( const CodingUnit& cu )
    {
      if( !cu.Y().valid() )
      {
        return;
      }
      if( !cu.cs->sps->getUseMIP() )
      {
        return;
      }
      if( cu.lwidth() > MIP_MAX_WIDTH || cu.lheight() > MIP_MAX_HEIGHT )
      {
        return;
      }
      if( !mipModesAvailable( cu.Y() ) )
      {
        return;
      }
    
      unsigned ctxId = DeriveCtx::CtxMipFlag( cu );
      m_BinEncoder.encodeBin( cu.mipFlag, Ctx::MipFlag( ctxId ) );
      DTRACE( g_trace_ctx, D_SYNTAX, "mip_flag() pos=(%d,%d) mode=%d\n", cu.lumaPos().x, cu.lumaPos().y, cu.mipFlag ? 1 : 0 );
    }
    
    void CABACWriter::mip_pred_modes( const CodingUnit& cu )
    {
      if( !cu.Y().valid() )
      {
        return;
      }
      for( const auto &pu : CU::traversePUs( cu ) )
      {
        mip_pred_mode( pu );
      }
    }
    
    void CABACWriter::mip_pred_mode( const PredictionUnit& pu )
    {
      const int numModes = getNumModesMip( pu.Y() ); CHECKD( numModes > MAX_NUM_MIP_MODE, "Error: too many MIP modes" );
    
      // derive modeIdx from true MIP mode
      unsigned mpm[NUM_MPM_MIP];
      PU::getMipMPMs(pu, mpm);
    
      unsigned mipMode = pu.intraDir[CHANNEL_TYPE_LUMA];
      unsigned mpmIdx   = NUM_MPM_MIP;
      for( auto k = 0; k < NUM_MPM_MIP; k++ )
      {
        if( mipMode == mpm[k] )
        {
          mpmIdx = k;
          break;
        }
      }
    
      unsigned modeIdx;
      if (mpmIdx < NUM_MPM_MIP)
      {
        modeIdx = mpmIdx;
      }
      else
      {
        std::sort( mpm, mpm + NUM_MPM_MIP);
    
        modeIdx = mipMode;
        for( auto k = (NUM_MPM_MIP - 1); k >= 0; k-- )
        {
          if( modeIdx > mpm[k] )
          {
            modeIdx--;
          }
        }
        CHECK( modeIdx >= (1<<getNumEpBinsMip( pu.Y() )), "Incorrect mode" );
        modeIdx += NUM_MPM_MIP;
      }
    
      CHECK( modeIdx >= numModes, "modeIdx out of range" );
      int unaryMax = NUM_MPM_MIP - 1;
      int fixedLength = getNumEpBinsMip( pu.Y() );
      code_unary_fixed( modeIdx, Ctx::MipMode( 0 ), unaryMax, fixedLength );
    
      DTRACE( g_trace_ctx, D_SYNTAX, "mip_pred_mode() pos=(%d,%d) mode=%d\n", pu.lumaPos().x, pu.lumaPos().y, pu.intraDir[CHANNEL_TYPE_LUMA] );
    }
    
    Karsten Suehring's avatar
    Karsten Suehring committed
    void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr, bool alfEnableLuma)
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      if ( (!cs.sps->getALFEnabledFlag()) || (!alfEnableLuma))
    
      {
        return;
      }
    
      uint8_t* ctbAlfFlag = cs.slice->getPic()->getAlfCtuEnableFlag(COMPONENT_Y);
      if (!ctbAlfFlag[ctuRsAddr])
      {
        return;
      }
    
      short* alfCtbFilterIndex = cs.slice->getPic()->getAlfCtbFilterIndex();
      const unsigned filterSetIdx = alfCtbFilterIndex[ctuRsAddr];
      unsigned numAps = cs.slice->getTileGroupNumAps();
      unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
      if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
      {
        int useLatestFilt = (filterSetIdx == NUM_FIXED_FILTER_SETS) ? 1 : 0;
        m_BinEncoder.encodeBin(useLatestFilt, Ctx::AlfUseLatestFilt());
        if (!useLatestFilt)
        {
    
          if (numAps == 1)
          {
            CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set numavail < num_fixed");
            xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
          }
          else
          {
            int useTemporalFilt = (filterSetIdx > NUM_FIXED_FILTER_SETS) ? 1 : 0;
            m_BinEncoder.encodeBin(useTemporalFilt, Ctx::AlfUseTemporalFilt());
    
            if (useTemporalFilt)
            {
              CHECK((filterSetIdx - (NUM_FIXED_FILTER_SETS + 1)) >= (numAvailableFiltSets - (NUM_FIXED_FILTER_SETS + 1)), "temporal non-latest set");
    
    #if JVET_O0247_ALF_CTB_CODING_REDUNDANCY_REMOVAL
              if (numAps > 2)
              {
    #endif
                xWriteTruncBinCode(filterSetIdx - (NUM_FIXED_FILTER_SETS + 1), numAvailableFiltSets - (NUM_FIXED_FILTER_SETS + 1));
    #if JVET_O0247_ALF_CTB_CODING_REDUNDANCY_REMOVAL
              }
    #endif
    
            }
            else
            {
              CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set larger than temporal");
              xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
            }
          }
        }
      }
      else
      {
        CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set numavail < num_fixed");
        xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
      }
    }