source/Lib/TLibEncoder/TEncSlice.cpp
/**
 - multi-loop slice encoding for different slice QP
 .
 \param rpcPic    picture class
 */
multi-loop slice encoding for different slice QP
.
\param rpcPic    picture class
multi - loop slice encoding for different slice QP . \ param rpcPic picture class
Void TEncSlice::precompressSlice( TComPic*& rpcPic )
{
  if ( m_pcCfg->getDeltaQpRD() == 0 )
  {
    return;
  }
  if ( m_pcCfg->getUseRateCtrl() )
  {
    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
    assert(0);
  }
  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
  Double     dPicRdCostBest = MAX_DOUBLE;
  UInt       uiQpIdxBest = 0;
  Double dFrameLambda;
#if FULL_NBIT
  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
#else
  Int    SHIFT_QP = 12;
#endif
  if (m_pcCfg->getGOPSize() > 1)
  {
    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
  }
  else
  {
    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
  }
  m_pcRdCost      ->setFrameLambda(dFrameLambda);
  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
  {
    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
#if ADAPTIVE_QP_SELECTION
    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
#endif
    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
    Int iQP = m_piRdPicQp    [uiQpIdx];
    Double weight[2] = { 1.0, 1.0 };
    Int qpc;
    Int chromaQPOffset;
    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  
    m_pcRdCost->setCbDistortionWeight(weight[0]);
    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  
    m_pcRdCost->setCrDistortionWeight(weight[1]);
    const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
#if RDOQ_CHROMA_LAMBDA 
    Q
    m_pcTrQuant->setLambdas( lambdaArray );
#else
    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
#endif
    pcSlice->setLambdas( lambdaArray );
    compressSlice   ( rpcPic );
    Double dPicRdCost;
    UInt64 uiPicDist        = m_uiPicDist;
    UInt64 uiALFBits        = 0;
    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
    if ( dPicRdCost < dPicRdCostBest )
    {
      uiQpIdxBest    = uiQpIdx;
      dPicRdCostBest = dPicRdCost;
    }
  }
  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
#if ADAPTIVE_QP_SELECTION
  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
#endif
  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
  Int iQP = m_piRdPicQp    [uiQpIdxBest];
  Double weight[2] = { 1.0, 1.0 };
  Int qpc;
  Int chromaQPOffset;
  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
  weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  
  m_pcRdCost->setCbDistortionWeight(weight[0]);
  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
  weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  
  m_pcRdCost->setCrDistortionWeight(weight[1]);
  const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
#if RDOQ_CHROMA_LAMBDA 
  Q 
  m_pcTrQuant->setLambdas( lambdaArray );
#else
  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
#endif
  pcSlice->setLambdas( lambdaArray );
}
Void TEncSlice :: precompressSlice ( TComPic * & rpcPic ) { if ( m_pcCfg -> getDeltaQpRD ( ) == 0 ) { return ; } if ( m_pcCfg -> getUseRateCtrl ( ) ) { printf ( " \n " ) ; assert ( 0 ) ; } TComSlice * pcSlice = rpcPic -> getSlice ( getSliceIdx ( ) ) ; Double dPicRdCostBest = MAX_DOUBLE ; UInt uiQpIdxBest = 0 ; Double dFrameLambda ; #if FULL_NBIT Int SHIFT_QP = 12 + 6 * ( g_bitDepth - 8 ) ; #else Int SHIFT_QP = 12 ; #endif if ( m_pcCfg -> getGOPSize ( ) > 1 ) { dFrameLambda = 0.68 * pow ( 2 , ( m_piRdPicQp [ 0 ] - SHIFT_QP ) / 3.0 ) * ( pcSlice -> isInterB ( ) ? 2 : 1 ) ; } else { dFrameLambda = 0.68 * pow ( 2 , ( m_piRdPicQp [ 0 ] - SHIFT_QP ) / 3.0 ) ; } m_pcRdCost -> setFrameLambda ( dFrameLambda ) ; for ( UInt uiQpIdx = 0 ; uiQpIdx < 2 * m_pcCfg -> getDeltaQpRD ( ) + 1 ; uiQpIdx ++ ) { pcSlice -> setSliceQp ( m_piRdPicQp [ uiQpIdx ] ) ; #if ADAPTIVE_QP_SELECTION pcSlice -> setSliceQpBase ( m_piRdPicQp [ uiQpIdx ] ) ; #endif m_pcRdCost -> setLambda ( m_pdRdPicLambda [ uiQpIdx ] ) ; Int iQP = m_piRdPicQp [ uiQpIdx ] ; Double weight [ 2 ] = { 1.0 , 1.0 } ; Int qpc ; Int chromaQPOffset ; chromaQPOffset = pcSlice -> getPPS ( ) -> getChromaCbQpOffset ( ) + pcSlice -> getSliceQpDeltaCb ( ) ; qpc = Clip3 ( 0 , 57 , iQP + chromaQPOffset ) ; weight [ 0 ] = pow ( 2.0 , ( iQP - g_aucChromaScale [ qpc ] ) / 3.0 ) ; m_pcRdCost -> setCbDistortionWeight ( weight [ 0 ] ) ; chromaQPOffset = pcSlice -> getPPS ( ) -> getChromaCrQpOffset ( ) + pcSlice -> getSliceQpDeltaCr ( ) ; qpc = Clip3 ( 0 , 57 , iQP + chromaQPOffset ) ; weight [ 1 ] = pow ( 2.0 , ( iQP - g_aucChromaScale [ qpc ] ) / 3.0 ) ; m_pcRdCost -> setCrDistortionWeight ( weight [ 1 ] ) ; const Double lambdaArray [ 3 ] = { m_pdRdPicLambda [ uiQpIdx ] , ( m_pdRdPicLambda [ uiQpIdx ] / weight [ 0 ] ) , ( m_pdRdPicLambda [ uiQpIdx ] / weight [ 1 ] ) } ; #if RDOQ_CHROMA_LAMBDA m_pcTrQuant -> setLambdas ( lambdaArray ) ; #else m_pcTrQuant -> setLambda ( m_pdRdPicLambda [ uiQpIdx ] ) ; #endif pcSlice -> setLambdas ( lambdaArray ) ; compressSlice ( rpcPic ) ; Double dPicRdCost ; UInt64 uiPicDist = m_uiPicDist ; UInt64 uiALFBits = 0 ; m_pcGOPEncoder -> preLoopFilterPicAll ( rpcPic , uiPicDist , uiALFBits ) ; dPicRdCost = m_pcRdCost -> calcRdCost64 ( m_uiPicTotalBits + uiALFBits , uiPicDist , true , DF_SSE_FRAME ) ; if ( dPicRdCost < dPicRdCostBest ) { uiQpIdxBest = uiQpIdx ; dPicRdCostBest = dPicRdCost ; } } pcSlice -> setSliceQp ( m_piRdPicQp [ uiQpIdxBest ] ) ; #if ADAPTIVE_QP_SELECTION pcSlice -> setSliceQpBase ( m_piRdPicQp [ uiQpIdxBest ] ) ; #endif m_pcRdCost -> setLambda ( m_pdRdPicLambda [ uiQpIdxBest ] ) ; Int iQP = m_piRdPicQp [ uiQpIdxBest ] ; Double weight [ 2 ] = { 1.0 , 1.0 } ; Int qpc ; Int chromaQPOffset ; chromaQPOffset = pcSlice -> getPPS ( ) -> getChromaCbQpOffset ( ) + pcSlice -> getSliceQpDeltaCb ( ) ; qpc = Clip3 ( 0 , 57 , iQP + chromaQPOffset ) ; weight [ 0 ] = pow ( 2.0 , ( iQP - g_aucChromaScale [ qpc ] ) / 3.0 ) ; m_pcRdCost -> setCbDistortionWeight ( weight [ 0 ] ) ; chromaQPOffset = pcSlice -> getPPS ( ) -> getChromaCrQpOffset ( ) + pcSlice -> getSliceQpDeltaCr ( ) ; qpc = Clip3 ( 0 , 57 , iQP + chromaQPOffset ) ; weight [ 1 ] = pow ( 2.0 , ( iQP - g_aucChromaScale [ qpc ] ) / 3.0 ) ; m_pcRdCost -> setCrDistortionWeight ( weight [ 1 ] ) ; const Double lambdaArray [ 3 ] = { m_pdRdPicLambda [ uiQpIdxBest ] , ( m_pdRdPicLambda [ uiQpIdxBest ] / weight [ 0 ] ) , ( m_pdRdPicLambda [ uiQpIdxBest ] / weight [ 1 ] ) } ; #if RDOQ_CHROMA_LAMBDA m_pcTrQuant -> setLambdas ( lambdaArray ) ; #else m_pcTrQuant -> setLambda ( m_pdRdPicLambda [ uiQpIdxBest ] ) ; #endif pcSlice -> setLambdas ( lambdaArray ) ; }
multi-loop slice encoding for different slice QP
.
multi - loop slice encoding for different slice QP .
// if deltaQP RD is not used, simply return // set frame lambda // for each QP candidate // for RDO // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma. // takes into account of the chroma qp mapping and chroma qp Offset // takes into account of the chroma qp mapping and chroma qp Offset // for RDOQ // For SAO // try compress // compute RD cost and choose the best // set best values // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma. // takes into account of the chroma qp mapping and chroma qp Offset // takes into account of the chroma qp mapping and chroma qp Offset // for RDOQ  // For SAO