source: 3DVCSoftware/branches/HTM-5.1-dev0-MERL-Mediatek-Fix/source/Lib/TLibEncoder/TEncSlice.cpp

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

Integration of branch dev 2.

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