source: 3DVCSoftware/branches/HTM-4.1-dev1-HHI/source/Lib/TLibEncoder/TEncSlice.cpp

Last change on this file was 120, checked in by tech, 12 years ago

Cleanup of WVSO and fixed cfg-file switch

  • Property svn:eol-style set to native
File size: 65.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2012, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
40#if HHI_VSO_SPEEDUP_A0033
41#include "../../App/TAppEncoder/TAppEncTop.h"
42#endif
43#include <math.h>
44
45//! \ingroup TLibEncoder
46//! \{
47
48// ====================================================================================================================
49// Constructor / destructor / create / destroy
50// ====================================================================================================================
51
52TEncSlice::TEncSlice()
53{
54  m_apcPicYuvPred = NULL;
55  m_apcPicYuvResi = NULL;
56 
57  m_pdRdPicLambda = NULL;
58  m_pdRdPicQp     = NULL;
59  m_piRdPicQp     = NULL;
60  m_pcBufferSbacCoders    = NULL;
61  m_pcBufferBinCoderCABACs  = NULL;
62  m_pcBufferLowLatSbacCoders    = NULL;
63  m_pcBufferLowLatBinCoderCABACs  = NULL;
64}
65
66TEncSlice::~TEncSlice()
67{
68}
69
70Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
71{
72  // create prediction picture
73  if ( m_apcPicYuvPred == NULL )
74  {
75    m_apcPicYuvPred  = new TComPicYuv;
76    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
77  }
78 
79  // create residual picture
80  if( m_apcPicYuvResi == NULL )
81  {
82    m_apcPicYuvResi  = new TComPicYuv;
83    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
84  }
85}
86
87Void TEncSlice::destroy()
88{
89  // destroy prediction picture
90  if ( m_apcPicYuvPred )
91  {
92    m_apcPicYuvPred->destroy();
93    delete m_apcPicYuvPred;
94    m_apcPicYuvPred  = NULL;
95  }
96 
97  // destroy residual picture
98  if ( m_apcPicYuvResi )
99  {
100    m_apcPicYuvResi->destroy();
101    delete m_apcPicYuvResi;
102    m_apcPicYuvResi  = NULL;
103  }
104 
105  // free lambda and QP arrays
106  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
107  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
108  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
109
110  if ( m_pcBufferSbacCoders )
111  {
112    delete[] m_pcBufferSbacCoders;
113  }
114  if ( m_pcBufferBinCoderCABACs )
115  {
116    delete[] m_pcBufferBinCoderCABACs;
117  }
118  if ( m_pcBufferLowLatSbacCoders )
119    delete[] m_pcBufferLowLatSbacCoders;
120  if ( m_pcBufferLowLatBinCoderCABACs )
121    delete[] m_pcBufferLowLatBinCoderCABACs;
122}
123
124Void TEncSlice::init( TEncTop* pcEncTop )
125{
126  m_pcCfg             = pcEncTop;
127  m_pcListPic         = pcEncTop->getListPic();
128 
129  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
130  m_pcCuEncoder       = pcEncTop->getCuEncoder();
131  m_pcPredSearch      = pcEncTop->getPredSearch();
132 
133  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
134  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
135  m_pcSbacCoder       = pcEncTop->getSbacCoder();
136  m_pcBinCABAC        = pcEncTop->getBinCABAC();
137  m_pcTrQuant         = pcEncTop->getTrQuant();
138 
139  m_pcBitCounter      = pcEncTop->getBitCounter();
140  m_pcRdCost          = pcEncTop->getRdCost();
141  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
142  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
143 
144  // create lambda and QP arrays
145  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
146  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
147  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
148}
149
150/**
151 - non-referenced frame marking
152 - QP computation based on temporal structure
153 - lambda computation based on QP
154 - set temporal layer ID and the parameter sets
155 .
156 \param pcPic         picture class
157 \param iPOCLast      POC of last picture
158 \param uiPOCCurr     current POC
159 \param iNumPicRcvd   number of received pictures
160 \param iTimeOffset   POC offset for hierarchical structure
161 \param iDepth        temporal layer depth
162 \param rpcSlice      slice header class
163 \param pSPS          SPS associated with the slice
164 \param pPPS          PPS associated with the slice
165 */
166#if VIDYO_VPS_INTEGRATION
167Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS * pVPS, TComSPS* pSPS, TComPPS *pPPS )
168#else
169Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
170#endif
171{
172  Double dQP;
173  Double dLambda;
174 
175  rpcSlice = pcPic->getSlice(0);
176#if VIDYO_VPS_INTEGRATION
177  rpcSlice->setVPS( pVPS );
178#endif
179  rpcSlice->setSPS( pSPS );
180  rpcSlice->setPPS( pPPS );
181  rpcSlice->setSliceBits(0);
182  rpcSlice->setPic( pcPic );
183  rpcSlice->initSlice();
184  rpcSlice->initTiles();
185#if H0388
186  rpcSlice->setPicOutputFlag( true );
187#endif
188  rpcSlice->setPOC( uiPOCCurr );
189 
190#if SONY_COLPIC_AVAILABILITY
191  rpcSlice->setViewOrderIdx(m_pcCfg->getViewOrderIdx());
192#endif
193
194  // set mutliview parameters
195  rpcSlice->initMultiviewSlice( pcPic->getCodedScale(), pcPic->getCodedOffset() );
196
197  // depth computation based on GOP size
198  int iDepth;
199  {
200    Int i, j;
201    Int iPOC = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
202    if ( iPOC == 0 )
203    {
204      iDepth = 0;
205    }
206    else
207    {
208      Int iStep = m_pcCfg->getGOPSize();
209      iDepth    = 0;
210      for( i=iStep>>1; i>=1; i>>=1 )
211      {
212        for ( j=i; j<m_pcCfg->getGOPSize(); j+=iStep )
213        {
214          if ( j == iPOC )
215          {
216            i=0;
217            break;
218          }
219        }
220        iStep>>=1;
221        iDepth++;
222      }
223    }
224  }
225 
226  // slice type
227  SliceType eSliceTypeBaseView;
228  if( iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 )
229  {
230    eSliceTypeBaseView = I_SLICE;
231  }
232  else
233  {
234    eSliceTypeBaseView = B_SLICE;
235  }
236  SliceType eSliceType = eSliceTypeBaseView;
237  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
238  {
239    eSliceType = B_SLICE; 
240  }
241  rpcSlice->setSliceType( eSliceType );
242 
243  // ------------------------------------------------------------------------------------------------------------------
244  // Non-referenced frame marking
245  // ------------------------------------------------------------------------------------------------------------------
246  rpcSlice->setReferenced( m_pcCfg->getGOPEntry(iGOPid).m_refPic );
247  if( eSliceTypeBaseView == I_SLICE )
248  {
249    rpcSlice->setReferenced(true);
250  }
251 
252  // ------------------------------------------------------------------------------------------------------------------
253  // QP setting
254  // ------------------------------------------------------------------------------------------------------------------
255 
256  dQP = m_pcCfg->getQP();
257  if( eSliceType != I_SLICE )
258  {
259#if LOSSLESS_CODING
260#if H0736_AVC_STYLE_QP_RANGE
261    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
262#else
263    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == 0 ) && (rpcSlice->getSPS()->getUseLossless())))
264#endif
265#endif
266    {
267    dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
268    }
269  }
270 
271  // modify QP
272  Int* pdQPs = m_pcCfg->getdQPs();
273  if ( pdQPs )
274  {
275    dQP += pdQPs[ rpcSlice->getPOC() ];
276  }
277 
278  // ------------------------------------------------------------------------------------------------------------------
279  // Lambda computation
280  // ------------------------------------------------------------------------------------------------------------------
281 
282  Int iQP;
283  Double dOrigQP = dQP;
284
285  // pre-compute lambda and QP values for all possible QP candidates
286  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
287  {
288    // compute QP value
289    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
290   
291    // compute lambda value
292    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
293    Int    SHIFT_QP = 12;
294    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
295#if FULL_NBIT
296    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
297#else
298    Int    bitdepth_luma_qp_scale = 0;
299#endif
300    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
301#if FULL_NBIT
302    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
303#endif
304    // Case #1: I or P-slices (key-frame)
305    Double dQPFactor;
306    if( eSliceType != I_SLICE ) 
307    {
308      dQPFactor = m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPFactor;
309    }
310    else
311    {
312      dQPFactor = 0.57 * dLambda_scale;
313    }
314
315    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
316
317    if ( iDepth>0 )
318    {
319#if FULL_NBIT
320        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
321#else
322        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
323#endif
324    }
325   
326    // if hadamard is used in ME process
327    if ( !m_pcCfg->getUseHADME() )
328    {
329      dLambda *= 0.95;
330    }
331   
332#if H0736_AVC_STYLE_QP_RANGE
333    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
334#else
335    iQP = max( MIN_QP, min( MAX_QP, (Int)floor( dQP + 0.5 ) ) );
336#endif
337
338    m_pdRdPicLambda[iDQpIdx] = dLambda;
339    m_pdRdPicQp    [iDQpIdx] = dQP;
340    m_piRdPicQp    [iDQpIdx] = iQP;
341  }
342 
343  // obtain dQP = 0 case
344  dLambda = m_pdRdPicLambda[0];
345  dQP     = m_pdRdPicQp    [0];
346  iQP     = m_piRdPicQp    [0];
347 
348  if( rpcSlice->getSliceType( ) != I_SLICE )
349  {
350    dLambda *= m_pcCfg->getLambdaModifier( iDepth );
351  }
352
353  // store lambda
354  m_pcRdCost ->setLambda( dLambda );
355#if WEIGHTED_CHROMA_DISTORTION
356// for RDO
357  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
358#if H0736_AVC_STYLE_QP_RANGE
359  Double weight = 1.0;
360  if(iQP >= 0)
361  {
362    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
363  }
364#else
365  Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
366#endif
367  m_pcRdCost ->setChromaDistortionWeight( weight );     
368#endif
369
370#if HHI_VSO
371  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->isDepthCoder()  );
372  m_pcRdCost->setLambdaVSO( dLambda * m_pcCfg->getLambdaScaleVSO() );
373#endif
374
375#if SAIT_VSO_EST_A0033
376  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
377#endif
378#if LGE_WVSO_A0119
379  if( m_pcCfg->getUseWVSO() && m_pcCfg->isDepthCoder() )
380  {
381
382    Int iDWeight, iVSOWeight, iVSDWeight;
383    iDWeight = m_pcCfg->getDWeight();
384    iVSOWeight = m_pcCfg->getVSOWeight();
385    iVSDWeight = m_pcCfg->getVSDWeight();
386
387    m_pcRdCost->setDWeight( iDWeight );
388    m_pcRdCost->setVSOWeight( iVSOWeight );
389    m_pcRdCost->setVSDWeight( iVSDWeight );
390
391  }
392#endif
393#if RDOQ_CHROMA_LAMBDA
394// for RDOQ
395  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
396#else
397  m_pcTrQuant->setLambda( dLambda );
398#endif
399
400#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
401// For ALF or SAO
402  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
403#else
404  rpcSlice   ->setLambda( dLambda );
405#endif
406 
407#if HHI_INTER_VIEW_MOTION_PRED
408  m_pcRdCost ->setLambdaMVReg ( dLambda * m_pcCfg->getMultiviewMvRegLambdaScale() );
409#endif
410 
411#if HB_LAMBDA_FOR_LDC
412  // restore original slice type
413  eSliceType = eSliceTypeBaseView;
414  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
415  {
416    eSliceType = B_SLICE;
417  }
418  rpcSlice->setSliceType( eSliceType );
419#endif
420 
421  rpcSlice->setSliceQp          ( iQP );
422#if ADAPTIVE_QP_SELECTION
423  rpcSlice->setSliceQpBase      ( iQP );
424#endif
425  rpcSlice->setSliceQpDelta     ( 0 );
426  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
427  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
428 
429  rpcSlice->setLoopFilterOffsetInAPS( m_pcCfg->getLoopFilterOffsetInAPS() );
430#if DBL_CONTROL
431  if (rpcSlice->getPPS()->getDeblockingFilterControlPresent())
432  {
433#endif
434    rpcSlice->setInheritDblParamFromAPS( m_pcCfg->getLoopFilterOffsetInAPS() ? 1 : 0 );
435    rpcSlice->setLoopFilterDisable( m_pcCfg->getLoopFilterDisable() );
436    if ( !rpcSlice->getLoopFilterDisable())
437    {
438      rpcSlice->setLoopFilterBetaOffset( m_pcCfg->getLoopFilterBetaOffset() );
439      rpcSlice->setLoopFilterTcOffset( m_pcCfg->getLoopFilterTcOffset() );
440    }
441#if DBL_CONTROL
442  }
443#endif
444
445  rpcSlice->setDepth            ( iDepth );
446 
447  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
448  if( eSliceType == I_SLICE )
449  {
450    pcPic->setTLayer(0);
451  }
452  rpcSlice->setTLayer( pcPic->getTLayer() );
453#if !H0566_TLA
454  rpcSlice->setTLayerSwitchingFlag( pPPS->getTLayerSwitchingFlag( pcPic->getTLayer() ) );
455#endif
456
457  assert( m_apcPicYuvPred );
458  assert( m_apcPicYuvResi );
459 
460  pcPic->setPicYuvPred( m_apcPicYuvPred );
461  pcPic->setPicYuvResi( m_apcPicYuvResi );
462  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
463  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
464  rpcSlice->setEntropySliceMode     ( m_pcCfg->getEntropySliceMode()     );
465  rpcSlice->setEntropySliceArgument ( m_pcCfg->getEntropySliceArgument() );
466
467#if ( HHI_MPI || HHI_INTER_VIEW_MOTION_PRED )
468  #if ( HHI_MPI && HHI_INTER_VIEW_MOTION_PRED )
469  const int iExtraMergeCandidates = ( pSPS->getUseMVI() || pSPS->getMultiviewMvPredMode() ) ? 1 : 0;
470  #elif HHI_MPI
471  const int iExtraMergeCandidates = pSPS->getUseMVI() ? 1 : 0;
472  #else
473  const int iExtraMergeCandidates = pSPS->getMultiviewMvPredMode() ? 1 : 0;
474  #endif
475  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED+iExtraMergeCandidates);
476#else
477  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED);
478#endif
479  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPredIdc() );
480}
481
482// ====================================================================================================================
483// Public member functions
484// ====================================================================================================================
485
486Void TEncSlice::setSearchRange( TComSlice* pcSlice )
487{
488  Int iCurrPOC = pcSlice->getPOC();
489  Int iRefPOC;
490  Int iGOPSize = m_pcCfg->getGOPSize();
491  Int iOffset = (iGOPSize >> 1);
492  Int iMaxSR = m_pcCfg->getSearchRange();
493  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
494 
495  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
496  {
497    RefPicList e = (RefPicList)iDir;
498    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
499    {
500      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
501      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
502      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
503    }
504  }
505}
506
507/**
508 - multi-loop slice encoding for different slice QP
509 .
510 \param rpcPic    picture class
511 */
512Void TEncSlice::precompressSlice( TComPic*& rpcPic )
513{
514  // if deltaQP RD is not used, simply return
515  if ( m_pcCfg->getDeltaQpRD() == 0 )
516  {
517    return;
518  }
519 
520  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
521  Double     dPicRdCostBest = MAX_DOUBLE;
522  UInt       uiQpIdxBest = 0;
523 
524  Double dFrameLambda;
525#if FULL_NBIT
526  Int    SHIFT_QP = 12 + 6 * (g_uiBitDepth - 8);
527#else
528  Int    SHIFT_QP = 12;
529#endif
530 
531  // set frame lambda
532  if (m_pcCfg->getGOPSize() > 1)
533  {
534    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
535  }
536  else
537  {
538    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
539  }
540  m_pcRdCost      ->setFrameLambda(dFrameLambda);
541 
542  // for each QP candidate
543  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
544  {
545    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
546#if ADAPTIVE_QP_SELECTION
547    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
548#endif
549    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
550#if WEIGHTED_CHROMA_DISTORTION
551    // for RDO
552    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
553    int iQP = m_piRdPicQp    [uiQpIdx];
554#if H0736_AVC_STYLE_QP_RANGE
555    Double weight = 1.0;
556    if(iQP >= 0)
557    {
558      weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
559    }
560#else
561    Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
562#endif
563    m_pcRdCost    ->setChromaDistortionWeight( weight );     
564#endif
565
566#if RDOQ_CHROMA_LAMBDA
567    // for RDOQ
568    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
569#else
570    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
571#endif
572#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
573    // For ALF or SAO
574    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
575#else
576    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
577#endif
578#if HHI_INTER_VIEW_MOTION_PRED
579    m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdx] * m_pcCfg->getMultiviewMvRegLambdaScale() );
580#endif
581   
582    // try compress
583    compressSlice   ( rpcPic );
584   
585    Double dPicRdCost;
586    UInt64 uiPicDist        = m_uiPicDist;
587    UInt64 uiALFBits        = 0;
588   
589    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
590   
591    // compute RD cost and choose the best
592    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
593   
594    if ( dPicRdCost < dPicRdCostBest )
595    {
596      uiQpIdxBest    = uiQpIdx;
597      dPicRdCostBest = dPicRdCost;
598    }
599  }
600 
601  // set best values
602  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
603#if ADAPTIVE_QP_SELECTION
604  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
605#endif
606  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
607#if WEIGHTED_CHROMA_DISTORTION
608  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
609  int iQP = m_piRdPicQp    [uiQpIdxBest];
610#if H0736_AVC_STYLE_QP_RANGE
611  Double weight = 1.0;
612  if(iQP >= 0)
613  {
614    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
615  }
616#else
617  Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
618#endif
619  m_pcRdCost ->setChromaDistortionWeight( weight );     
620#endif
621
622#if RDOQ_CHROMA_LAMBDA
623  // for RDOQ
624  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
625#else
626  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
627#endif
628#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
629  // For ALF or SAO
630  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
631#else
632  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
633#endif
634#if HHI_INTER_VIEW_MOTION_PRED
635  m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdxBest] * m_pcCfg->getMultiviewMvRegLambdaScale() );
636#endif
637}
638
639/** \param rpcPic   picture class
640 */
641Void TEncSlice::compressSlice( TComPic*& rpcPic )
642{
643  UInt  uiCUAddr;
644  UInt   uiStartCUAddr;
645  UInt   uiBoundingCUAddr;
646  rpcPic->getSlice(getSliceIdx())->setEntropySliceCounter(0);
647  TEncBinCABAC* pppcRDSbacCoder = NULL;
648  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
649  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
650#if LG_ZEROINTRADEPTHRESI_M26039
651  rpcPic->setIntraPeriod(this->m_pcCfg->getIntraPeriod());
652#endif
653 
654  // initialize cost values
655  m_uiPicTotalBits  = 0;
656  m_dPicRdCost      = 0;
657  m_uiPicDist       = 0;
658 
659#if CABAC_INIT_FLAG && POZNAN_CABAC_INIT_FLAG_FIX
660  Bool bReset =(pcSlice->getPOC() == 0) || 
661    (pcSlice->getPOC() % m_pcCfg->getIntraPeriod() == 0) ||
662    (pcSlice->getPPS()->getEncPrevPOC() % m_pcCfg->getIntraPeriod() == 0) ||
663    (pcSlice->getPOC()/m_pcCfg->getIntraPeriod() > pcSlice->getPPS()->getEncPrevPOC()/m_pcCfg->getIntraPeriod()) ||
664    (m_pcGOPEncoder->getGOPSize() == 0);
665
666  if ( bReset && pcSlice->getPPS()->getCabacInitPresentFlag())
667  {
668    pcSlice->getPPS()->setEncCABACTableIdx(pcSlice->getSliceType()); // reset cabac initialization table index
669  };
670#endif
671
672  // set entropy coder
673  if( m_pcCfg->getUseSBACRD() )
674  {
675    m_pcSbacCoder->init( m_pcBinCABAC );
676    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
677    m_pcEntropyCoder->resetEntropy      ();
678    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
679    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
680    pppcRDSbacCoder->setBinCountingEnableFlag( false );
681    pppcRDSbacCoder->setBinsCoded( 0 );
682  }
683  else
684  {
685    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
686    m_pcEntropyCoder->resetEntropy      ();
687    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
688  }
689 
690  //------------------------------------------------------------------------------
691  //  Weighted Prediction parameters estimation.
692  //------------------------------------------------------------------------------
693  // calculate AC/DC values for current picture
694  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPredIdc() )
695  {
696    xCalcACDCParamSlice(pcSlice);
697  }
698
699  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==1);
700  Bool bWp_implicit = (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==2);
701
702  if ( bWp_explicit || bWp_implicit )
703  {
704    //------------------------------------------------------------------------------
705    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
706    //------------------------------------------------------------------------------
707    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
708    {
709      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
710    }
711
712    if( bWp_explicit )
713    {
714      xEstimateWPParamSlice( pcSlice );
715    }
716   
717    pcSlice->initWpScaling();
718
719    // check WP on/off
720    if( bWp_explicit )
721    {
722      xCheckWPEnable( pcSlice );
723    }
724  }
725
726#if ADAPTIVE_QP_SELECTION
727  if( m_pcCfg->getUseAdaptQpSelect() )
728  {
729    m_pcTrQuant->clearSliceARLCnt();
730    if(pcSlice->getSliceType()!=I_SLICE)
731    {
732      Int qpBase = pcSlice->getSliceQpBase();
733      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
734    }
735  }
736#endif
737  // initialize ALF parameters
738  m_pcEntropyCoder->setAlfCtrl(false);
739  m_pcEntropyCoder->setMaxAlfCtrlDepth(0); //unnecessary
740 
741#if SAIT_VSO_EST_A0033
742 if( m_pcCfg->getUseVSO() )
743 {
744
745   Int frameWidth = m_pcCfg->getSourceWidth();
746   Pel* pVideoRec = m_pcRdCost->getVideoRecPicYuv()->getLumaAddr();
747   Int iVideoRecStride = m_pcRdCost->getVideoRecPicYuv()->getStride();
748
749   Pel* pDepthOrg = m_pcRdCost->getDepthPicYuv()->getLumaAddr();
750   Int iDepthOrgStride = m_pcRdCost->getDepthPicYuv()->getStride();
751
752   for( Int y = 0 ; y < m_pcCfg->getSourceHeight() ; y++ )
753   {
754     pVideoRec[-1] = pVideoRec[0];
755     pVideoRec[frameWidth] = pVideoRec[frameWidth-1];
756     pDepthOrg[-1] = pDepthOrg[0];
757     pDepthOrg[frameWidth] = pDepthOrg[frameWidth-1];
758
759     pVideoRec += iVideoRecStride;
760     pDepthOrg += iDepthOrgStride;
761   }
762 }
763#endif
764
765  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
766  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
767  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
768  Int  iNumSubstreams = 1;
769  UInt uiTilesAcross  = 0;
770
771  if( m_pcCfg->getUseSBACRD() )
772  {
773    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
774    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
775    delete[] m_pcBufferSbacCoders;
776    delete[] m_pcBufferBinCoderCABACs;
777    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
778    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
779    for (int ui = 0; ui < uiTilesAcross; ui++)
780    {
781      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
782    }
783    for (UInt ui = 0; ui < uiTilesAcross; ui++)
784    {
785      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
786    }
787
788    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
789    {
790      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
791    }
792  }
793  //if( m_pcCfg->getUseSBACRD() )
794  {
795    delete[] m_pcBufferLowLatSbacCoders;
796    delete[] m_pcBufferLowLatBinCoderCABACs;
797    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
798    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
799    for (int ui = 0; ui < uiTilesAcross; ui++)
800    {
801      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
802    }
803    for (UInt ui = 0; ui < uiTilesAcross; ui++)
804      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
805  }
806  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
807  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
808  UInt uiCol=0, uiLin=0, uiSubStrm=0;
809#if !REMOVE_TILE_DEPENDENCE
810  Int  iBreakDep      = 0;
811#endif
812  UInt uiTileCol      = 0;
813  UInt uiTileStartLCU = 0;
814  UInt uiTileLCUX     = 0;
815
816#if HHI_VSO_SPEEDUP_A0033
817  Int iLastPosY = -1;
818#endif
819
820  // for every CU in slice
821  UInt uiEncCUOrder;
822  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
823  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
824       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
825       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
826  {
827    // initialize CU encoder
828    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
829    pcCU->initCU( rpcPic, uiCUAddr );
830
831#if HHI_VSO_SPEEDUP_A0033
832    if ( m_pcRdCost->getUseRenModel() )
833    {
834      // updated renderer model if necessary
835      Int iCurPosX;
836      Int iCurPosY; 
837      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
838      if ( iCurPosY != iLastPosY )
839      {
840        iLastPosY = iCurPosY; 
841       
842        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
843      }
844    }   
845#endif
846
847#if OL_DEPTHLIMIT_A0044 //stop dumping partition information
848    m_bDumpPartInfo = 0;
849    pcCU->setPartDumpFlag(m_bDumpPartInfo);
850#endif
851
852    // inherit from TR if necessary, select substream to use.
853    if( m_pcCfg->getUseSBACRD() )
854    {
855#if !REMOVE_TILE_DEPENDENCE
856      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
857#endif
858      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
859      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
860      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
861      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
862      uiCol     = uiCUAddr % uiWidthInLCUs;
863      uiLin     = uiCUAddr / uiWidthInLCUs;
864#if !REMOVE_TILE_DEPENDENCE
865#if WPP_SIMPLIFICATION
866      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
867#else
868      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
869#endif
870#else
871#if WPP_SIMPLIFICATION
872      if (pcSlice->getPPS()->getNumSubstreams() > 1)
873#else
874      if (pcSlice->getPPS()->getEntropyCodingSynchro())
875#endif
876#endif
877      {
878        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
879        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
880        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
881                      + uiLin%iNumSubstreamsPerTile;
882      }
883      else
884      {
885        // dependent tiles => substreams are "per frame".
886        uiSubStrm = uiLin % iNumSubstreams;
887      }
888#if WPP_SIMPLIFICATION
889      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
890#else
891      if ( pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX) )
892#endif
893      {
894        // We'll sync if the TR is available.
895        TComDataCU *pcCUUp = pcCU->getCUAbove();
896        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
897        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
898        TComDataCU *pcCUTR = NULL;
899#if WPP_SIMPLIFICATION
900        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
901        {
902          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
903        }
904#else
905        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
906        {
907          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
908        }
909#endif
910        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
911             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
912#if !REMOVE_TILE_DEPENDENCE
913             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
914#else
915             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
916#endif
917             )||
918             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
919             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
920#if !REMOVE_TILE_DEPENDENCE
921             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
922#else
923             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
924#endif
925             )
926           )
927        {
928          // TR not available.
929        }
930        else
931        {
932          // TR is available, we use it.
933          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
934        }
935      }
936      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
937    }
938
939    // reset the entropy coder
940    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
941        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
942        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
943    {
944#if CABAC_INIT_FLAG
945      SliceType sliceType = pcSlice->getSliceType();
946      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
947      {
948        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
949      }
950      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
951      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
952      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
953      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
954#else
955      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
956      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
957      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
958      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
959#endif
960    }
961#if !REMOVE_TILE_DEPENDENCE
962    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
963    {
964      // Synchronize cabac probabilities with LCU among Tiles
965      if( (uiTileLCUX != 0) &&
966          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
967      { 
968        TComDataCU *pcCULeft = pcCU->getCULeft();
969        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
970
971        if ( (true/*bEnforceSliceRestriction*/ &&
972              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
973               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
974              )
975             )||
976             (true/*bEnforceEntropySliceRestriction*/ &&
977              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
978               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
979              )
980             )
981           )
982        {
983          // Left not available.
984        }
985        else
986        {
987          // Left is available, we use it.
988          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
989          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
990        }
991      }
992    }
993#endif
994    // if RD based on SBAC is used
995    if( m_pcCfg->getUseSBACRD() )
996    {
997      // set go-on entropy coder
998      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
999      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1000     
1001      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1002      // run CU encoder
1003      m_pcCuEncoder->compressCU( pcCU );
1004     
1005      // restore entropy coder to an initial stage
1006      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1007      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1008      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1009      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1010      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1011      m_pcBitCounter->resetBits();
1012      pppcRDSbacCoder->setBinsCoded( 0 );
1013      m_pcCuEncoder->encodeCU( pcCU );
1014
1015      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1016      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1017      {
1018        pcSlice->setNextSlice( true );
1019        break;
1020      }
1021      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1022      {
1023        pcSlice->setNextEntropySlice( true );
1024        break;
1025      }
1026      if( m_pcCfg->getUseSBACRD() )
1027      {
1028         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1029       
1030         //Store probabilties of second LCU in line into buffer
1031#if WPP_SIMPLIFICATION
1032        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
1033#else
1034        if (pcSlice->getPPS()->getEntropyCodingSynchro() && uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro())
1035#endif
1036        {
1037          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1038        }
1039      }
1040#if !REMOVE_TILE_DEPENDENCE
1041      if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1042      {
1043         //Store probabilties for next tile
1044        if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1045            (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1046        {
1047          m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1048        }
1049      }
1050#endif
1051    }
1052    // other case: encodeCU is not called
1053    else
1054    {
1055      m_pcCuEncoder->compressCU( pcCU );
1056      m_pcCuEncoder->encodeCU( pcCU );
1057      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1058      {
1059        pcSlice->setNextSlice( true );
1060        break;
1061      }
1062      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
1063      {
1064        pcSlice->setNextEntropySlice( true );
1065        break;
1066      }
1067    }
1068   
1069    m_uiPicTotalBits += pcCU->getTotalBits();
1070    m_dPicRdCost     += pcCU->getTotalCost();
1071    m_uiPicDist      += pcCU->getTotalDistortion();
1072  }
1073  xRestoreWPparam( pcSlice );
1074}
1075
1076/**
1077 \param  rpcPic        picture class
1078 \retval rpcBitstream  bitstream class
1079 */
1080Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
1081{
1082  UInt       uiCUAddr;
1083  UInt       uiStartCUAddr;
1084  UInt       uiBoundingCUAddr;
1085  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1086
1087  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1088  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
1089  // choose entropy coder
1090  {
1091    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1092    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1093  }
1094 
1095  m_pcCuEncoder->setBitCounter( NULL );
1096  m_pcBitCounter = NULL;
1097  // Appropriate substream bitstream is switched later.
1098  // for every CU
1099#if ENC_DEC_TRACE
1100  g_bJustDoIt = g_bEncDecTraceEnable;
1101#endif
1102  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1103  DTRACE_CABAC_T( "\tPOC: " );
1104  DTRACE_CABAC_V( rpcPic->getPOC() );
1105  DTRACE_CABAC_T( "\n" );
1106#if ENC_DEC_TRACE
1107  g_bJustDoIt = g_bEncDecTraceDisable;
1108#endif
1109
1110  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1111  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1112  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1113  UInt uiBitsOriginallyInSubstreams = 0;
1114  {
1115    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1116    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1117    {
1118      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1119    }
1120   
1121    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1122    {
1123      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1124    }
1125
1126    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1127    {
1128      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1129    }
1130  }
1131
1132  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1133  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1134#if !REMOVE_TILE_DEPENDENCE
1135  Int  iBreakDep      = 0;
1136#endif
1137  UInt uiTileCol      = 0;
1138  UInt uiTileStartLCU = 0;
1139  UInt uiTileLCUX     = 0;
1140
1141  UInt uiEncCUOrder;
1142  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1143                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1144                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1145  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1146       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1147       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1148  {
1149    if( m_pcCfg->getUseSBACRD() )
1150    {
1151#if !REMOVE_TILE_DEPENDENCE
1152      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
1153#endif
1154      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1155      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1156      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1157      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1158      uiCol     = uiCUAddr % uiWidthInLCUs;
1159      uiLin     = uiCUAddr / uiWidthInLCUs;
1160#if !REMOVE_TILE_DEPENDENCE
1161#if WPP_SIMPLIFICATION
1162      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
1163#else
1164      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
1165#endif
1166#else
1167#if WPP_SIMPLIFICATION
1168      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1169#else
1170      if (pcSlice->getPPS()->getEntropyCodingSynchro())
1171#endif
1172#endif
1173      {
1174        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1175        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1176        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1177                      + uiLin%iNumSubstreamsPerTile;
1178      }
1179      else
1180      {
1181        // dependent tiles => substreams are "per frame".
1182        uiSubStrm = uiLin % iNumSubstreams;
1183      }
1184
1185      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1186
1187      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1188#if WPP_SIMPLIFICATION
1189      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1190#else
1191      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX))
1192#endif
1193      {
1194        // We'll sync if the TR is available.
1195        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1196        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1197        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1198        TComDataCU *pcCUTR = NULL;
1199#if WPP_SIMPLIFICATION
1200        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1201        {
1202          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1203        }
1204#else
1205        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
1206        {
1207          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
1208        }
1209#endif
1210        if ( (true/*bEnforceSliceRestriction*/ &&
1211             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1212             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1213#if !REMOVE_TILE_DEPENDENCE
1214             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1215#else
1216             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1217#endif
1218             ))||
1219             (true/*bEnforceEntropySliceRestriction*/ &&
1220             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1221             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1222#if !REMOVE_TILE_DEPENDENCE
1223             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1224#else
1225             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1226#endif
1227             ))
1228           )
1229        {
1230          // TR not available.
1231        }
1232        else
1233        {
1234          // TR is available, we use it.
1235          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1236        }
1237      }
1238      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1239    }
1240    // reset the entropy coder
1241    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1242        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1243        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1244    {
1245      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1246      Bool bWriteTileMarker   = false;
1247      // check if current iTileIdx should have a marker
1248      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1249      {
1250        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1251        if (bWriteTileMarker)
1252        {
1253          break;
1254        }
1255      }
1256      {
1257        // We're crossing into another tile, tiles are independent.
1258        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1259        // have to perform it here.
1260#if WPP_SIMPLIFICATION
1261        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1262#else
1263        if (pcSlice->getPPS()->getEntropyCodingSynchro())
1264#endif
1265        {
1266          ; // do nothing.
1267        }
1268        else
1269        {
1270#if CABAC_INIT_FLAG
1271          SliceType sliceType  = pcSlice->getSliceType();
1272          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1273          {
1274            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1275          }
1276          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1277#else
1278          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1279#endif
1280          pcSubstreams[uiSubStrm].write( 1, 1 );
1281          pcSubstreams[uiSubStrm].writeAlignZero();
1282        }
1283      }
1284      {
1285        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1286        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1287        {
1288          // Log locations where tile markers are to be inserted during emulation prevention
1289          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1290          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1291          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1292          // Write tile index
1293          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1294        }
1295
1296       
1297        UInt uiAccumulatedSubstreamLength = 0;
1298        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1299        {
1300          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1301        }
1302        UInt uiLocationCount = pcSlice->getTileLocationCount();
1303        // add bits coded in previous entropy slices + bits coded so far
1304        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1305        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1306      }
1307    }
1308
1309    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1310#if OL_DEPTHLIMIT_A0044
1311    pcCU->setPartDumpFlag(m_bDumpPartInfo);
1312    pcCU->resetPartInfo();
1313#endif
1314#if !REMOVE_TILE_DEPENDENCE
1315    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1316    {   
1317      // Synchronize cabac probabilities with LCU among Tiles
1318      if( (uiTileLCUX != 0) &&
1319          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
1320      {
1321        TComDataCU *pcCULeft = pcCU->getCULeft();
1322        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1323
1324        if ( (true/*bEnforceSliceRestriction*/ &&
1325              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1326               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
1327              )
1328             )||
1329             (true/*bEnforceEntropySliceRestriction*/ &&
1330              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1331               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
1332              )
1333             )
1334           )
1335        {
1336          // Left not available.
1337        }
1338        else
1339        {
1340          // Left is available, we use it.
1341          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
1342          m_pcSbacCoder->loadContexts(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1343        }
1344      }
1345    }
1346#endif
1347
1348#if SAO_UNIT_INTERLEAVING
1349    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1350    {
1351      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1352      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1353      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1354      Int rx = uiCUAddr % iNumCuInWidth;
1355      Int ry = uiCUAddr / iNumCuInWidth;
1356      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1357    }
1358#endif
1359#if ENC_DEC_TRACE
1360    g_bJustDoIt = g_bEncDecTraceEnable;
1361#endif
1362    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1363      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1364    {
1365      m_pcCuEncoder->encodeCU( pcCU, true );
1366    }
1367    else
1368    {
1369      m_pcCuEncoder->encodeCU( pcCU );
1370    }
1371#if ENC_DEC_TRACE
1372    g_bJustDoIt = g_bEncDecTraceDisable;
1373#endif   
1374    if( m_pcCfg->getUseSBACRD() )
1375    {
1376       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1377       
1378
1379       //Store probabilties of second LCU in line into buffer
1380#if WPP_SIMPLIFICATION
1381      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1382#else
1383      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro()))
1384#endif
1385      {
1386        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1387      }
1388    }
1389#if !REMOVE_TILE_DEPENDENCE
1390    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1391    {
1392      pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1393       //Store probabilties for next tile
1394      if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1395          (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1396      {
1397        m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1398      }
1399    }
1400#endif
1401  }
1402
1403#if ADAPTIVE_QP_SELECTION
1404  if( m_pcCfg->getUseAdaptQpSelect() )
1405  {
1406    m_pcTrQuant->storeSliceQpNext(pcSlice);
1407  }
1408#endif
1409#if CABAC_INIT_FLAG
1410  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1411  {
1412    m_pcEntropyCoder->determineCabacInitIdx();
1413  }
1414#endif
1415}
1416
1417/** Determines the starting and bounding LCU address of current slice / entropy slice
1418 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1419 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1420 */
1421Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1422{
1423  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1424  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1425#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1426  UInt tileIdxIncrement;
1427  UInt tileIdx;
1428  UInt tileWidthInLcu;
1429  UInt tileHeightInLcu;
1430  UInt tileTotalCount;
1431#endif
1432
1433  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1434  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1435  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1436  if (bEncodeSlice) 
1437  {
1438    UInt uiCUAddrIncrement;
1439    switch (m_pcCfg->getSliceMode())
1440    {
1441    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1442      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1443      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1444      break;
1445    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1446      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1447      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1448      break;
1449#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1450    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1451      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1452        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1453        );
1454      uiCUAddrIncrement        = 0;
1455      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1456
1457      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1458      {
1459        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1460        {
1461          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1462          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1463          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1464        }
1465      }
1466
1467      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1468      break;
1469#endif
1470    default:
1471      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1472      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1473      break;
1474    } 
1475    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1476  }
1477  else
1478  {
1479    UInt uiCUAddrIncrement     ;
1480    switch (m_pcCfg->getSliceMode())
1481    {
1482    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1483      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1484      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1485      break;
1486#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1487    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1488      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1489        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1490        );
1491      uiCUAddrIncrement        = 0;
1492      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1493
1494      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1495      {
1496        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1497        {
1498          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1499          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1500          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1501        }
1502      }
1503
1504      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1505      break;
1506#endif
1507    default:
1508      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1509      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1510      break;
1511    } 
1512    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1513  }
1514
1515#if COMPLETE_SLICES_IN_TILE
1516  Bool tileBoundary = false;
1517  if ((m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE || m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE) && 
1518      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1519  {
1520    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1521    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1522    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1523    UInt tileBoundingCUAddrSlice = 0;
1524    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1525    {
1526      lcuEncAddr++;
1527      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1528    }
1529    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1530   
1531    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1532    {
1533      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1534      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1535      tileBoundary = true;
1536    }
1537  }
1538#endif
1539
1540  // Entropy slice
1541  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1542  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1543  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
1544  if (bEncodeSlice) 
1545  {
1546    UInt uiCUAddrIncrement;
1547    switch (m_pcCfg->getEntropySliceMode())
1548    {
1549    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1550      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1551      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1552      break;
1553    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1554      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1555      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1556      break;
1557    default:
1558      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1559      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1560      break;
1561    } 
1562    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1563  }
1564  else
1565  {
1566    UInt uiCUAddrIncrement;
1567    switch (m_pcCfg->getEntropySliceMode())
1568    {
1569    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1570      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
1571      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1572      break;
1573    default:
1574      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1575      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1576      break;
1577    } 
1578    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1579  }
1580  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1581  {
1582    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1583    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1584  }
1585  //calculate real entropy slice start address
1586  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1587  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1588  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1589  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1590  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1591  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1592  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1593  {
1594    uiInternalAddress++;
1595    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1596    {
1597      uiInternalAddress=0;
1598      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1599    }
1600    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1601    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1602  }
1603  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1604 
1605  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1606  uiStartCUAddrEntropySlice=uiRealStartAddress;
1607 
1608  //calculate real slice start address
1609  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1610  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1611  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1612  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1613  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1614  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1615  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1616  {
1617    uiInternalAddress++;
1618    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1619    {
1620      uiInternalAddress=0;
1621      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1622    }
1623    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1624    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1625  }
1626  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1627 
1628  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1629  uiStartCUAddrSlice=uiRealStartAddress;
1630 
1631  // Make a joint decision based on reconstruction and entropy slice bounds
1632  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1633  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1634
1635
1636  if (!bEncodeSlice)
1637  {
1638    // 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
1639    // first. Set the flags accordingly.
1640    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1641      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1642      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1643#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1644      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1645      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1646#endif
1647#if COMPLETE_SLICES_IN_TILE
1648      || tileBoundary
1649#endif
1650)
1651    {
1652      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1653      {
1654        pcSlice->setNextSlice       ( true );
1655        pcSlice->setNextEntropySlice( false );
1656      }
1657      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1658      {
1659        pcSlice->setNextSlice       ( false );
1660        pcSlice->setNextEntropySlice( true );
1661      }
1662      else
1663      {
1664        pcSlice->setNextSlice       ( true );
1665        pcSlice->setNextEntropySlice( true );
1666      }
1667    }
1668    else
1669    {
1670      pcSlice->setNextSlice       ( false );
1671      pcSlice->setNextEntropySlice( false );
1672    }
1673  }
1674}
1675//! \}
Note: See TracBrowser for help on using the repository browser.