HEVC中的码率控制(RC)

来源:互联网 发布:linux ftp命令用法 编辑:程序博客网 时间:2024/06/10 02:16


题记:

HEVC 标准中所推荐的码率控制模型不像H.264中推荐 《二次率失真模型》, 而采用了 R-lambda 模型。


模型较简单,主要提案涉及三个


JCT-VC K0103

JCT-VC M0257

JCT-VC M0036 



在HM中对应的代码如下:



 

////////////////////////////////////////////////group level GROUP_LEVEL_RC#if RATE_CONTROL_LAMBDA_DOMAIN  if ( m_RCEnableRateControl )  {    m_cRateCtrl.initRCGOP( m_iNumPicRcvd );  }#endif////////////////////////////////////////////////////////////////////////////////////////////////slice level SLICE_LEVEL_RC#if RATE_CONTROL_LAMBDA_DOMAIN    Double lambda            = 0.0;    Int actualHeadBits       = 0;    Int actualTotalBits      = 0;    Int estimatedBits        = 0;    Int tmpBitsBeforeWriting = 0;    if ( m_pcCfg->getUseRateCtrl() )    {      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )      {        frameLevel = 0;      }      m_pcRateCtrl->initRCPic( frameLevel );      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();      Int sliceQP = m_pcCfg->getInitialQP();      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified      {        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );        Double dQPFactor     = 0.57*dLambda_scale;        Int    SHIFT_QP      = 12;        Int    bitdepth_luma_qp_scale = 0;        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );      }      else if ( frameLevel == 0 )   // intra case, but use the model      {#if RATE_CONTROL_INTRA        m_pcSliceEncoder->calCostSliceI(pcPic);  // calculate the whole frame hardmard cost#endif        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case        {          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();#if RATE_CONTROL_INTRA          bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );#else          bits = m_pcRateCtrl->getRCSeq()->getRefineBitsForIntra( bits );#endif          if ( bits < 200 )          {            bits = 200;          }          m_pcRateCtrl->getRCPic()->setTargetBits( bits );        }        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();#if RATE_CONTROL_INTRA        m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();  // to set LCU target bits        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());#else        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture );#endif        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );      }      else    // normal case      {        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();#if RATE_CONTROL_INTRA        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());#else        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture );#endif        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );      }      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP );      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );    }#endif////////////////////////////////////////////////////////////////////////////////////////////////LCU level CU_LEVEL_RC#if RATE_CONTROL_LAMBDA_DOMAIN      Double oldLambda = m_pcRdCost->getLambda();      if ( m_pcCfg->getUseRateCtrl() )      {        Int estQP        = pcSlice->getSliceQp();        Double estLambda = -1.0;        Double bpp       = -1.0;#if M0036_RC_IMPROVEMENT        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )#else        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )#endif        {          estQP = pcSlice->getSliceQp();        }        else        {#if RATE_CONTROL_INTRA          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)          {            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);          }          else          {            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );          }#else          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );#endif          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );          m_pcRdCost->setLambda(estLambda);           //set lambda in RD-cost function#if M0036_RC_IMPROVEMENT#if RDOQ_CHROMA_LAMBDA          // set lambda for RDOQ          Double weight=m_pcRdCost->getChromaWeight();          m_pcTrQuant->setLambda( estLambda, estLambda / weight );#else          m_pcTrQuant->setLambda( estLambda );       //set lambda in TransQuant function#endif#endif        }        m_pcRateCtrl->setRCQP( estQP );#if ADAPTIVE_QP_SELECTION  //mhwang        pcCU->getSlice()->setSliceQpBase( estQP );#endif      }#endif////////////////////////////////////////////////