Changeset 1313 in 3DVCSoftware for trunk/source/Lib/TLibEncoder/TEncSlice.cpp


Ignore:
Timestamp:
13 Aug 2015, 17:38:13 (9 years ago)
Author:
tech
Message:

Merged 14.1-update-dev1@1312.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/Lib/TLibEncoder/TEncSlice.cpp

    r1196 r1313  
    22 * License, included below. This software may be subject to other third party
    33 * and contributor rights, including patent rights, and no such rights are
    4  * granted under this license. 
     4 * granted under this license.
    55 *
    6 * Copyright (c) 2010-2015, ITU/ISO/IEC
     6 * Copyright (c) 2010-2015, ITU/ISO/IEC
    77 * All rights reserved.
    88 *
     
    4646// Constructor / destructor / create / destroy
    4747// ====================================================================================================================
    48 
    4948TEncSlice::TEncSlice()
     49 : m_encCABACTableIdx(I_SLICE)
    5050{
    5151  m_apcPicYuvPred = NULL;
    5252  m_apcPicYuvResi = NULL;
    53  
     53
    5454  m_pdRdPicLambda = NULL;
    5555  m_pdRdPicQp     = NULL;
    5656  m_piRdPicQp     = NULL;
    57   m_pcBufferSbacCoders    = NULL;
    58   m_pcBufferBinCoderCABACs  = NULL;
    59   m_pcBufferLowLatSbacCoders    = NULL;
    60   m_pcBufferLowLatBinCoderCABACs  = NULL;
    6157}
    6258
    6359TEncSlice::~TEncSlice()
    6460{
    65   for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
    66   {
    67     delete (*i);
    68   }
    69 }
    70 
    71 Void TEncSlice::initCtxMem(  UInt i )               
    72 {   
    73   for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
    74   {
    75     delete (*j);
    76   }
    77   CTXMem.clear();
    78   CTXMem.resize(i);
    79 }
    80 
    81 Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
     61}
     62
     63Void TEncSlice::create( Int iWidth, Int iHeight, ChromaFormat chromaFormat, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
    8264{
    8365  // create prediction picture
     
    8567  {
    8668    m_apcPicYuvPred  = new TComPicYuv;
    87     m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
    88   }
    89  
     69    m_apcPicYuvPred->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth, true );
     70  }
     71
    9072  // create residual picture
    9173  if( m_apcPicYuvResi == NULL )
    9274  {
    9375    m_apcPicYuvResi  = new TComPicYuv;
    94     m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
     76    m_apcPicYuvResi->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth, true );
    9577  }
    9678}
     
    10587    m_apcPicYuvPred  = NULL;
    10688  }
    107  
     89
    10890  // destroy residual picture
    10991  if ( m_apcPicYuvResi )
     
    11395    m_apcPicYuvResi  = NULL;
    11496  }
    115  
     97
    11698  // free lambda and QP arrays
    117   if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
    118   if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
    119   if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
    120 
    121   if ( m_pcBufferSbacCoders )
    122   {
    123     delete[] m_pcBufferSbacCoders;
    124   }
    125   if ( m_pcBufferBinCoderCABACs )
    126   {
    127     delete[] m_pcBufferBinCoderCABACs;
    128   }
    129   if ( m_pcBufferLowLatSbacCoders )
    130     delete[] m_pcBufferLowLatSbacCoders;
    131   if ( m_pcBufferLowLatBinCoderCABACs )
    132     delete[] m_pcBufferLowLatBinCoderCABACs;
     99  if ( m_pdRdPicLambda )
     100  {
     101    xFree( m_pdRdPicLambda );
     102    m_pdRdPicLambda = NULL;
     103  }
     104  if ( m_pdRdPicQp )
     105  {
     106    xFree( m_pdRdPicQp );
     107    m_pdRdPicQp = NULL;
     108  }
     109  if ( m_piRdPicQp )
     110  {
     111    xFree( m_piRdPicQp );
     112    m_piRdPicQp = NULL;
     113  }
    133114}
    134115
     
    137118  m_pcCfg             = pcEncTop;
    138119  m_pcListPic         = pcEncTop->getListPic();
    139  
     120
    140121  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
    141122  m_pcCuEncoder       = pcEncTop->getCuEncoder();
    142123  m_pcPredSearch      = pcEncTop->getPredSearch();
    143  
     124
    144125  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
    145   m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
    146126  m_pcSbacCoder       = pcEncTop->getSbacCoder();
    147127  m_pcBinCABAC        = pcEncTop->getBinCABAC();
    148128  m_pcTrQuant         = pcEncTop->getTrQuant();
    149  
    150   m_pcBitCounter      = pcEncTop->getBitCounter();
     129
    151130  m_pcRdCost          = pcEncTop->getRdCost();
    152131  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
    153132  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
    154  
     133
    155134  // create lambda and QP arrays
    156135  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
     
    169148  m_pcRateCtrl        = pcEncTop->getRateCtrl();
    170149#endif
    171 }
     150
     151}
     152
     153
     154
     155Void
     156TEncSlice::setUpLambda(TComSlice* slice, const Double dLambda, Int iQP)
     157{
     158  // store lambda
     159  m_pcRdCost ->setLambda( dLambda, slice->getSPS()->getBitDepths() );
     160
     161  // for RDO
     162  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
     163  Double dLambdas[MAX_NUM_COMPONENT] = { dLambda };
     164  for(UInt compIdx=1; compIdx<MAX_NUM_COMPONENT; compIdx++)
     165  {
     166    const ComponentID compID=ComponentID(compIdx);
     167    Int chromaQPOffset = slice->getPPS()->getQpOffset(compID) + slice->getSliceChromaQpDelta(compID);
     168    Int qpc=(iQP + chromaQPOffset < 0) ? iQP : getScaledChromaQP(iQP + chromaQPOffset, m_pcCfg->getChromaFormatIdc());
     169    Double tmpWeight = pow( 2.0, (iQP-qpc)/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
     170    m_pcRdCost->setDistortionWeight(compID, tmpWeight);
     171    dLambdas[compIdx]=dLambda/tmpWeight;
     172  }
     173
     174#if RDOQ_CHROMA_LAMBDA
     175// for RDOQ
     176  m_pcTrQuant->setLambdas( dLambdas );
     177#else
     178  m_pcTrQuant->setLambda( dLambda );
     179#endif
     180
     181// For SAO
     182  slice   ->setLambdas( dLambdas );
     183}
     184
     185
    172186
    173187/**
     
    181195 \param pocCurr       current POC
    182196 \param iNumPicRcvd   number of received pictures
    183  \param iTimeOffset   POC offset for hierarchical structure
    184  \param iDepth        temporal layer depth
     197 \param iGOPid        POC offset for hierarchical structure
    185198 \param rpcSlice      slice header class
    186  \param pSPS          SPS associated with the slice
    187  \param pPPS          PPS associated with the slice
     199 \param isField       true for field coding
    188200 */
    189 #if H_MV
    190 Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, TComSPS* pSPS, TComPPS *pPPS, Int layerId, bool isField )
    191 #else
    192 Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, bool isField )
     201
     202#if NH_MV
     203Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, Int layerId, bool isField )
     204#else
     205Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iGOPid, TComSlice*& rpcSlice, Bool isField )
    193206#endif
    194207{
    195208  Double dQP;
    196209  Double dLambda;
    197  
     210
    198211  rpcSlice = pcPic->getSlice(0);
    199212
    200 #if H_MV
     213#if NH_MV
    201214  rpcSlice->setVPS( pVPS );
    202215
     
    204217  rpcSlice->setViewId      ( pVPS->getViewId      ( layerId ) );   
    205218  rpcSlice->setViewIndex   ( pVPS->getViewIndex   ( layerId ) );
    206 #if H_3D
     219#if NH_3D
    207220  rpcSlice->setIsDepth     ( pVPS->getDepthId     ( layerId ) != 0 );   
    208221#endif
    209222#endif
    210   rpcSlice->setSPS( pSPS );
    211   rpcSlice->setPPS( pPPS );
    212223  rpcSlice->setSliceBits(0);
    213224  rpcSlice->setPic( pcPic );
     
    215226  rpcSlice->setPicOutputFlag( true );
    216227  rpcSlice->setPOC( pocCurr );
    217 #if H_3D_IC
     228#if NH_3D_IC
    218229  rpcSlice->setApplyIC( false );
    219230#endif
     
    221232  Int depth;
    222233  {
    223 #if FIX_FIELD_DEPTH   
     234
    224235    Int poc = rpcSlice->getPOC();
    225236    if(isField)
    226237    {
    227       poc = (poc/2)%(m_pcCfg->getGOPSize()/2);
     238      poc = (poc/2) % (m_pcCfg->getGOPSize()/2);
    228239    }
    229240    else
    230241    {
    231       poc = poc%m_pcCfg->getGOPSize();   
    232     }
    233 #else
    234     Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
    235 #endif
     242      poc = poc % m_pcCfg->getGOPSize();   
     243    }
    236244    if ( poc == 0 )
    237245    {
     
    256264      }
    257265    }
    258 #if FIX_FIELD_DEPTH 
    259 #if HARMONIZE_GOP_FIRST_FIELD_COUPLE
    260     if(poc != 0)
    261     {
    262 #endif
    263     if(isField && rpcSlice->getPOC()%2 == 1)
    264     {
    265       depth ++;
    266     }
    267 #if HARMONIZE_GOP_FIRST_FIELD_COUPLE
    268   }
    269 #endif
    270 #endif
    271   }
    272  
     266
     267    if(m_pcCfg->getHarmonizeGopFirstFieldCoupleEnabled() && poc != 0)
     268    {
     269      if (isField && ((rpcSlice->getPOC() % 2) == 1))
     270      {
     271        depth ++;
     272      }
     273    }
     274  }
     275
    273276  // slice type
    274 #if H_MV
     277#if NH_MV
    275278  SliceType eSliceTypeBaseView;
    276279  if( pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 )
     
    289292#else
    290293  SliceType eSliceType;
    291  
     294
    292295  eSliceType=B_SLICE;
    293 #if EFFICIENT_FIELD_IRAP
    294   if(!(isField && pocLast == 1))
    295   {
    296 #endif // EFFICIENT_FIELD_IRAP
    297 #if ALLOW_RECOVERY_POINT_AS_RAP
    298   if(m_pcCfg->getDecodingRefreshType() == 3)
    299   {
    300     eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0             || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
    301   }
    302   else
    303   {
    304     eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
    305   }
    306 #else
    307   eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
    308 #endif
    309 #if EFFICIENT_FIELD_IRAP
    310   }
    311 #endif
    312 #endif
    313  
     296  if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled())
     297  {
     298    if(m_pcCfg->getDecodingRefreshType() == 3)
     299    {
     300      eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0             || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
     301    }
     302    else
     303    {
     304      eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
     305    }
     306  }
     307#endif
    314308  rpcSlice->setSliceType    ( eSliceType );
    315309
     
    317311  // Non-referenced frame marking
    318312  // ------------------------------------------------------------------------------------------------------------------
    319  
     313
    320314  if(pocLast == 0)
    321315  {
     
    324318  else
    325319  {
    326 #if 0 // Check this! H_MV
     320#if 0 // Check this! NH_MV
    327321    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_refPic);
    328322#else
     
    331325  }
    332326  rpcSlice->setReferenced(true);
    333  
     327
    334328  // ------------------------------------------------------------------------------------------------------------------
    335329  // QP setting
    336330  // ------------------------------------------------------------------------------------------------------------------
    337  
     331
    338332  dQP = m_pcCfg->getQP();
    339333  if(eSliceType!=I_SLICE)
    340334  {
    341     if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
    342     {
    343 #if H_MV
     335    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA) ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
     336    {
     337#if NH_MV
    344338      dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
    345339#else
     
    348342    }
    349343  }
    350  
     344
    351345  // modify QP
    352346  Int* pdQPs = m_pcCfg->getdQPs();
     
    355349    dQP += pdQPs[ rpcSlice->getPOC() ];
    356350  }
     351
     352  if (m_pcCfg->getCostMode()==COST_LOSSLESS_CODING)
     353  {
     354    dQP=LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP;
     355    m_pcCfg->setDeltaQpRD(0);
     356  }
     357
    357358  // ------------------------------------------------------------------------------------------------------------------
    358359  // Lambda computation
    359360  // ------------------------------------------------------------------------------------------------------------------
    360  
     361
    361362  Int iQP;
    362363  Double dOrigQP = dQP;
     
    367368    // compute QP value
    368369    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
    369    
     370
    370371    // compute lambda value
    371372    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
    372373    Int    SHIFT_QP = 12;
     374
    373375    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
     376
    374377#if FULL_NBIT
    375     Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
     378    Int    bitdepth_luma_qp_scale = 6 * (rpcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
    376379#else
    377380    Int    bitdepth_luma_qp_scale = 0;
     
    382385#endif
    383386    // Case #1: I or P-slices (key-frame)
    384 #if H_MV
     387#if NH_MV
    385388    Double dQPFactor;
    386389    if( eSliceType != I_SLICE )
     
    406409#endif
    407410    }
    408    
     411
    409412    // if hadamard is used in ME process
    410413    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
     
    412415      dLambda *= 0.95;
    413416    }
    414    
    415     iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
     417
     418    iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
    416419
    417420    m_pdRdPicLambda[iDQpIdx] = dLambda;
     
    419422    m_piRdPicQp    [iDQpIdx] = iQP;
    420423  }
    421  
     424
    422425  // obtain dQP = 0 case
    423426  dLambda = m_pdRdPicLambda[0];
    424427  dQP     = m_pdRdPicQp    [0];
    425428  iQP     = m_piRdPicQp    [0];
    426  
     429
    427430  if( rpcSlice->getSliceType( ) != I_SLICE )
    428431  {
    429 #if H_MV
     432#if NH_MV
    430433    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_temporalId );
    431434#else
     
    434437  }
    435438
    436   // store lambda
    437   m_pcRdCost ->setLambda( dLambda );
    438 
    439 #if H_3D_VSO
     439  setUpLambda(rpcSlice, dLambda, iQP);
     440
     441#if NH_3D_VSO
    440442  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->getIsDepth() );
    441443  m_pcRdCost->setLambdaVSO          ( dLambda * m_pcCfg->getLambdaScaleVSO() );
     
    456458#endif
    457459
    458 // for RDO
    459   // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
    460   Double weight[2] = { 1.0, 1.0 };
    461   Int qpc;
    462   Int chromaQPOffset;
    463 
    464   chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
    465   qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    466   weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    467   m_pcRdCost->setCbDistortionWeight(weight[0]);
    468 
    469   chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
    470   qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    471   weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    472   m_pcRdCost->setCrDistortionWeight(weight[1]);
    473 
    474   const Double lambdaArray[3] = {dLambda, (dLambda / weight[0]), (dLambda / weight[1])};
    475 
    476 #if RDOQ_CHROMA_LAMBDA
    477 // for RDOQ
    478   m_pcTrQuant->setLambdas( lambdaArray );
    479 #else
    480   m_pcTrQuant->setLambda( dLambda );
    481 #endif
    482 
    483 // For SAO
    484   rpcSlice->setLambdas( lambdaArray );
    485  
    486 #if HB_LAMBDA_FOR_LDC
     460  if (m_pcCfg->getFastMEForGenBLowDelayEnabled())
     461  {
    487462  // restore original slice type
    488 #if H_MV
     463#if NH_MV
    489464  eSliceType = eSliceTypeBaseView;
    490465  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
     
    493468  }
    494469#else
    495 #if EFFICIENT_FIELD_IRAP
    496   if(!(isField && pocLast == 1))
    497   {
    498 #endif // EFFICIENT_FIELD_IRAP
    499 #if ALLOW_RECOVERY_POINT_AS_RAP
    500   if(m_pcCfg->getDecodingRefreshType() == 3)
    501   {
    502     eSliceType = (pocLast == 0 || (pocCurr)           % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
    503 
    504   }
    505   else
    506   {
    507   eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
    508   }
    509 #else
    510   eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
    511 #endif
    512 #if EFFICIENT_FIELD_IRAP
    513   }
    514 #endif // EFFICIENT_FIELD_IRAP
     470    if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled())
     471  {
     472    if(m_pcCfg->getDecodingRefreshType() == 3)
     473    {
     474      eSliceType = (pocLast == 0 || (pocCurr)                     % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
     475    }
     476    else
     477    {
     478      eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
     479
     480    }
     481  }
    515482#endif
    516483
    517484  rpcSlice->setSliceType        ( eSliceType );
    518 #endif
    519  
     485}
     486
    520487  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
    521488  {
    522489    dQP = xGetQPValueAccordingToLambda( dLambda );
    523     iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
    524   }
    525 
    526   rpcSlice->setSliceQp          ( iQP );
     490    iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
     491  }
     492
     493  rpcSlice->setSliceQp           ( iQP );
    527494#if ADAPTIVE_QP_SELECTION
    528   rpcSlice->setSliceQpBase      ( iQP );
    529 #endif
    530   rpcSlice->setSliceQpDelta     ( 0 );
    531   rpcSlice->setSliceQpDeltaCb   ( 0 );
    532   rpcSlice->setSliceQpDeltaCr   ( 0 );
    533 #if H_MV
     495  rpcSlice->setSliceQpBase       ( iQP );
     496#endif
     497  rpcSlice->setSliceQpDelta      ( 0 );
     498  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
     499  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
     500  rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() );
     501#if NH_MV
    534502  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
    535503  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
     
    545513    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
    546514    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
    547   } else
    548   if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
    549   {
    550     rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
    551     rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
    552     rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
    553     rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
     515  }
     516  else if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
     517  {
     518    rpcSlice->setDeblockingFilterOverrideFlag( rpcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() );
     519    rpcSlice->setDeblockingFilterDisable( rpcSlice->getPPS()->getPicDisableDeblockingFilterFlag() );
    554520    if ( !rpcSlice->getDeblockingFilterDisable())
    555521    {
    556       if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
    557       {
    558 #if H_MV
    559         rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
    560         rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
     522      if ( rpcSlice->getDeblockingFilterOverrideFlag() && eSliceType!=I_SLICE)
     523      {
     524#if NH_MV
    561525        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
    562526        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
    563527#else
    564         rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
    565         rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
    566528        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
    567529        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
     
    570532      else
    571533      {
    572       rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
    573       rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
    574       rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
    575       rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
     534        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
     535        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
    576536      }
    577537    }
     
    586546
    587547  rpcSlice->setDepth            ( depth );
    588  
    589 #if H_MV
     548
     549#if NH_MV
    590550  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
    591551#else
     
    600560  assert( m_apcPicYuvPred );
    601561  assert( m_apcPicYuvResi );
    602  
     562
    603563  pcPic->setPicYuvPred( m_apcPicYuvPred );
    604564  pcPic->setPicYuvResi( m_apcPicYuvResi );
     
    607567  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
    608568  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
    609 #if !H_3D
     569#if NH_3D_IV_MERGE
     570#else
    610571  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
    611572#endif
    612   xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
    613573}
    614574
     
    622582  slice->setSliceQpBase ( sliceQP );
    623583#endif
    624   m_pcRdCost ->setLambda( lambda );
    625   // for RDO
    626   // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
    627   Double weight[2] = { 1.0, 1.0 };
    628   Int qpc;
    629   Int chromaQPOffset;
    630 
    631   chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
    632   qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
    633   weight[0] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    634   m_pcRdCost->setCbDistortionWeight(weight[0]);
    635 
    636   chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
    637   qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
    638   weight[1] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    639   m_pcRdCost->setCrDistortionWeight(weight[1]);
    640 
    641   const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])};
    642 
    643 #if RDOQ_CHROMA_LAMBDA
    644   // for RDOQ
    645   m_pcTrQuant->setLambdas( lambdaArray );
    646 #else
    647   m_pcTrQuant->setLambda( lambda );
    648 #endif
    649 
    650   // For SAO
    651   slice->setLambdas( lambdaArray );
    652 }
     584  setUpLambda(slice, lambda, sliceQP);
     585}
     586
    653587// ====================================================================================================================
    654588// Public member functions
     
    663597  Int iMaxSR = m_pcCfg->getSearchRange();
    664598  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
    665  
     599
    666600  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
    667601  {
     
    678612
    679613/**
    680  - multi-loop slice encoding for different slice QP
    681  .
    682  \param rpcPic    picture class
     614 Multi-loop slice encoding for different slice QP
     615
     616 \param pcPic    picture class
    683617 */
    684 Void TEncSlice::precompressSlice( TComPic*& rpcPic )
     618Void TEncSlice::precompressSlice( TComPic* pcPic )
    685619{
    686620  // if deltaQP RD is not used, simply return
     
    694628    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
    695629    assert(0);
    696   }
    697  
    698   TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
     630    return;
     631  }
     632
     633  TComSlice* pcSlice        = pcPic->getSlice(getSliceIdx());
     634
     635  if (pcSlice->getDependentSliceSegmentFlag())
     636  {
     637    // if this is a dependent slice segment, then it was optimised
     638    // when analysing the entire slice.
     639    return;
     640  }
     641
     642  if (pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES)
     643  {
     644    // TODO: investigate use of average cost per CTU so that this Slice Mode can be used.
     645    printf( "\nUnable to optimise Slice-level QP if Slice Mode is set to FIXED_NUMBER_OF_BYTES\n" );
     646    assert(0);
     647    return;
     648  }
     649
     650
    699651  Double     dPicRdCostBest = MAX_DOUBLE;
    700652  UInt       uiQpIdxBest = 0;
    701  
     653
    702654  Double dFrameLambda;
    703655#if FULL_NBIT
    704   Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
     656  Int    SHIFT_QP = 12 + 6 * (pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
    705657#else
    706658  Int    SHIFT_QP = 12;
    707659#endif
    708  
     660
    709661  // set frame lambda
    710662  if (m_pcCfg->getGOPSize() > 1)
     
    717669  }
    718670  m_pcRdCost      ->setFrameLambda(dFrameLambda);
    719  
     671
    720672  // for each QP candidate
    721673  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
     
    725677    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
    726678#endif
    727     m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
    728     // for RDO
    729     // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
    730     Int iQP = m_piRdPicQp    [uiQpIdx];
    731     Double weight[2] = { 1.0, 1.0 };
    732     Int qpc;
    733     Int chromaQPOffset;
    734 
    735     chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
    736     qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    737     weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    738     m_pcRdCost->setCbDistortionWeight(weight[0]);
    739 
    740     chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
    741     qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    742     weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    743     m_pcRdCost->setCrDistortionWeight(weight[1]);
    744 
    745     const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
    746 #if RDOQ_CHROMA_LAMBDA
    747     // for RDOQ
    748     m_pcTrQuant->setLambdas( lambdaArray );
    749 #else
    750     m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
    751 #endif
    752     // For SAO
    753     pcSlice->setLambdas( lambdaArray );
    754    
     679    setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdx], m_piRdPicQp    [uiQpIdx]);
     680
    755681    // try compress
    756     compressSlice   ( rpcPic );
    757    
    758     Double dPicRdCost;
    759 #if H_3D_VSO
     682    compressSlice   ( pcPic, true, m_pcCfg->getFastDeltaQp());
     683
     684#if NH_3D_VSO
    760685    Dist64 uiPicDist        = m_uiPicDist;
    761686#else
    762     UInt64 uiPicDist        = m_uiPicDist;
    763 #endif
    764     UInt64 uiALFBits        = 0;
    765    
    766     m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
    767    
     687    UInt64 uiPicDist        = m_uiPicDist; // Distortion, as calculated by compressSlice.
     688    // NOTE: This distortion is the chroma-weighted SSE distortion for the slice.
     689    //       Previously a standard SSE distortion was calculated (for the entire frame).
     690    //       Which is correct?
     691
     692    // TODO: Update loop filter, SAO and distortion calculation to work on one slice only.
     693    // m_pcGOPEncoder->preLoopFilterPicAll( pcPic, uiPicDist );
     694
     695#endif
     696
    768697    // compute RD cost and choose the best
    769     dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
     698    Double dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits, uiPicDist, true, DF_SSE_FRAME); // NOTE: Is the 'true' parameter really necessary?
    770699#if H_3D
    771700    // Above calculation need to be fixed for VSO, including frameLambda value.
    772701#endif
    773    
     702
    774703    if ( dPicRdCost < dPicRdCostBest )
    775704    {
     
    778707    }
    779708  }
    780  
     709
    781710  // set best values
    782711  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
     
    784713  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
    785714#endif
    786   m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
    787   // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
    788   Int iQP = m_piRdPicQp    [uiQpIdxBest];
    789   Double weight[2] = { 1.0, 1.0 };
    790   Int qpc;
    791   Int chromaQPOffset;
    792 
    793   chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
    794   qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    795   weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    796   m_pcRdCost->setCbDistortionWeight(weight[0]);
    797 
    798   chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
    799   qpc = Clip3( 0, 57, iQP + chromaQPOffset);
    800   weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
    801   m_pcRdCost->setCrDistortionWeight(weight[1]);
    802 
    803   const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
    804 #if RDOQ_CHROMA_LAMBDA
    805   // for RDOQ
    806   m_pcTrQuant->setLambdas( lambdaArray );
    807 #else
    808   m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
    809 #endif
    810   // For SAO
    811   pcSlice->setLambdas( lambdaArray );
    812 }
    813 
    814 /** \param rpcPic   picture class
     715  setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdxBest], m_piRdPicQp    [uiQpIdxBest]);
     716}
     717
     718Void TEncSlice::calCostSliceI(TComPic* pcPic) // TODO: this only analyses the first slice segment. What about the others?
     719{
     720  Double            iSumHadSlice      = 0;
     721  TComSlice * const pcSlice           = pcPic->getSlice(getSliceIdx());
     722  const TComSPS    &sps               = *(pcSlice->getSPS());
     723  const Int         shift             = sps.getBitDepth(CHANNEL_TYPE_LUMA)-8;
     724  const Int         offset            = (shift>0)?(1<<(shift-1)):0;
     725
     726  pcSlice->setSliceSegmentBits(0);
     727
     728  UInt startCtuTsAddr, boundingCtuTsAddr;
     729  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
     730
     731  for( UInt ctuTsAddr = startCtuTsAddr, ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
     732       ctuTsAddr < boundingCtuTsAddr;
     733       ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(++ctuTsAddr) )
     734  {
     735    // initialize CU encoder
     736    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
     737    pCtu->initCtu( pcPic, ctuRsAddr );
     738
     739    Int height  = min( sps.getMaxCUHeight(),sps.getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * sps.getMaxCUHeight() );
     740    Int width   = min( sps.getMaxCUWidth(), sps.getPicWidthInLumaSamples()  - ctuRsAddr % pcPic->getFrameWidthInCtus() * sps.getMaxCUWidth() );
     741
     742    Int iSumHad = m_pcCuEncoder->updateCtuDataISlice(pCtu, width, height);
     743
     744    (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift;
     745    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra;
     746
     747  }
     748  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
     749}
     750
     751/** \param pcPic   picture class
    815752 */
    816 Void TEncSlice::calCostSliceI(TComPic*& rpcPic)
    817 {
    818   UInt    uiCUAddr;
    819   UInt    uiStartCUAddr;
    820   UInt    uiBoundingCUAddr;
    821   Int     iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;;
    822   Double  iSumHadSlice = 0;
    823 
    824   rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
    825   TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
    826   xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
    827 
    828   UInt uiEncCUOrder;
    829   uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
    830   for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
    831        uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
    832        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
    833   {
    834     // initialize CU encoder
    835     TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
    836     pcCU->initCU( rpcPic, uiCUAddr );
    837 
    838     Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
    839     Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
    840 
    841     iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height);
    842 
    843     (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift;
    844     iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra;
    845 
    846   }
    847   m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
    848 }
    849 
    850 Void TEncSlice::compressSlice( TComPic*& rpcPic )
    851 {
    852   UInt  uiCUAddr;
    853   UInt   uiStartCUAddr;
    854   UInt   uiBoundingCUAddr;
    855   rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
    856   TEncBinCABAC* pppcRDSbacCoder = NULL;
    857   TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
    858   xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
     753Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bCompressEntireSlice, const Bool bFastDeltaQP )
     754{
     755  // if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed,
     756  //   effectively disabling the slice-segment-mode.
     757
     758  UInt   startCtuTsAddr;
     759  UInt   boundingCtuTsAddr;
     760  TComSlice* const pcSlice            = pcPic->getSlice(getSliceIdx());
     761  pcSlice->setSliceSegmentBits(0);
     762  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
     763  if (bCompressEntireSlice)
     764  {
     765    boundingCtuTsAddr = pcSlice->getSliceCurEndCtuTsAddr();
     766    pcSlice->setSliceSegmentCurEndCtuTsAddr(boundingCtuTsAddr);
     767  }
     768
     769  // initialize cost values - these are used by precompressSlice (they should be parameters).
     770  m_uiPicTotalBits  = 0;
     771  m_dPicRdCost      = 0; // NOTE: This is a write-only variable!
     772  m_uiPicDist       = 0;
     773
     774  m_pcEntropyCoder->setEntropyCoder   ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
     775  m_pcEntropyCoder->resetEntropy      ( pcSlice );
     776
     777  TEncBinCABAC* pRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
     778  pRDSbacCoder->setBinCountingEnableFlag( false );
     779  pRDSbacCoder->setBinsCoded( 0 );
     780
     781  TComBitCounter  tempBitCounter;
     782  const UInt      frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus();
    859783 
    860   // initialize cost values
    861   m_uiPicTotalBits  = 0;
    862   m_dPicRdCost      = 0;
    863   m_uiPicDist       = 0;
    864  
    865   // set entropy coder
    866     m_pcSbacCoder->init( m_pcBinCABAC );
    867     m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
    868     m_pcEntropyCoder->resetEntropy      ();
    869     m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
    870     pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
    871     pppcRDSbacCoder->setBinCountingEnableFlag( false );
    872     pppcRDSbacCoder->setBinsCoded( 0 );
    873  
     784  m_pcCuEncoder->setFastDeltaQp(bFastDeltaQP);
     785
    874786  //------------------------------------------------------------------------------
    875787  //  Weighted Prediction parameters estimation.
     
    881793  }
    882794
    883   Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
     795  const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
    884796
    885797  if ( bWp_explicit )
     
    888800    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
    889801    //------------------------------------------------------------------------------
    890     if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
     802    if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES )
    891803    {
    892804      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
     
    894806
    895807    xEstimateWPParamSlice( pcSlice );
    896     pcSlice->initWpScaling();
     808    pcSlice->initWpScaling(pcSlice->getSPS());
    897809
    898810    // check WP on/off
     
    901813
    902814#if ADAPTIVE_QP_SELECTION
    903   if( m_pcCfg->getUseAdaptQpSelect() )
    904   {
    905     m_pcTrQuant->clearSliceARLCnt();
     815  if( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag()))
     816  {
     817    // TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag())
     818    m_pcTrQuant->clearSliceARLCnt(); // TODO: this looks wrong for multiple slices - the results of all but the last slice will be cleared before they are used (all slices compressed, and then all slices encoded)
    906819    if(pcSlice->getSliceType()!=I_SLICE)
    907820    {
     
    911824  }
    912825#endif
    913   TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
    914   TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
    915   TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
    916   Int  iNumSubstreams = 1;
    917   UInt uiTilesAcross  = 0;
    918 #if H_3D_IC
    919   if ( pcEncTop->getViewIndex() && pcEncTop->getUseIC() &&
     826
     827#if NH_3D_IC
     828  if ( m_pcCfg->getViewIndex() && m_pcCfg->getUseIC() &&
    920829       !( ( pcSlice->getSliceType() == P_SLICE && pcSlice->getPPS()->getUseWP() ) || ( pcSlice->getSliceType() == B_SLICE && pcSlice->getPPS()->getWPBiPred() ) )
    921830     )
    922831  {
    923     pcSlice ->xSetApplyIC(pcEncTop->getUseICLowLatencyEnc());
     832    pcSlice ->xSetApplyIC(m_pcCfg->getUseICLowLatencyEnc());
    924833    if ( pcSlice->getApplyIC() )
    925834    {
     
    928837  }
    929838#endif
    930     iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
    931     uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
    932     delete[] m_pcBufferSbacCoders;
    933     delete[] m_pcBufferBinCoderCABACs;
    934     m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
    935     m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
    936     for (Int ui = 0; ui < uiTilesAcross; ui++)
    937     {
    938       m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
    939     }
    940     for (UInt ui = 0; ui < uiTilesAcross; ui++)
    941     {
    942       m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
    943     }
    944 
    945     for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
    946     {
    947       ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
    948     }
    949     delete[] m_pcBufferLowLatSbacCoders;
    950     delete[] m_pcBufferLowLatBinCoderCABACs;
    951     m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
    952     m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
    953     for (Int ui = 0; ui < uiTilesAcross; ui++)
    954     {
    955       m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
    956     }
    957     for (UInt ui = 0; ui < uiTilesAcross; ui++)
    958       m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
    959 
    960   UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
    961   //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
    962   UInt uiCol=0, uiLin=0, uiSubStrm=0;
    963   UInt uiTileCol      = 0;
    964   UInt uiTileStartLCU = 0;
    965   UInt uiTileLCUX     = 0;
    966   Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
    967   uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
    968   uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
    969   if( depSliceSegmentsEnabled )
    970   {
    971     if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
    972     {
    973       if( m_pcCfg->getWaveFrontsynchro() )
    974       {
    975         uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
    976         m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
    977         Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
    978         uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
    979         uiLin     = uiCUAddr / uiWidthInLCUs;
    980         uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
    981           + uiLin%iNumSubstreamsPerTile;
    982         if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
    983         {
    984           uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
    985           uiCol     = uiCUAddr % uiWidthInLCUs;
    986           if(uiCol==uiTileStartLCU)
    987           {
    988             CTXMem[0]->loadContexts(m_pcSbacCoder);
    989           }
    990         }
    991       }
    992       m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
    993       ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
    994     }
    995     else
    996     {
    997       if(m_pcCfg->getWaveFrontsynchro())
    998       {
    999         CTXMem[1]->loadContexts(m_pcSbacCoder);
    1000       }
    1001       CTXMem[0]->loadContexts(m_pcSbacCoder);
    1002     }
    1003   }
    1004 
    1005   // for every CU in slice
    1006 #if H_3D
     839
     840
     841
     842  // Adjust initial state if this is the start of a dependent slice.
     843  {
     844    const UInt      ctuRsAddr               = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
     845    const UInt      currentTileIdx          = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
     846    const TComTile *pCurrentTile            = pcPic->getPicSym()->getTComTile(currentTileIdx);
     847    const UInt      firstCtuRsAddrOfTile    = pCurrentTile->getFirstCtuRsAddr();
     848    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
     849    {
     850      // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
     851      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getWaveFrontsynchro() )
     852      {
     853        m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );
     854      }
     855    }
     856  }
     857
     858  // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
     859#if NH_3D_VSO
    1007860  Int iLastPosY = -1;
    1008861#endif
    1009   UInt uiEncCUOrder;
    1010   for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
    1011        uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
    1012        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
    1013   {
    1014     // initialize CU encoder
    1015     TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
    1016     pcCU->initCU( rpcPic, uiCUAddr );
    1017 #if H_3D_VSO
     862
     863  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
     864  {
     865    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
     866    // initialize CTU encoder
     867    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
     868    pCtu->initCtu( pcPic, ctuRsAddr );
     869#if NH_3D_VSO
    1018870    if ( m_pcRdCost->getUseRenModel() )
    1019871    {
     
    1021873      Int iCurPosX;
    1022874      Int iCurPosY;
    1023       pcCU->getPosInPic(0, iCurPosX, iCurPosY );
     875      pCtu->getPosInPic(0, iCurPosX, iCurPosY );
    1024876      if ( iCurPosY != iLastPosY )
    1025877      {
    1026878        iLastPosY = iCurPosY;         
    1027         pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
    1028       }
    1029     }
    1030 #endif
    1031     // inherit from TR if necessary, select substream to use.
    1032       uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
    1033       uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
    1034       uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
    1035       //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
    1036       uiCol     = uiCUAddr % uiWidthInLCUs;
    1037       uiLin     = uiCUAddr / uiWidthInLCUs;
    1038       if (pcSlice->getPPS()->getNumSubstreams() > 1)
    1039       {
    1040         // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
    1041         Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
    1042         uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
    1043                       + uiLin%iNumSubstreamsPerTile;
     879        TEncTop* pcEncTop = (TEncTop*) m_pcCfg; // Fix this later.
     880        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY, pcSlice->getSPS()->getMaxCUHeight() );
     881      }
     882    }
     883#endif
     884
     885    // update CABAC state
     886    const UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr();
     887    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
     888    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
     889   
     890    if (ctuRsAddr == firstCtuRsAddrOfTile)
     891    {
     892      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
     893    }
     894    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getWaveFrontsynchro())
     895    {
     896      // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
     897      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
     898      // Sync if the Top-Right is available.
     899      TComDataCU *pCtuUp = pCtu->getCtuAbove();
     900      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
     901      {
     902        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
     903        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
     904        {
     905          // Top-Right is available, we use it.
     906          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState );
     907        }
     908      }
     909    }
     910
     911    // set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer)
     912    m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder );
     913    m_pcEntropyCoder->setBitstream( &tempBitCounter );
     914    tempBitCounter.resetBits();
     915    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder
     916                                                                     // is reset to a known state before every decision process.
     917
     918    ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
     919
     920    Double oldLambda = m_pcRdCost->getLambda();
     921    if ( m_pcCfg->getUseRateCtrl() )
     922    {
     923      Int estQP        = pcSlice->getSliceQp();
     924      Double estLambda = -1.0;
     925      Double bpp       = -1.0;
     926
     927      if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
     928      {
     929        estQP = pcSlice->getSliceQp();
    1044930      }
    1045931      else
    1046932      {
    1047         // dependent tiles => substreams are "per frame".
    1048         uiSubStrm = uiLin % iNumSubstreams;
    1049       }
    1050       if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
    1051       {
    1052         // We'll sync if the TR is available.
    1053         TComDataCU *pcCUUp = pcCU->getCUAbove();
    1054         UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
    1055         UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
    1056         TComDataCU *pcCUTR = NULL;
    1057         if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
    1058         {
    1059           pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
    1060         }
    1061         if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
    1062              (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
    1063              ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
    1064              )
    1065            )
    1066         {
    1067           // TR not available.
    1068         }
    1069         else
    1070         {
    1071           // TR is available, we use it.
    1072           ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
    1073         }
    1074       }
    1075       m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
    1076 
    1077     // reset the entropy coder
    1078     if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
    1079         uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
    1080         uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
    1081         uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
    1082     {
    1083       SliceType sliceType = pcSlice->getSliceType();
    1084       if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
    1085       {
    1086         sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
    1087       }
    1088       m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
    1089       m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
    1090       m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
    1091       m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
    1092     }
    1093 
    1094       // set go-on entropy coder
    1095       m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
    1096       m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
    1097      
    1098       ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
    1099 
    1100       Double oldLambda = m_pcRdCost->getLambda();
    1101       if ( m_pcCfg->getUseRateCtrl() )
    1102       {
    1103         Int estQP        = pcSlice->getSliceQp();
    1104         Double estLambda = -1.0;
    1105         Double bpp       = -1.0;
    1106 
    1107         if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
    1108         {
    1109           estQP = pcSlice->getSliceQp();
    1110         }
    1111         else
    1112         {
    1113933#if KWU_RC_MADPRED_E0227
    1114934          if(pcSlice->getLayerId() != 0 && m_pcCfg->getUseDepthMADPred() && !pcSlice->getIsDepth())
     
    1129949          {
    1130950#endif
    1131           bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
    1132           if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
    1133           {
    1134             estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
    1135           }
    1136           else
    1137           {
    1138             estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
    1139             estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
    1140           }
     951        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
     952        if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE)
     953        {
     954          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
     955        }
     956        else
     957        {
     958          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
     959          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
     960        }
    1141961#if KWU_RC_MADPRED_E0227
    1142962          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
    1143963          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
    1144964#endif
    1145           estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
    1146 
    1147           m_pcRdCost->setLambda(estLambda);
     965
     966        estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
     967
     968        m_pcRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths());
     969
    1148970#if RDOQ_CHROMA_LAMBDA
    1149           // set lambda for RDOQ
    1150           Double weight=m_pcRdCost->getChromaWeight();
    1151         const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
     971        // set lambda for RDOQ
     972        const Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight();
     973        const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
    1152974        m_pcTrQuant->setLambdas( lambdaArray );
    1153975#else
    1154           m_pcTrQuant->setLambda( estLambda );
    1155 #endif
    1156         }
    1157 
    1158         m_pcRateCtrl->setRCQP( estQP );
     976        m_pcTrQuant->setLambda( estLambda );
     977#endif
     978      }
     979
     980      m_pcRateCtrl->setRCQP( estQP );
    1159981#if ADAPTIVE_QP_SELECTION
    1160         pcCU->getSlice()->setSliceQpBase( estQP );
    1161 #endif
    1162       }
    1163       // run CU encoder
    1164       m_pcCuEncoder->compressCU( pcCU );
    1165 
    1166       // restore entropy coder to an initial stage
    1167       m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
    1168       m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
    1169       m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
    1170       m_pcBitCounter = &pcBitCounters[uiSubStrm];
    1171       pppcRDSbacCoder->setBinCountingEnableFlag( true );
    1172       m_pcBitCounter->resetBits();
    1173       pppcRDSbacCoder->setBinsCoded( 0 );
    1174       m_pcCuEncoder->encodeCU( pcCU );
    1175 
    1176       pppcRDSbacCoder->setBinCountingEnableFlag( false );
    1177       if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
    1178       {
    1179         pcSlice->setNextSlice( true );
    1180         break;
    1181       }
    1182       if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
    1183       {
    1184         pcSlice->setNextSliceSegment( true );
    1185         break;
    1186       }
    1187        
    1188     ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
    1189          //Store probabilties of second LCU in line into buffer
    1190          if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
    1191         {
    1192           m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
    1193         }
    1194 
    1195       if ( m_pcCfg->getUseRateCtrl() )
    1196       {
     982      pCtu->getSlice()->setSliceQpBase( estQP );
     983#endif
     984    }
     985
     986    // run CTU trial encoder
     987    m_pcCuEncoder->compressCtu( pCtu );
     988
     989
     990    // All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode,
     991    // which will result in the state of the contexts being correct. It will also count up the number of bits coded,
     992    // which is used if there is a limit of the number of bytes per slice-segment.
     993
     994    m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
     995    m_pcEntropyCoder->setBitstream( &tempBitCounter );
     996    pRDSbacCoder->setBinCountingEnableFlag( true );
     997    m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits();
     998    pRDSbacCoder->setBinsCoded( 0 );
     999
     1000    // encode CTU and calculate the true bit counters.
     1001    m_pcCuEncoder->encodeCtu( pCtu );
     1002
     1003
     1004    pRDSbacCoder->setBinCountingEnableFlag( false );
     1005
     1006    const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
     1007
     1008    // Calculate if this CTU puts us over slice bit size.
     1009    // cannot terminate if current slice/slice-segment would be 0 Ctu in size,
     1010    const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);
     1011    // Set slice end parameter
     1012    if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3))
     1013    {
     1014      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
     1015      pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
     1016      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
     1017    }
     1018    else if((!bCompressEntireSlice) && pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3))
     1019    {
     1020      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
     1021      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
     1022    }
     1023
     1024    if (boundingCtuTsAddr <= ctuTsAddr)
     1025    {
     1026      break;
     1027    }
     1028
     1029    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
     1030    pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);
     1031
     1032    // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
     1033    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getWaveFrontsynchro())
     1034    {
     1035      m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
     1036    }
     1037
     1038
     1039    if ( m_pcCfg->getUseRateCtrl() )
     1040    {
    11971041#if KWU_RC_MADPRED_E0227
    11981042        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
     
    12041048#endif
    12051049
    1206         Int actualQP        = g_RCInvalidQPValue;
    1207         Double actualLambda = m_pcRdCost->getLambda();
    1208         Int actualBits      = pcCU->getTotalBits();
    1209         Int numberOfEffectivePixels    = 0;
    1210         for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
     1050      Int actualQP        = g_RCInvalidQPValue;
     1051      Double actualLambda = m_pcRdCost->getLambda();
     1052      Int actualBits      = pCtu->getTotalBits();
     1053      Int numberOfEffectivePixels    = 0;
     1054      for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ )
     1055      {
     1056        if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) )
    12111057        {
    1212           if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
    1213           {
    1214             numberOfEffectivePixels = numberOfEffectivePixels + 16;
    1215             break;
    1216           }
     1058          numberOfEffectivePixels = numberOfEffectivePixels + 16;
     1059          break;
    12171060        }
    1218 
    1219         if ( numberOfEffectivePixels == 0 )
    1220         {
    1221           actualQP = g_RCInvalidQPValue;
    1222         }
    1223         else
    1224         {
    1225           actualQP = pcCU->getQP( 0 );
    1226         }
    1227         m_pcRdCost->setLambda(oldLambda);
    1228 
    1229         m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
    1230           pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
    1231     }
    1232    
    1233     m_uiPicTotalBits += pcCU->getTotalBits();
    1234     m_dPicRdCost     += pcCU->getTotalCost();
    1235     m_uiPicDist      += pcCU->getTotalDistortion();
    1236   }
    1237   if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
    1238   {
    1239     pcSlice->setNextSlice( true );
    1240   }
    1241   if(m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES || m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES)
    1242   {
    1243     if(pcSlice->getSliceCurEndCUAddr()<=pcSlice->getSliceSegmentCurEndCUAddr())
    1244     {
    1245        pcSlice->setNextSlice( true );
    1246     }
    1247     else
    1248     {
    1249        pcSlice->setNextSliceSegment( true );
    1250     }
    1251   }
    1252   if( depSliceSegmentsEnabled )
    1253   {
    1254     if (m_pcCfg->getWaveFrontsynchro())
    1255     {
    1256       CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
    1257     }
    1258      CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
    1259   }
    1260   xRestoreWPparam( pcSlice );
    1261 }
    1262 
    1263 /**
    1264  \param  rpcPic        picture class
    1265  \retval rpcBitstream  bitstream class
    1266  */
    1267 Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
    1268 {
    1269   UInt       uiCUAddr;
    1270   UInt       uiStartCUAddr;
    1271   UInt       uiBoundingCUAddr;
    1272   TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
    1273 
    1274   uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
    1275   uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
    1276   // choose entropy coder
    1277   {
    1278     m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
    1279     m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
    1280   }
    1281  
    1282   m_pcCuEncoder->setBitCounter( NULL );
    1283   m_pcBitCounter = NULL;
    1284   // Appropriate substream bitstream is switched later.
    1285   // for every CU
     1061      }
     1062
     1063      if ( numberOfEffectivePixels == 0 )
     1064      {
     1065        actualQP = g_RCInvalidQPValue;
     1066      }
     1067      else
     1068      {
     1069        actualQP = pCtu->getQP( 0 );
     1070      }
     1071      m_pcRdCost->setLambda(oldLambda, pcSlice->getSPS()->getBitDepths());
     1072      m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
     1073                                                pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
     1074    }
     1075
     1076    m_uiPicTotalBits += pCtu->getTotalBits();
     1077    m_dPicRdCost     += pCtu->getTotalCost();
     1078    m_uiPicDist      += pCtu->getTotalDistortion();
     1079  }
     1080
     1081  // store context state at the end of this slice-segment, in case the next slice is a dependent slice and continues using the CABAC contexts.
     1082  if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() )
     1083  {
     1084    m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
     1085  }
     1086
     1087  // stop use of temporary bit counter object.
     1088  m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL);
     1089  m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter.
     1090
     1091  // TODO: optimise cabac_init during compress slice to improve multi-slice operation
     1092  //if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
     1093  //{
     1094  //  m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx();
     1095  //}
     1096  //else
     1097  //{
     1098  //  m_encCABACTableIdx = pcSlice->getSliceType();
     1099  //}
     1100}
     1101
     1102Void TEncSlice::encodeSlice   ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded )
     1103{
     1104  TComSlice *const pcSlice           = pcPic->getSlice(getSliceIdx());
     1105
     1106  const UInt startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
     1107  const UInt boundingCtuTsAddr       = pcSlice->getSliceSegmentCurEndCtuTsAddr();
     1108
     1109  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
     1110  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
     1111  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
     1112
     1113  // initialise entropy coder for the slice
     1114  m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
     1115  m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder );
     1116  m_pcEntropyCoder->resetEntropy    ( pcSlice );
     1117
     1118  numBinsCoded = 0;
     1119  m_pcBinCABAC->setBinCountingEnableFlag( true );
     1120  m_pcBinCABAC->setBinsCoded(0);
     1121
    12861122#if ENC_DEC_TRACE
    12871123  g_bJustDoIt = g_bEncDecTraceEnable;
    12881124#endif
     1125#if H_MV_ENC_DEC_TRAC
     1126#if ENC_DEC_TRACE
     1127  incSymbolCounter();
     1128#endif
     1129  DTRACE_CABAC_VL( g_nSymbolCounter );
     1130#else
    12891131  DTRACE_CABAC_VL( g_nSymbolCounter++ );
     1132#endif
    12901133  DTRACE_CABAC_T( "\tPOC: " );
    1291   DTRACE_CABAC_V( rpcPic->getPOC() );
     1134  DTRACE_CABAC_V( pcPic->getPOC() );
    12921135#if H_MV_ENC_DEC_TRAC
    12931136  DTRACE_CABAC_T( " Layer: " );
    1294   DTRACE_CABAC_V( rpcPic->getLayerId() );
     1137  DTRACE_CABAC_V( pcPic->getLayerId() );
    12951138#endif
    12961139  DTRACE_CABAC_T( "\n" );
     
    12991142#endif
    13001143
    1301   TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
    1302   TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
    1303   Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
    1304   UInt uiBitsOriginallyInSubstreams = 0;
    1305   {
    1306     UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
    1307     for (UInt ui = 0; ui < uiTilesAcross; ui++)
    1308     {
    1309       m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
    1310     }
    1311    
    1312     for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
    1313     {
    1314       uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
    1315     }
    1316 
    1317     for (UInt ui = 0; ui < uiTilesAcross; ui++)
    1318     {
    1319       m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
    1320     }
    1321   }
    1322 
    1323   UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
    1324   UInt uiCol=0, uiLin=0, uiSubStrm=0;
    1325   UInt uiTileCol      = 0;
    1326   UInt uiTileStartLCU = 0;
    1327   UInt uiTileLCUX     = 0;
    1328   Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
    1329   uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
    1330                                                                                                an encoding order index, so we need to convert the index (uiStartCUAddr)
    1331                                                                                                into the real raster scan address (uiCUAddr) via the CUOrderMap */
    1332   uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
    1333   if( depSliceSegmentsEnabled )
    1334   {
    1335     if( pcSlice->isNextSlice()||
    1336         uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
    1337     {
    1338       if(m_pcCfg->getWaveFrontsynchro())
    1339       {
    1340         CTXMem[1]->loadContexts(m_pcSbacCoder);
    1341       }
    1342       CTXMem[0]->loadContexts(m_pcSbacCoder);
    1343     }
    1344     else
    1345     {
    1346       if(m_pcCfg->getWaveFrontsynchro())
    1347       {
    1348         uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
    1349         m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
    1350         Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
    1351         uiLin     = uiCUAddr / uiWidthInLCUs;
    1352         uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
    1353           + uiLin%iNumSubstreamsPerTile;
    1354         if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs )
     1144
     1145  if (depSliceSegmentsEnabled)
     1146  {
     1147    // modify initial contexts with previous slice segment if this is a dependent slice.
     1148    const UInt ctuRsAddr        = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr );
     1149    const UInt currentTileIdx=pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
     1150    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(currentTileIdx);
     1151    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();
     1152
     1153    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
     1154    {
     1155      if( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled )
     1156      {
     1157        m_pcSbacCoder->loadContexts(&m_lastSliceSegmentEndContextState);
     1158      }
     1159    }
     1160  }
     1161
     1162  // for every CTU in the slice segment...
     1163
     1164  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
     1165  {
     1166    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
     1167    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
     1168    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
     1169    const UInt tileXPosInCtus       = firstCtuRsAddrOfTile % frameWidthInCtus;
     1170    const UInt tileYPosInCtus       = firstCtuRsAddrOfTile / frameWidthInCtus;
     1171    const UInt ctuXPosInCtus        = ctuRsAddr % frameWidthInCtus;
     1172    const UInt ctuYPosInCtus        = ctuRsAddr / frameWidthInCtus;
     1173    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice);
     1174    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
     1175
     1176    m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
     1177
     1178    // set up CABAC contexts' state for this CTU
     1179    if (ctuRsAddr == firstCtuRsAddrOfTile)
     1180    {
     1181      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
     1182      {
     1183        m_pcEntropyCoder->resetEntropy(pcSlice);
     1184      }
     1185    }
     1186    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
     1187    {
     1188      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
     1189      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
     1190      {
     1191        m_pcEntropyCoder->resetEntropy(pcSlice);
     1192      }
     1193      TComDataCU *pCtuUp = pCtu->getCtuAbove();
     1194      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
     1195      {
     1196        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
     1197        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
    13551198        {
    1356           uiCol     = uiCUAddr % uiWidthInLCUs;
    1357           uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
    1358           if(uiCol==uiTileLCUX)
    1359           {
    1360             CTXMem[0]->loadContexts(m_pcSbacCoder);
    1361           }
     1199          // Top-right is available, so use it.
     1200          m_pcSbacCoder->loadContexts( &m_entropyCodingSyncContextState );
    13621201        }
    13631202      }
    1364       pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
    1365     }
    1366   }
    1367 
    1368   UInt uiEncCUOrder;
    1369   for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
    1370        uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
    1371        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
    1372   {
    1373       uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
    1374       uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
    1375       uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
    1376       //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
    1377       uiCol     = uiCUAddr % uiWidthInLCUs;
    1378       uiLin     = uiCUAddr / uiWidthInLCUs;
    1379       if (pcSlice->getPPS()->getNumSubstreams() > 1)
    1380       {
    1381         // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
    1382         Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
    1383         uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
    1384                       + uiLin%iNumSubstreamsPerTile;
    1385       }
    1386       else
    1387       {
    1388         // dependent tiles => substreams are "per frame".
    1389         uiSubStrm = uiLin % iNumSubstreams;
    1390       }
    1391 
    1392       m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
    1393       // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
    1394       if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
    1395       {
    1396         // We'll sync if the TR is available.
    1397         TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
    1398         UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
    1399         UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
    1400         TComDataCU *pcCUTR = NULL;
    1401         if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
     1203    }
     1204
     1205#if NH_3D_QTLPC
     1206    pcPic->setReduceBitsFlag(true);
     1207#endif
     1208    if ( pcSlice->getSPS()->getUseSAO() )
     1209    {
     1210      Bool bIsSAOSliceEnabled = false;
     1211      Bool sliceEnabled[MAX_NUM_COMPONENT];
     1212      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
     1213      {
     1214        ComponentID compId=ComponentID(comp);
     1215        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
     1216        if (sliceEnabled[compId])
    14021217        {
    1403           pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
     1218          bIsSAOSliceEnabled=true;
    14041219        }
    1405         if ( (true/*bEnforceSliceRestriction*/ &&
    1406              ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
    1407              (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
    1408              ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
    1409              ))
    1410            )
    1411         {
    1412           // TR not available.
    1413         }
    1414         else
    1415         {
    1416           // TR is available, we use it.
    1417           pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
    1418         }
    1419       }
    1420       m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
    1421 
    1422     // reset the entropy coder
    1423     if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
    1424         uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
    1425         uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
    1426         uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
    1427     {
    1428       {
    1429         // We're crossing into another tile, tiles are independent.
    1430         // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
    1431         // have to perform it here.
    1432         if (pcSlice->getPPS()->getNumSubstreams() > 1)
    1433         {
    1434           ; // do nothing.
    1435         }
    1436         else
    1437         {
    1438           SliceType sliceType  = pcSlice->getSliceType();
    1439           if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
    1440           {
    1441             sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
    1442           }
    1443           m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
    1444           // Byte-alignment in slice_data() when new tile
    1445           pcSubstreams[uiSubStrm].writeByteAlignment();
    1446         }
    1447       }
    1448       {
    1449         UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
    1450         UInt uiAccumulatedSubstreamLength = 0;
    1451         for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
    1452         {
    1453           uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
    1454         }
    1455         // add bits coded in previous dependent slices + bits coded so far
    1456         // add number of emulation prevention byte count in the tile
    1457         pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
    1458       }
    1459     }
    1460 
    1461 #if H_3D_QTLPC
    1462     rpcPic->setReduceBitsFlag(true);
    1463 #endif
    1464     TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
    1465     if ( pcSlice->getSPS()->getUseSAO() )
    1466     {
    1467       if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
    1468       {
    1469         SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr];
    1470         Bool sliceEnabled[NUM_SAO_COMPONENTS];
    1471         sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
    1472         sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
     1220      }
     1221      if (bIsSAOSliceEnabled)
     1222      {
     1223        SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
    14731224
    14741225        Bool leftMergeAvail = false;
    14751226        Bool aboveMergeAvail= false;
    14761227        //merge left condition
    1477         Int rx = (uiCUAddr % uiWidthInLCUs);
     1228        Int rx = (ctuRsAddr % frameWidthInCtus);
    14781229        if(rx > 0)
    14791230        {
    1480           leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);
     1231          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
    14811232        }
    14821233
    14831234        //merge up condition
    1484         Int ry = (uiCUAddr / uiWidthInLCUs);
     1235        Int ry = (ctuRsAddr / frameWidthInCtus);
    14851236        if(ry > 0)
    1486       {
    1487           aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);
     1237        {
     1238          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
    14881239        }
    14891240
    1490         m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
    1491       }
    1492     }
     1241        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, pcPic->getPicSym()->getSPS().getBitDepths(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
     1242      }
     1243    }
     1244
    14931245#if ENC_DEC_TRACE
    14941246    g_bJustDoIt = g_bEncDecTraceEnable;
    14951247#endif
    1496     if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
    1497       uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
    1498     {
    1499       m_pcCuEncoder->encodeCU( pcCU );
    1500     }
    1501     else
    1502     {
    1503       m_pcCuEncoder->encodeCU( pcCU );
    1504     }
     1248      m_pcCuEncoder->encodeCtu( pCtu );
    15051249#if ENC_DEC_TRACE
    15061250    g_bJustDoIt = g_bEncDecTraceDisable;
    1507 #endif   
    1508        pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
    1509        
    1510 
    1511        //Store probabilties of second LCU in line into buffer
    1512        if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
    1513       {
    1514         m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
    1515       }
    1516 #if H_3D_QTLPC
    1517     rpcPic->setReduceBitsFlag(false);
    1518 #endif
    1519   }
     1251#endif
     1252
     1253    //Store probabilities of second CTU in line into buffer
     1254    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
     1255    {
     1256      m_entropyCodingSyncContextState.loadContexts( m_pcSbacCoder );
     1257    }
     1258
     1259    // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row):
     1260    if (ctuTsAddr+1 == boundingCtuTsAddr ||
     1261         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
     1262          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
     1263         )
     1264       )
     1265    {
     1266      m_pcEntropyCoder->encodeTerminatingBit(1);
     1267      m_pcEntropyCoder->encodeSliceFinish();
     1268      // Byte-alignment in slice_data() when new tile
     1269      pcSubstreams[uiSubStrm].writeByteAlignment();
     1270
     1271      // write sub-stream size
     1272      if (ctuTsAddr+1 != boundingCtuTsAddr)
     1273      {
     1274        pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() );
     1275      }
     1276    }
     1277#if NH_3D_QTLPC
     1278    pcPic->setReduceBitsFlag(false);
     1279#endif
     1280  } // CTU-loop
     1281
    15201282  if( depSliceSegmentsEnabled )
    15211283  {
    1522     if (m_pcCfg->getWaveFrontsynchro())
    1523     {
    1524       CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
    1525     }
    1526     CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
    1527   }
     1284    m_lastSliceSegmentEndContextState.loadContexts( m_pcSbacCoder );//ctx end of dep.slice
     1285  }
     1286
    15281287#if ADAPTIVE_QP_SELECTION
    15291288  if( m_pcCfg->getUseAdaptQpSelect() )
    15301289  {
    1531     m_pcTrQuant->storeSliceQpNext(pcSlice);
    1532   }
    1533 #endif
    1534   if (pcSlice->getPPS()->getCabacInitPresentFlag())
    1535   {
    1536     if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
    1537     {
    1538       pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
    1539     }
    1540     else
    1541     {
    1542       m_pcEntropyCoder->determineCabacInitIdx();
    1543     }
    1544   }
    1545 }
    1546 
    1547 /** Determines the starting and bounding LCU address of current slice / dependent slice
    1548  * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
    1549  * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
    1550  */
    1551 Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
    1552 {
    1553   TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
    1554   UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
    1555   UInt tileIdxIncrement;
    1556   UInt tileIdx;
    1557   UInt tileWidthInLcu;
    1558   UInt tileHeightInLcu;
    1559   UInt tileTotalCount;
    1560 
    1561   uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
    1562   UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
    1563   uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
    1564   if (bEncodeSlice)
    1565   {
    1566     UInt uiCUAddrIncrement;
    1567     switch (m_pcCfg->getSliceMode())
    1568     {
    1569     case FIXED_NUMBER_OF_LCU:
    1570       uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
    1571       uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
     1290    m_pcTrQuant->storeSliceQpNext(pcSlice); // TODO: this will only be storing the adaptive QP state of the very last slice-segment that is not dependent in the frame... Perhaps this should be moved to the compress slice loop.
     1291  }
     1292#endif
     1293
     1294  if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
     1295  {
     1296    m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx(pcSlice);
     1297  }
     1298  else
     1299  {
     1300    m_encCABACTableIdx = pcSlice->getSliceType();
     1301  }
     1302 
     1303  numBinsCoded = m_pcBinCABAC->getBinsCoded();
     1304}
     1305
     1306Void TEncSlice::calculateBoundingCtuTsAddrForSlice(UInt &startCtuTSAddrSlice, UInt &boundingCtuTSAddrSlice, Bool &haveReachedTileBoundary,
     1307                                                   TComPic* pcPic, const Int sliceMode, const Int sliceArgument)
     1308{
     1309  TComSlice* pcSlice = pcPic->getSlice(getSliceIdx());
     1310  const UInt numberOfCtusInFrame = pcPic->getNumberOfCtusInFrame();
     1311  const TComPPS &pps=*(pcSlice->getPPS());
     1312  boundingCtuTSAddrSlice=0;
     1313  haveReachedTileBoundary=false;
     1314
     1315  switch (sliceMode)
     1316  {
     1317    case FIXED_NUMBER_OF_CTU:
     1318      {
     1319        UInt ctuAddrIncrement    = sliceArgument;
     1320        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
     1321      }
    15721322      break;
    15731323    case FIXED_NUMBER_OF_BYTES:
    1574       uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
    1575       uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
     1324      boundingCtuTSAddrSlice  = numberOfCtusInFrame; // This will be adjusted later if required.
    15761325      break;
    15771326    case FIXED_NUMBER_OF_TILES:
    1578       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
    1579         rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
    1580         );
    1581       uiCUAddrIncrement        = 0;
    1582       tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
    1583 
    1584       for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
    1585       {
    1586         if((tileIdx + tileIdxIncrement) < tileTotalCount)
     1327      {
     1328        const UInt tileIdx        = pcPic->getPicSym()->getTileIdxMap( pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice) );
     1329        const UInt tileTotalCount = (pcPic->getPicSym()->getNumTileColumnsMinus1()+1) * (pcPic->getPicSym()->getNumTileRowsMinus1()+1);
     1330        UInt ctuAddrIncrement   = 0;
     1331
     1332        for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++)
    15871333        {
    1588           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
    1589           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
    1590           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
     1334          if((tileIdx + tileIdxIncrement) < tileTotalCount)
     1335          {
     1336            UInt tileWidthInCtus   = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidthInCtus();
     1337            UInt tileHeightInCtus  = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeightInCtus();
     1338            ctuAddrIncrement    += (tileWidthInCtus * tileHeightInCtus);
     1339          }
    15911340        }
    1592       }
    1593 
    1594       uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
     1341
     1342        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
     1343      }
    15951344      break;
    15961345    default:
    1597       uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
    1598       uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
     1346      boundingCtuTSAddrSlice    = numberOfCtusInFrame;
    15991347      break;
    1600     }
     1348  }
     1349
     1350  // Adjust for tiles and wavefronts.
     1351  const Bool wavefrontsAreEnabled = pps.getEntropyCodingSyncEnabledFlag();
     1352
     1353  if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) &&
     1354      (pps.getNumTileRowsMinus1() > 0 || pps.getNumTileColumnsMinus1() > 0))
     1355  {
     1356    const UInt ctuRSAddr                  = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice);
     1357    const UInt startTileIdx               = pcPic->getPicSym()->getTileIdxMap(ctuRSAddr);
     1358
     1359    const TComTile *pStartingTile         = pcPic->getPicSym()->getTComTile(startTileIdx);
     1360    const UInt tileStartTsAddr            = pcPic->getPicSym()->getCtuRsToTsAddrMap(pStartingTile->getFirstCtuRsAddr());
     1361    const UInt tileStartWidth             = pStartingTile->getTileWidthInCtus();
     1362    const UInt tileStartHeight            = pStartingTile->getTileHeightInCtus();
     1363    const UInt tileLastTsAddr_excl        = tileStartTsAddr + tileStartWidth*tileStartHeight;
     1364    const UInt tileBoundingCtuTsAddrSlice = tileLastTsAddr_excl;
     1365
     1366    const UInt ctuColumnOfStartingTile    = ((startCtuTSAddrSlice-tileStartTsAddr)%tileStartWidth);
     1367    if (wavefrontsAreEnabled && ctuColumnOfStartingTile!=0)
     1368    {
     1369      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
     1370      const UInt numberOfCTUsToEndOfRow            = tileStartWidth - ctuColumnOfStartingTile;
     1371      const UInt wavefrontTileBoundingCtuAddrSlice = startCtuTSAddrSlice + numberOfCTUsToEndOfRow;
     1372      if (wavefrontTileBoundingCtuAddrSlice < boundingCtuTSAddrSlice)
     1373      {
     1374        boundingCtuTSAddrSlice = wavefrontTileBoundingCtuAddrSlice;
     1375      }
     1376    }
     1377
     1378    if (tileBoundingCtuTsAddrSlice < boundingCtuTSAddrSlice)
     1379    {
     1380      boundingCtuTSAddrSlice = tileBoundingCtuTsAddrSlice;
     1381      haveReachedTileBoundary = true;
     1382    }
     1383  }
     1384  else if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && wavefrontsAreEnabled && ((startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) != 0))
     1385  {
     1386    // Adjust for wavefronts (no tiles).
    16011387    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
    1602     if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
    1603     {
    1604       uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
    1605     }
    1606     pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
    1607   }
    1608   else
    1609   {
    1610     UInt uiCUAddrIncrement     ;
    1611     switch (m_pcCfg->getSliceMode())
    1612     {
    1613     case FIXED_NUMBER_OF_LCU:
    1614       uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
    1615       uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1616       break;
    1617     case FIXED_NUMBER_OF_TILES:
    1618       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
    1619         rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
    1620         );
    1621       uiCUAddrIncrement        = 0;
    1622       tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
    1623 
    1624       for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
    1625       {
    1626         if((tileIdx + tileIdxIncrement) < tileTotalCount)
    1627         {
    1628           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
    1629           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
    1630           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
    1631         }
    1632       }
    1633 
    1634       uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1635       break;
    1636     default:
    1637       uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
    1638       uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1639       break;
    1640     }
    1641     // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
    1642     if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
    1643     {
    1644       uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
    1645     }
    1646     pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
    1647   }
    1648 
    1649   Bool tileBoundary = false;
    1650   if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) &&
    1651       (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
    1652   {
    1653     UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
    1654     UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
    1655     UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
    1656     UInt tileBoundingCUAddrSlice = 0;
    1657     while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
    1658     {
    1659       lcuEncAddr++;
    1660       lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
    1661     }
    1662     tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
    1663    
    1664     if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
    1665     {
    1666       uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
    1667       pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
    1668       tileBoundary = true;
    1669     }
    1670   }
     1388    boundingCtuTSAddrSlice = min(boundingCtuTSAddrSlice, startCtuTSAddrSlice - (startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) + (pcPic->getFrameWidthInCtus()));
     1389  }
     1390}
     1391
     1392/** Determines the starting and bounding CTU address of current slice / dependent slice
     1393 * \param [out] startCtuTsAddr
     1394 * \param [out] boundingCtuTsAddr
     1395 * \param [in]  pcPic
     1396
     1397 * Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address
     1398 */
     1399Void TEncSlice::xDetermineStartAndBoundingCtuTsAddr  ( UInt& startCtuTsAddr, UInt& boundingCtuTsAddr, TComPic* pcPic )
     1400{
     1401  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
     1402
     1403  // Non-dependent slice
     1404  UInt startCtuTsAddrSlice           = pcSlice->getSliceCurStartCtuTsAddr();
     1405  Bool haveReachedTileBoundarySlice  = false;
     1406  UInt boundingCtuTsAddrSlice;
     1407  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic,
     1408                                     m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument());
     1409  pcSlice->setSliceCurEndCtuTsAddr(   boundingCtuTsAddrSlice );
     1410  pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice    );
    16711411
    16721412  // Dependent slice
    1673   UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
    1674   startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
    1675   boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
    1676   if (bEncodeSlice)
    1677   {
    1678     UInt uiCUAddrIncrement;
    1679     switch (m_pcCfg->getSliceSegmentMode())
    1680     {
    1681     case FIXED_NUMBER_OF_LCU:
    1682       uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
    1683       boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1684       break;
    1685     case FIXED_NUMBER_OF_BYTES:
    1686       uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
    1687       boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
    1688       break;
    1689     case FIXED_NUMBER_OF_TILES:
    1690       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
    1691         rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
    1692         );
    1693       uiCUAddrIncrement        = 0;
    1694       tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
    1695 
    1696       for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
    1697       {
    1698         if((tileIdx + tileIdxIncrement) < tileTotalCount)
    1699         {
    1700           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
    1701           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
    1702           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
    1703         }
    1704       }
    1705       boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1706       break;
    1707     default:
    1708       uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
    1709       boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1710       break;
    1711     }
    1712     // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
    1713     if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
    1714     {
    1715       boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
    1716     }
    1717     pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
    1718   }
    1719   else
    1720   {
    1721     UInt uiCUAddrIncrement;
    1722     switch (m_pcCfg->getSliceSegmentMode())
    1723     {
    1724     case FIXED_NUMBER_OF_LCU:
    1725       uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
    1726       boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1727       break;
    1728     case FIXED_NUMBER_OF_TILES:
    1729       tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
    1730         rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
    1731         );
    1732       uiCUAddrIncrement        = 0;
    1733       tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
    1734 
    1735       for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
    1736       {
    1737         if((tileIdx + tileIdxIncrement) < tileTotalCount)
    1738         {
    1739           tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
    1740           tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
    1741           uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
    1742         }
    1743       }
    1744       boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1745       break;
    1746     default:
    1747       uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
    1748       boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
    1749       break;
    1750     }
    1751     // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
    1752     if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
    1753     {
    1754       boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
    1755     }
    1756     pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
    1757   }
    1758   if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) &&
    1759     (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
    1760   {
    1761     UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
    1762     UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
    1763     UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
    1764     UInt tileBoundingCUAddrSlice = 0;
    1765     while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
    1766     {
    1767       lcuEncAddr++;
    1768       lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
    1769     }
    1770     tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
    1771 
    1772     if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
    1773     {
    1774       boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
    1775       pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
    1776       tileBoundary = true;
    1777     }
    1778   }
    1779 
    1780   if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
    1781   {
    1782     boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
    1783     pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
    1784   }
    1785 
    1786   //calculate real dependent slice start address
    1787   UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
    1788   UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
    1789   UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1790   UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1791   UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
    1792   UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
    1793   while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
    1794   {
    1795     uiInternalAddress++;
    1796     if(uiInternalAddress>=rpcPic->getNumPartInCU())
    1797     {
    1798       uiInternalAddress=0;
    1799       uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
    1800     }
    1801     uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1802     uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1803   }
    1804   UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
    1805  
    1806   pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
    1807   startCUAddrSliceSegment=uiRealStartAddress;
    1808  
    1809   //calculate real slice start address
    1810   uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
    1811   uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
    1812   uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1813   uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1814   uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
    1815   uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
    1816   while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
    1817   {
    1818     uiInternalAddress++;
    1819     if(uiInternalAddress>=rpcPic->getNumPartInCU())
    1820     {
    1821       uiInternalAddress=0;
    1822       uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
    1823     }
    1824     uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1825     uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1826   }
    1827   uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
    1828  
    1829   pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
    1830   uiStartCUAddrSlice=uiRealStartAddress;
    1831  
     1413  UInt startCtuTsAddrSliceSegment          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
     1414  Bool haveReachedTileBoundarySliceSegment = false;
     1415  UInt boundingCtuTsAddrSliceSegment;
     1416  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic,
     1417                                     m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument());
     1418  if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice)
     1419  {
     1420    boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice;
     1421  }
     1422  pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment );
     1423  pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment);
     1424
    18321425  // Make a joint decision based on reconstruction and dependent slice bounds
    1833   startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
    1834   boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
    1835 
    1836 
    1837   if (!bEncodeSlice)
    1838   {
    1839     // For fixed number of LCU within an entropy and reconstruction slice we already know whether we will encounter end of entropy and/or reconstruction slice
    1840     // first. Set the flags accordingly.
    1841     if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
    1842       || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
    1843       || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0)
    1844       || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
    1845       || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0)
    1846       || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
    1847       || tileBoundary
    1848 )
    1849     {
    1850       if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
    1851       {
    1852         pcSlice->setNextSlice       ( true );
    1853         pcSlice->setNextSliceSegment( false );
    1854       }
    1855       else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
    1856       {
    1857         pcSlice->setNextSlice       ( false );
    1858         pcSlice->setNextSliceSegment( true );
    1859       }
    1860       else
    1861       {
    1862         pcSlice->setNextSlice       ( true );
    1863         pcSlice->setNextSliceSegment( true );
    1864       }
    1865     }
    1866     else
    1867     {
    1868       pcSlice->setNextSlice       ( false );
    1869       pcSlice->setNextSliceSegment( false );
    1870     }
    1871   }
     1426  startCtuTsAddr    = max(startCtuTsAddrSlice   , startCtuTsAddrSliceSegment   );
     1427  boundingCtuTsAddr = boundingCtuTsAddrSliceSegment;
    18721428}
    18731429
Note: See TracChangeset for help on using the changeset viewer.