source: SHVCSoftware/branches/SHM-5.0-dev/source/Lib/TLibEncoder/TEncCu.cpp @ 550

Last change on this file since 550 was 540, checked in by seregin, 11 years ago

merge SHM-4.1-dev branch

  • Property svn:eol-style set to native
File size: 71.7 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-2013, 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     TEncCu.cpp
35    \brief    Coding Unit (CU) encoder class
36*/
37
38#include <stdio.h>
39#include "TEncTop.h"
40#include "TEncCu.h"
41#include "TEncAnalyze.h"
42
43#include <cmath>
44#include <algorithm>
45using namespace std;
46
47//! \ingroup TLibEncoder
48//! \{
49
50// ====================================================================================================================
51// Constructor / destructor / create / destroy
52// ====================================================================================================================
53
54/**
55 \param    uiTotalDepth  total number of allowable depth
56 \param    uiMaxWidth    largest CU width
57 \param    uiMaxHeight   largest CU height
58 */
59Void TEncCu::create(UChar uhTotalDepth, UInt uiMaxWidth, UInt uiMaxHeight)
60{
61  Int i;
62 
63  m_uhTotalDepth   = uhTotalDepth + 1;
64  m_ppcBestCU      = new TComDataCU*[m_uhTotalDepth-1];
65  m_ppcTempCU      = new TComDataCU*[m_uhTotalDepth-1];
66   
67  m_ppcPredYuvBest = new TComYuv*[m_uhTotalDepth-1];
68  m_ppcResiYuvBest = new TComYuv*[m_uhTotalDepth-1];
69  m_ppcRecoYuvBest = new TComYuv*[m_uhTotalDepth-1];
70  m_ppcPredYuvTemp = new TComYuv*[m_uhTotalDepth-1];
71  m_ppcResiYuvTemp = new TComYuv*[m_uhTotalDepth-1];
72  m_ppcRecoYuvTemp = new TComYuv*[m_uhTotalDepth-1];
73  m_ppcOrigYuv     = new TComYuv*[m_uhTotalDepth-1];
74 
75  UInt uiNumPartitions;
76  for( i=0 ; i<m_uhTotalDepth-1 ; i++)
77  {
78    uiNumPartitions = 1<<( ( m_uhTotalDepth - i - 1 )<<1 );
79    UInt uiWidth  = uiMaxWidth  >> i;
80    UInt uiHeight = uiMaxHeight >> i;
81   
82    m_ppcBestCU[i] = new TComDataCU; m_ppcBestCU[i]->create( uiNumPartitions, uiWidth, uiHeight, false, uiMaxWidth >> (m_uhTotalDepth - 1) );
83    m_ppcTempCU[i] = new TComDataCU; m_ppcTempCU[i]->create( uiNumPartitions, uiWidth, uiHeight, false, uiMaxWidth >> (m_uhTotalDepth - 1) );
84   
85    m_ppcPredYuvBest[i] = new TComYuv; m_ppcPredYuvBest[i]->create(uiWidth, uiHeight);
86    m_ppcResiYuvBest[i] = new TComYuv; m_ppcResiYuvBest[i]->create(uiWidth, uiHeight);
87    m_ppcRecoYuvBest[i] = new TComYuv; m_ppcRecoYuvBest[i]->create(uiWidth, uiHeight);
88   
89    m_ppcPredYuvTemp[i] = new TComYuv; m_ppcPredYuvTemp[i]->create(uiWidth, uiHeight);
90    m_ppcResiYuvTemp[i] = new TComYuv; m_ppcResiYuvTemp[i]->create(uiWidth, uiHeight);
91    m_ppcRecoYuvTemp[i] = new TComYuv; m_ppcRecoYuvTemp[i]->create(uiWidth, uiHeight);
92   
93    m_ppcOrigYuv    [i] = new TComYuv; m_ppcOrigYuv    [i]->create(uiWidth, uiHeight);
94  }
95 
96  m_bEncodeDQP = false;
97
98  // initialize partition order.
99  UInt* piTmp = &g_auiZscanToRaster[0];
100  initZscanToRaster( m_uhTotalDepth, 1, 0, piTmp);
101  initRasterToZscan( uiMaxWidth, uiMaxHeight, m_uhTotalDepth );
102 
103  // initialize conversion matrix from partition index to pel
104  initRasterToPelXY( uiMaxWidth, uiMaxHeight, m_uhTotalDepth );
105}
106
107Void TEncCu::destroy()
108{
109  Int i;
110 
111  for( i=0 ; i<m_uhTotalDepth-1 ; i++)
112  {
113    if(m_ppcBestCU[i])
114    {
115      m_ppcBestCU[i]->destroy();      delete m_ppcBestCU[i];      m_ppcBestCU[i] = NULL;
116    }
117    if(m_ppcTempCU[i])
118    {
119      m_ppcTempCU[i]->destroy();      delete m_ppcTempCU[i];      m_ppcTempCU[i] = NULL;
120    }
121    if(m_ppcPredYuvBest[i])
122    {
123      m_ppcPredYuvBest[i]->destroy(); delete m_ppcPredYuvBest[i]; m_ppcPredYuvBest[i] = NULL;
124    }
125    if(m_ppcResiYuvBest[i])
126    {
127      m_ppcResiYuvBest[i]->destroy(); delete m_ppcResiYuvBest[i]; m_ppcResiYuvBest[i] = NULL;
128    }
129    if(m_ppcRecoYuvBest[i])
130    {
131      m_ppcRecoYuvBest[i]->destroy(); delete m_ppcRecoYuvBest[i]; m_ppcRecoYuvBest[i] = NULL;
132    }
133    if(m_ppcPredYuvTemp[i])
134    {
135      m_ppcPredYuvTemp[i]->destroy(); delete m_ppcPredYuvTemp[i]; m_ppcPredYuvTemp[i] = NULL;
136    }
137    if(m_ppcResiYuvTemp[i])
138    {
139      m_ppcResiYuvTemp[i]->destroy(); delete m_ppcResiYuvTemp[i]; m_ppcResiYuvTemp[i] = NULL;
140    }
141    if(m_ppcRecoYuvTemp[i])
142    {
143      m_ppcRecoYuvTemp[i]->destroy(); delete m_ppcRecoYuvTemp[i]; m_ppcRecoYuvTemp[i] = NULL;
144    }
145    if(m_ppcOrigYuv[i])
146    {
147      m_ppcOrigYuv[i]->destroy();     delete m_ppcOrigYuv[i];     m_ppcOrigYuv[i] = NULL;
148    }
149  }
150  if(m_ppcBestCU)
151  {
152    delete [] m_ppcBestCU;
153    m_ppcBestCU = NULL;
154  }
155  if(m_ppcTempCU)
156  {
157    delete [] m_ppcTempCU;
158    m_ppcTempCU = NULL;
159  }
160 
161  if(m_ppcPredYuvBest)
162  {
163    delete [] m_ppcPredYuvBest;
164    m_ppcPredYuvBest = NULL;
165  }
166  if(m_ppcResiYuvBest)
167  {
168    delete [] m_ppcResiYuvBest;
169    m_ppcResiYuvBest = NULL;
170  }
171  if(m_ppcRecoYuvBest)
172  {
173    delete [] m_ppcRecoYuvBest;
174    m_ppcRecoYuvBest = NULL;
175  }
176  if(m_ppcPredYuvTemp)
177  {
178    delete [] m_ppcPredYuvTemp;
179    m_ppcPredYuvTemp = NULL;
180  }
181  if(m_ppcResiYuvTemp)
182  {
183    delete [] m_ppcResiYuvTemp;
184    m_ppcResiYuvTemp = NULL;
185  }
186  if(m_ppcRecoYuvTemp)
187  {
188    delete [] m_ppcRecoYuvTemp;
189    m_ppcRecoYuvTemp = NULL;
190  }
191  if(m_ppcOrigYuv)
192  {
193    delete [] m_ppcOrigYuv;
194    m_ppcOrigYuv = NULL;
195  }
196}
197
198/** \param    pcEncTop      pointer of encoder class
199 */
200Void TEncCu::init( TEncTop* pcEncTop )
201{
202  m_pcEncCfg           = pcEncTop;
203  m_pcPredSearch       = pcEncTop->getPredSearch();
204  m_pcTrQuant          = pcEncTop->getTrQuant();
205  m_pcBitCounter       = pcEncTop->getBitCounter();
206  m_pcRdCost           = pcEncTop->getRdCost();
207 
208#if SVC_EXTENSION
209  m_ppcTEncTop         = pcEncTop->getLayerEnc();
210  for(UInt i=0 ; i< m_uhTotalDepth-1 ; i++)
211  {   
212    m_ppcBestCU[i]->setLayerId(pcEncTop->getLayerId());
213    m_ppcTempCU[i]->setLayerId(pcEncTop->getLayerId());
214  }
215#endif
216 
217  m_pcEntropyCoder     = pcEncTop->getEntropyCoder();
218  m_pcCavlcCoder       = pcEncTop->getCavlcCoder();
219  m_pcSbacCoder       = pcEncTop->getSbacCoder();
220  m_pcBinCABAC         = pcEncTop->getBinCABAC();
221 
222  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
223  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
224 
225  m_bUseSBACRD        = pcEncTop->getUseSBACRD();
226  m_pcRateCtrl        = pcEncTop->getRateCtrl();
227}
228
229// ====================================================================================================================
230// Public member functions
231// ====================================================================================================================
232
233/** \param  rpcCU pointer of CU data class
234 */
235Void TEncCu::compressCU( TComDataCU*& rpcCU )
236{
237  // initialize CU data
238  m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
239  m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
240
241#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
242  m_disableILP = xCheckTileSetConstraint(rpcCU);
243  m_pcPredSearch->setDisableILP(m_disableILP);
244#endif
245
246  // analysis of CU
247  xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 );
248
249#if ADAPTIVE_QP_SELECTION
250  if( m_pcEncCfg->getUseAdaptQpSelect() )
251  {
252    if(rpcCU->getSlice()->getSliceType()!=I_SLICE) //IIII
253    {
254      xLcuCollectARLStats( rpcCU);
255    }
256  }
257#endif
258
259#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
260  xVerifyTileSetConstraint(rpcCU);
261#endif
262}
263/** \param  pcCU  pointer of CU data class
264 */
265Void TEncCu::encodeCU ( TComDataCU* pcCU )
266{
267  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
268  {
269    setdQPFlag(true);
270  }
271
272  // Encode CU data
273  xEncodeCU( pcCU, 0, 0 );
274}
275
276// ====================================================================================================================
277// Protected member functions
278// ====================================================================================================================
279/** Derive small set of test modes for AMP encoder speed-up
280 *\param   rpcBestCU
281 *\param   eParentPartSize
282 *\param   bTestAMP_Hor
283 *\param   bTestAMP_Ver
284 *\param   bTestMergeAMP_Hor
285 *\param   bTestMergeAMP_Ver
286 *\returns Void
287*/
288#if AMP_ENC_SPEEDUP
289#if AMP_MRG
290Void TEncCu::deriveTestModeAMP (TComDataCU *&rpcBestCU, PartSize eParentPartSize, Bool &bTestAMP_Hor, Bool &bTestAMP_Ver, Bool &bTestMergeAMP_Hor, Bool &bTestMergeAMP_Ver)
291#else
292Void TEncCu::deriveTestModeAMP (TComDataCU *&rpcBestCU, PartSize eParentPartSize, Bool &bTestAMP_Hor, Bool &bTestAMP_Ver)
293#endif
294{
295  if ( rpcBestCU->getPartitionSize(0) == SIZE_2NxN )
296  {
297    bTestAMP_Hor = true;
298  }
299  else if ( rpcBestCU->getPartitionSize(0) == SIZE_Nx2N )
300  {
301    bTestAMP_Ver = true;
302  }
303  else if ( rpcBestCU->getPartitionSize(0) == SIZE_2Nx2N && rpcBestCU->getMergeFlag(0) == false && rpcBestCU->isSkipped(0) == false )
304  {
305    bTestAMP_Hor = true;         
306    bTestAMP_Ver = true;         
307  }
308
309#if AMP_MRG
310  //! Utilizing the partition size of parent PU   
311  if ( eParentPartSize >= SIZE_2NxnU && eParentPartSize <= SIZE_nRx2N )
312  { 
313    bTestMergeAMP_Hor = true;
314    bTestMergeAMP_Ver = true;
315  }
316
317  if ( eParentPartSize == SIZE_NONE ) //! if parent is intra
318  {
319    if ( rpcBestCU->getPartitionSize(0) == SIZE_2NxN )
320    {
321      bTestMergeAMP_Hor = true;
322    }
323    else if ( rpcBestCU->getPartitionSize(0) == SIZE_Nx2N )
324    {
325      bTestMergeAMP_Ver = true;
326    }
327  }
328
329  if ( rpcBestCU->getPartitionSize(0) == SIZE_2Nx2N && rpcBestCU->isSkipped(0) == false )
330  {
331    bTestMergeAMP_Hor = true;         
332    bTestMergeAMP_Ver = true;         
333  }
334
335  if ( rpcBestCU->getWidth(0) == 64 )
336  { 
337    bTestAMP_Hor = false;
338    bTestAMP_Ver = false;
339  }   
340#else
341  //! Utilizing the partition size of parent PU       
342  if ( eParentPartSize >= SIZE_2NxnU && eParentPartSize <= SIZE_nRx2N )
343  { 
344    bTestAMP_Hor = true;
345    bTestAMP_Ver = true;
346  }
347
348  if ( eParentPartSize == SIZE_2Nx2N )
349  { 
350    bTestAMP_Hor = false;
351    bTestAMP_Ver = false;
352  }     
353#endif
354}
355#endif
356
357// ====================================================================================================================
358// Protected member functions
359// ====================================================================================================================
360/** Compress a CU block recursively with enabling sub-LCU-level delta QP
361 *\param   rpcBestCU
362 *\param   rpcTempCU
363 *\param   uiDepth
364 *\returns Void
365 *
366 *- for loop of QP value to compress the current CU with all possible QP
367*/
368#if AMP_ENC_SPEEDUP
369Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth, PartSize eParentPartSize )
370#else
371Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth )
372#endif
373{
374  TComPic* pcPic = rpcBestCU->getPic();
375
376  // get Original YUV data from picture
377  m_ppcOrigYuv[uiDepth]->copyFromPicYuv( pcPic->getPicYuvOrg(), rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
378
379  // variable for Early CU determination
380  Bool    bSubBranch = true;
381
382  // variable for Cbf fast mode PU decision
383  Bool    doNotBlockPu = true;
384  Bool earlyDetectionSkipMode = false;
385
386  Bool bBoundary = false;
387  UInt uiLPelX   = rpcBestCU->getCUPelX();
388  UInt uiRPelX   = uiLPelX + rpcBestCU->getWidth(0)  - 1;
389  UInt uiTPelY   = rpcBestCU->getCUPelY();
390  UInt uiBPelY   = uiTPelY + rpcBestCU->getHeight(0) - 1;
391
392  Int iBaseQP = xComputeQP( rpcBestCU, uiDepth );
393  Int iMinQP;
394  Int iMaxQP;
395  Bool isAddLowestQP = false;
396#if REPN_FORMAT_IN_VPS
397  Int lowestQP = -rpcTempCU->getSlice()->getQpBDOffsetY();
398#else
399  Int lowestQP = -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY();
400#endif
401
402  if( (g_uiMaxCUWidth>>uiDepth) >= rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() )
403  {
404    Int idQP = m_pcEncCfg->getMaxDeltaQP();
405#if REPN_FORMAT_IN_VPS
406    iMinQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP-idQP );
407    iMaxQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP+idQP );
408#else
409    iMinQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP-idQP );
410    iMaxQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP+idQP );
411#endif
412    if ( (rpcTempCU->getSlice()->getSPS()->getUseLossless()) && (lowestQP < iMinQP) && rpcTempCU->getSlice()->getPPS()->getUseDQP() )
413    {
414      isAddLowestQP = true; 
415      iMinQP = iMinQP - 1;
416    }
417  }
418  else
419  {
420    iMinQP = rpcTempCU->getQP(0);
421    iMaxQP = rpcTempCU->getQP(0);
422  }
423
424  if ( m_pcEncCfg->getUseRateCtrl() )
425  {
426    iMinQP = m_pcRateCtrl->getRCQP();
427    iMaxQP = m_pcRateCtrl->getRCQP();
428  }
429
430  // If slice start or slice end is within this cu...
431  TComSlice * pcSlice = rpcTempCU->getPic()->getSlice(rpcTempCU->getPic()->getCurrSliceIdx());
432  Bool bSliceStart = pcSlice->getSliceSegmentCurStartCUAddr()>rpcTempCU->getSCUAddr()&&pcSlice->getSliceSegmentCurStartCUAddr()<rpcTempCU->getSCUAddr()+rpcTempCU->getTotalNumPart();
433  Bool bSliceEnd = (pcSlice->getSliceSegmentCurEndCUAddr()>rpcTempCU->getSCUAddr()&&pcSlice->getSliceSegmentCurEndCUAddr()<rpcTempCU->getSCUAddr()+rpcTempCU->getTotalNumPart());
434#if REPN_FORMAT_IN_VPS
435  Bool bInsidePicture = ( uiRPelX < rpcBestCU->getSlice()->getPicWidthInLumaSamples()           ) && ( uiBPelY < rpcBestCU->getSlice()->getPicHeightInLumaSamples()           );
436#else
437  Bool bInsidePicture = ( uiRPelX < rpcBestCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiBPelY < rpcBestCU->getSlice()->getSPS()->getPicHeightInLumaSamples() );
438#endif
439  // We need to split, so don't try these modes.
440  if(!bSliceEnd && !bSliceStart && bInsidePicture )
441  {
442#if HIGHER_LAYER_IRAP_SKIP_FLAG
443    if (m_pcEncCfg->getSkipPictureAtArcSwitch() && m_pcEncCfg->getAdaptiveResolutionChange() > 0 && pcSlice->getLayerId() == 1 && pcSlice->getPOC() == m_pcEncCfg->getAdaptiveResolutionChange())
444    {
445      rpcTempCU->initEstData( uiDepth, iBaseQP );
446     
447      xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode, true );
448    }
449    else
450    {
451#endif
452#if (ENCODER_FAST_MODE)
453    Bool testInter = true;
454    if (rpcBestCU->getLayerId() > 0)
455    {
456      if(pcSlice->getSliceType() == P_SLICE && pcSlice->getNumRefIdx(REF_PIC_LIST_0) == pcSlice->getActiveNumILRRefIdx())
457      {
458        testInter = false;
459      }
460      if(pcSlice->getSliceType() == B_SLICE && pcSlice->getNumRefIdx(REF_PIC_LIST_0) == pcSlice->getActiveNumILRRefIdx() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) == pcSlice->getActiveNumILRRefIdx()) 
461      {
462        testInter = false;
463      }
464#if M0457_IL_SAMPLE_PRED_ONLY_FLAG
465      if( pcSlice->getInterLayerSamplePredOnlyFlag() )
466      {
467        testInter = false;
468      }
469#endif
470    }
471#endif
472    for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
473    {
474      if (isAddLowestQP && (iQP == iMinQP))
475      {
476        iQP = lowestQP;
477      }
478
479      rpcTempCU->initEstData( uiDepth, iQP );
480
481      // do inter modes, SKIP and 2Nx2N
482#if (ENCODER_FAST_MODE == 1)
483      if( rpcBestCU->getSlice()->getSliceType() != I_SLICE && testInter )
484#else
485      if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
486#endif
487      {
488        // 2Nx2N
489        if(m_pcEncCfg->getUseEarlySkipDetection())
490        {
491          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData( uiDepth, iQP );//by Competition for inter_2Nx2N
492        }
493        // SKIP
494        xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode );//by Merge for inter_2Nx2N
495        rpcTempCU->initEstData( uiDepth, iQP );
496       
497#if (ENCODER_FAST_MODE == 2)
498        if (testInter)
499        {
500#endif
501        if(!m_pcEncCfg->getUseEarlySkipDetection())
502        {
503          // 2Nx2N, NxN
504          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData( uiDepth, iQP );
505          if(m_pcEncCfg->getUseCbfFastMode())
506          {
507            doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
508          }
509        }
510#if (ENCODER_FAST_MODE == 2)
511        }
512#endif
513      }
514
515      if (isAddLowestQP && (iQP == lowestQP))
516      {
517        iQP = iMinQP;
518      }
519    }
520
521    if(!earlyDetectionSkipMode)
522    {
523      for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
524      {
525        if (isAddLowestQP && (iQP == iMinQP))
526        {
527          iQP = lowestQP;
528        }
529        rpcTempCU->initEstData( uiDepth, iQP );
530
531        // do inter modes, NxN, 2NxN, and Nx2N
532#if (ENCODER_FAST_MODE)
533        if( rpcBestCU->getSlice()->getSliceType() != I_SLICE && testInter )
534#else
535        if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
536#endif
537        {
538          // 2Nx2N, NxN
539          if(!( (rpcBestCU->getWidth(0)==8) && (rpcBestCU->getHeight(0)==8) ))
540          {
541            if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth && doNotBlockPu)
542            {
543              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN   );
544              rpcTempCU->initEstData( uiDepth, iQP );
545            }
546          }
547
548          // 2NxN, Nx2N
549          if(doNotBlockPu)
550          {
551            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_Nx2N  );
552            rpcTempCU->initEstData( uiDepth, iQP );
553            if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_Nx2N )
554            {
555              doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
556            }
557          }
558          if(doNotBlockPu)
559          {
560            xCheckRDCostInter      ( rpcBestCU, rpcTempCU, SIZE_2NxN  );
561            rpcTempCU->initEstData( uiDepth, iQP );
562            if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxN)
563            {
564              doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
565            }
566          }
567
568#if 1
569          //! Try AMP (SIZE_2NxnU, SIZE_2NxnD, SIZE_nLx2N, SIZE_nRx2N)
570          if( pcPic->getSlice(0)->getSPS()->getAMPAcc(uiDepth) )
571          {
572#if AMP_ENC_SPEEDUP       
573            Bool bTestAMP_Hor = false, bTestAMP_Ver = false;
574
575#if AMP_MRG
576            Bool bTestMergeAMP_Hor = false, bTestMergeAMP_Ver = false;
577
578            deriveTestModeAMP (rpcBestCU, eParentPartSize, bTestAMP_Hor, bTestAMP_Ver, bTestMergeAMP_Hor, bTestMergeAMP_Ver);
579#else
580            deriveTestModeAMP (rpcBestCU, eParentPartSize, bTestAMP_Hor, bTestAMP_Ver);
581#endif
582
583            //! Do horizontal AMP
584            if ( bTestAMP_Hor )
585            {
586              if(doNotBlockPu)
587              {
588                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnU );
589                rpcTempCU->initEstData( uiDepth, iQP );
590                if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnU )
591                {
592                  doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
593                }
594              }
595              if(doNotBlockPu)
596              {
597                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnD );
598                rpcTempCU->initEstData( uiDepth, iQP );
599                if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnD )
600                {
601                  doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
602                }
603              }
604            }
605#if AMP_MRG
606            else if ( bTestMergeAMP_Hor ) 
607            {
608              if(doNotBlockPu)
609              {
610                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnU, true );
611                rpcTempCU->initEstData( uiDepth, iQP );
612                if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnU )
613                {
614                  doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
615                }
616              }
617              if(doNotBlockPu)
618              {
619                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnD, true );
620                rpcTempCU->initEstData( uiDepth, iQP );
621                if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnD )
622                {
623                  doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
624                }
625              }
626            }
627#endif
628
629            //! Do horizontal AMP
630            if ( bTestAMP_Ver )
631            {
632              if(doNotBlockPu)
633              {
634                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nLx2N );
635                rpcTempCU->initEstData( uiDepth, iQP );
636                if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_nLx2N )
637                {
638                  doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
639                }
640              }
641              if(doNotBlockPu)
642              {
643                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nRx2N );
644                rpcTempCU->initEstData( uiDepth, iQP );
645              }
646            }
647#if AMP_MRG
648            else if ( bTestMergeAMP_Ver )
649            {
650              if(doNotBlockPu)
651              {
652                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nLx2N, true );
653                rpcTempCU->initEstData( uiDepth, iQP );
654                if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_nLx2N )
655                {
656                  doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
657                }
658              }
659              if(doNotBlockPu)
660              {
661                xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nRx2N, true );
662                rpcTempCU->initEstData( uiDepth, iQP );
663              }
664            }
665#endif
666
667#else
668            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnU );
669            rpcTempCU->initEstData( uiDepth, iQP );
670            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnD );
671            rpcTempCU->initEstData( uiDepth, iQP );
672            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nLx2N );
673            rpcTempCU->initEstData( uiDepth, iQP );
674
675            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nRx2N );
676            rpcTempCU->initEstData( uiDepth, iQP );
677
678#endif
679          }   
680#endif
681        }
682
683        // do normal intra modes
684          // speedup for inter frames
685#if (ENCODER_FAST_MODE)
686        if( rpcBestCU->getSlice()->getSliceType() == I_SLICE || 
687          !testInter ||
688          rpcBestCU->getCbf( 0, TEXT_LUMA     ) != 0   ||
689          rpcBestCU->getCbf( 0, TEXT_CHROMA_U ) != 0   ||
690          rpcBestCU->getCbf( 0, TEXT_CHROMA_V ) != 0     ) // avoid very complex intra if it is unlikely
691#else
692          if( rpcBestCU->getSlice()->getSliceType() == I_SLICE || 
693            rpcBestCU->getCbf( 0, TEXT_LUMA     ) != 0   ||
694            rpcBestCU->getCbf( 0, TEXT_CHROMA_U ) != 0   ||
695            rpcBestCU->getCbf( 0, TEXT_CHROMA_V ) != 0     ) // avoid very complex intra if it is unlikely
696#endif
697          {
698            xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_2Nx2N );
699            rpcTempCU->initEstData( uiDepth, iQP );
700            if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth )
701            {
702              if( rpcTempCU->getWidth(0) > ( 1 << rpcTempCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() ) )
703              {
704                xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_NxN   );
705                rpcTempCU->initEstData( uiDepth, iQP );
706              }
707            }
708          }
709
710        // test PCM
711        if(pcPic->getSlice(0)->getSPS()->getUsePCM()
712          && rpcTempCU->getWidth(0) <= (1<<pcPic->getSlice(0)->getSPS()->getPCMLog2MaxSize())
713          && rpcTempCU->getWidth(0) >= (1<<pcPic->getSlice(0)->getSPS()->getPCMLog2MinSize()) )
714        {
715          UInt uiRawBits = (2 * g_bitDepthY + g_bitDepthC) * rpcBestCU->getWidth(0) * rpcBestCU->getHeight(0) / 2;
716          UInt uiBestBits = rpcBestCU->getTotalBits();
717          if((uiBestBits > uiRawBits) || (rpcBestCU->getTotalCost() > m_pcRdCost->calcRdCost(uiRawBits, 0)))
718          {
719            xCheckIntraPCM (rpcBestCU, rpcTempCU);
720            rpcTempCU->initEstData( uiDepth, iQP );
721          }
722        }
723#if (ENCODER_FAST_MODE)
724#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
725      if(pcPic->getLayerId() > 0 && !m_disableILP)
726#else
727      if(pcPic->getLayerId() > 0)
728#endif
729      {
730        for(Int refLayer = 0; refLayer < pcSlice->getActiveNumILRRefIdx(); refLayer++)
731        { 
732           xCheckRDCostILRUni( rpcBestCU, rpcTempCU, pcSlice->getInterLayerPredLayerIdc(refLayer));
733           rpcTempCU->initEstData( uiDepth, iQP );
734        }
735      }
736#endif
737
738        if (isAddLowestQP && (iQP == lowestQP))
739        {
740          iQP = iMinQP;
741        }
742      }
743    }
744
745    m_pcEntropyCoder->resetBits();
746    m_pcEntropyCoder->encodeSplitFlag( rpcBestCU, 0, uiDepth, true );
747    rpcBestCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
748    if(m_pcEncCfg->getUseSBACRD())
749    {
750      rpcBestCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
751    }
752    rpcBestCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcBestCU->getTotalBits(), rpcBestCU->getTotalDistortion() );
753
754    // Early CU determination
755    if( m_pcEncCfg->getUseEarlyCU() && rpcBestCU->isSkipped(0) )
756    {
757      bSubBranch = false;
758    }
759    else
760    {
761      bSubBranch = true;
762    }
763#if HIGHER_LAYER_IRAP_SKIP_FLAG
764    }
765#endif
766  }
767  else if(!(bSliceEnd && bInsidePicture))
768  {
769    bBoundary = true;
770  }
771
772  // copy orginal YUV samples to PCM buffer
773  if( rpcBestCU->isLosslessCoded(0) && (rpcBestCU->getIPCMFlag(0) == false))
774  {
775    xFillPCMBuffer(rpcBestCU, m_ppcOrigYuv[uiDepth]);
776  }
777  if( (g_uiMaxCUWidth>>uiDepth) == rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() )
778  {
779    Int idQP = m_pcEncCfg->getMaxDeltaQP();
780#if REPN_FORMAT_IN_VPS
781    iMinQP = Clip3( -rpcTempCU->getSlice()->getQpBDOffsetY(), MAX_QP, iBaseQP-idQP );
782    iMaxQP = Clip3( -rpcTempCU->getSlice()->getQpBDOffsetY(), MAX_QP, iBaseQP+idQP );
783#else
784    iMinQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP-idQP );
785    iMaxQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP+idQP );
786#endif
787    if ( (rpcTempCU->getSlice()->getSPS()->getUseLossless()) && (lowestQP < iMinQP) && rpcTempCU->getSlice()->getPPS()->getUseDQP() )
788    {
789      isAddLowestQP = true;
790      iMinQP = iMinQP - 1;     
791    }
792  }
793  else if( (g_uiMaxCUWidth>>uiDepth) > rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() )
794  {
795    iMinQP = iBaseQP;
796    iMaxQP = iBaseQP;
797  }
798  else
799  {
800    Int iStartQP;
801    if( pcPic->getCU( rpcTempCU->getAddr() )->getSliceSegmentStartCU(rpcTempCU->getZorderIdxInCU()) == pcSlice->getSliceSegmentCurStartCUAddr())
802    {
803      iStartQP = rpcTempCU->getQP(0);
804    }
805    else
806    {
807      UInt uiCurSliceStartPartIdx = pcSlice->getSliceSegmentCurStartCUAddr() % pcPic->getNumPartInCU() - rpcTempCU->getZorderIdxInCU();
808      iStartQP = rpcTempCU->getQP(uiCurSliceStartPartIdx);
809    }
810    iMinQP = iStartQP;
811    iMaxQP = iStartQP;
812  }
813  if ( m_pcEncCfg->getUseRateCtrl() )
814  {
815    iMinQP = m_pcRateCtrl->getRCQP();
816    iMaxQP = m_pcRateCtrl->getRCQP();
817  }
818  for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
819  {
820    if (isAddLowestQP && (iQP == iMinQP))
821    {
822      iQP = lowestQP;
823    }
824    rpcTempCU->initEstData( uiDepth, iQP );
825
826    // further split
827    if( bSubBranch && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth )
828    {
829      UChar       uhNextDepth         = uiDepth+1;
830      TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
831      TComDataCU* pcSubTempPartCU     = m_ppcTempCU[uhNextDepth];
832
833      for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )
834      {
835        pcSubBestPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
836        pcSubTempPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
837
838        Bool bInSlice = pcSubBestPartCU->getSCUAddr()+pcSubBestPartCU->getTotalNumPart()>pcSlice->getSliceSegmentCurStartCUAddr()&&pcSubBestPartCU->getSCUAddr()<pcSlice->getSliceSegmentCurEndCUAddr();
839#if REPN_FORMAT_IN_VPS
840        if(bInSlice && ( pcSubBestPartCU->getCUPelX() < pcSlice->getPicWidthInLumaSamples()           ) && ( pcSubBestPartCU->getCUPelY() < pcSlice->getPicHeightInLumaSamples()           ) )
841#else
842        if(bInSlice && ( pcSubBestPartCU->getCUPelX() < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( pcSubBestPartCU->getCUPelY() < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
843#endif
844        {
845          if( m_bUseSBACRD )
846          {
847            if ( 0 == uiPartUnitIdx) //initialize RD with previous depth buffer
848            {
849              m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
850            }
851            else
852            {
853              m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
854            }
855          }
856
857#if AMP_ENC_SPEEDUP
858          if ( rpcBestCU->isIntra(0) )
859          {
860            xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, SIZE_NONE );
861          }
862          else
863          {
864            xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, rpcBestCU->getPartitionSize(0) );
865          }
866#else
867          xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth );
868#endif
869
870          rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );         // Keep best part data to current temporary data.
871          xCopyYuv2Tmp( pcSubBestPartCU->getTotalNumPart()*uiPartUnitIdx, uhNextDepth );
872        }
873        else if (bInSlice)
874        {
875          pcSubBestPartCU->copyToPic( uhNextDepth );
876          rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );
877        }
878      }
879
880      if( !bBoundary )
881      {
882        m_pcEntropyCoder->resetBits();
883        m_pcEntropyCoder->encodeSplitFlag( rpcTempCU, 0, uiDepth, true );
884
885        rpcTempCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
886        if(m_pcEncCfg->getUseSBACRD())
887        {
888          rpcTempCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
889        }
890      }
891      rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
892
893      if( (g_uiMaxCUWidth>>uiDepth) == rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() && rpcTempCU->getSlice()->getPPS()->getUseDQP())
894      {
895        Bool hasResidual = false;
896        for( UInt uiBlkIdx = 0; uiBlkIdx < rpcTempCU->getTotalNumPart(); uiBlkIdx ++)
897        {
898          if( ( pcPic->getCU( rpcTempCU->getAddr() )->getSliceSegmentStartCU(uiBlkIdx+rpcTempCU->getZorderIdxInCU()) == rpcTempCU->getSlice()->getSliceSegmentCurStartCUAddr() ) && 
899              ( rpcTempCU->getCbf( uiBlkIdx, TEXT_LUMA ) || rpcTempCU->getCbf( uiBlkIdx, TEXT_CHROMA_U ) || rpcTempCU->getCbf( uiBlkIdx, TEXT_CHROMA_V ) ) )
900          {
901            hasResidual = true;
902            break;
903          }
904        }
905
906        UInt uiTargetPartIdx;
907        if ( pcPic->getCU( rpcTempCU->getAddr() )->getSliceSegmentStartCU(rpcTempCU->getZorderIdxInCU()) != pcSlice->getSliceSegmentCurStartCUAddr() )
908        {
909          uiTargetPartIdx = pcSlice->getSliceSegmentCurStartCUAddr() % pcPic->getNumPartInCU() - rpcTempCU->getZorderIdxInCU();
910        }
911        else
912        {
913          uiTargetPartIdx = 0;
914        }
915        if ( hasResidual )
916        {
917#if !RDO_WITHOUT_DQP_BITS
918          m_pcEntropyCoder->resetBits();
919          m_pcEntropyCoder->encodeQP( rpcTempCU, uiTargetPartIdx, false );
920          rpcTempCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
921          if(m_pcEncCfg->getUseSBACRD())
922          {
923            rpcTempCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
924          }
925          rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
926#endif
927
928          Bool foundNonZeroCbf = false;
929          rpcTempCU->setQPSubCUs( rpcTempCU->getRefQP( uiTargetPartIdx ), rpcTempCU, 0, uiDepth, foundNonZeroCbf );
930          assert( foundNonZeroCbf );
931        }
932        else
933        {
934          rpcTempCU->setQPSubParts( rpcTempCU->getRefQP( uiTargetPartIdx ), 0, uiDepth ); // set QP to default QP
935        }
936      }
937
938      if( m_bUseSBACRD )
939      {
940        m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
941      }
942      Bool isEndOfSlice        = rpcBestCU->getSlice()->getSliceMode()==FIXED_NUMBER_OF_BYTES
943                                 && (rpcBestCU->getTotalBits()>rpcBestCU->getSlice()->getSliceArgument()<<3);
944      Bool isEndOfSliceSegment = rpcBestCU->getSlice()->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES
945                                 && (rpcBestCU->getTotalBits()>rpcBestCU->getSlice()->getSliceSegmentArgument()<<3);
946      if(isEndOfSlice||isEndOfSliceSegment)
947      {
948        rpcBestCU->getTotalCost()=rpcTempCU->getTotalCost()+1;
949      }
950      xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth);                                  // RD compare current larger prediction
951    }                                                                                  // with sub partitioned prediction.
952    if (isAddLowestQP && (iQP == lowestQP))
953    {
954      iQP = iMinQP;
955    }
956  }
957
958  rpcBestCU->copyToPic(uiDepth);                                                     // Copy Best data to Picture for next partition prediction.
959
960  xCopyYuv2Pic( rpcBestCU->getPic(), rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU(), uiDepth, uiDepth, rpcBestCU, uiLPelX, uiTPelY );   // Copy Yuv data to picture Yuv
961  if( bBoundary ||(bSliceEnd && bInsidePicture))
962  {
963    return;
964  }
965
966  // Assert if Best prediction mode is NONE
967  // Selected mode's RD-cost must be not MAX_DOUBLE.
968  assert( rpcBestCU->getPartitionSize ( 0 ) != SIZE_NONE  );
969  assert( rpcBestCU->getPredictionMode( 0 ) != MODE_NONE  );
970  assert( rpcBestCU->getTotalCost     (   ) != MAX_DOUBLE );
971}
972
973/** finish encoding a cu and handle end-of-slice conditions
974 * \param pcCU
975 * \param uiAbsPartIdx
976 * \param uiDepth
977 * \returns Void
978 */
979Void TEncCu::finishCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
980{
981  TComPic* pcPic = pcCU->getPic();
982  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
983
984  //Calculate end address
985  UInt uiCUAddr = pcCU->getSCUAddr()+uiAbsPartIdx;
986
987  UInt uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU();
988  UInt uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU();
989  UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
990  UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
991#if REPN_FORMAT_IN_VPS
992  UInt uiWidth =  pcSlice->getPicWidthInLumaSamples();
993  UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
994#else
995  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
996  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
997#endif
998  while(uiPosX>=uiWidth||uiPosY>=uiHeight)
999  {
1000    uiInternalAddress--;
1001    uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1002    uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1003  }
1004  uiInternalAddress++;
1005  if(uiInternalAddress==pcCU->getPic()->getNumPartInCU())
1006  {
1007    uiInternalAddress = 0;
1008    uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1009  }
1010  UInt uiRealEndAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
1011
1012  // Encode slice finish
1013  Bool bTerminateSlice = false;
1014  if (uiCUAddr+(pcCU->getPic()->getNumPartInCU()>>(uiDepth<<1)) == uiRealEndAddress)
1015  {
1016    bTerminateSlice = true;
1017  }
1018  UInt uiGranularityWidth = g_uiMaxCUWidth;
1019  uiPosX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1020  uiPosY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1021  Bool granularityBoundary=((uiPosX+pcCU->getWidth(uiAbsPartIdx))%uiGranularityWidth==0||(uiPosX+pcCU->getWidth(uiAbsPartIdx)==uiWidth))
1022    &&((uiPosY+pcCU->getHeight(uiAbsPartIdx))%uiGranularityWidth==0||(uiPosY+pcCU->getHeight(uiAbsPartIdx)==uiHeight));
1023 
1024  if(granularityBoundary)
1025  {
1026    // The 1-terminating bit is added to all streams, so don't add it here when it's 1.
1027    if (!bTerminateSlice)
1028      m_pcEntropyCoder->encodeTerminatingBit( bTerminateSlice ? 1 : 0 );
1029  }
1030 
1031  Int numberOfWrittenBits = 0;
1032  if (m_pcBitCounter)
1033  {
1034    numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
1035  }
1036 
1037  // Calculate slice end IF this CU puts us over slice bit size.
1038  UInt iGranularitySize = pcCU->getPic()->getNumPartInCU();
1039  Int iGranularityEnd = ((pcCU->getSCUAddr()+uiAbsPartIdx)/iGranularitySize)*iGranularitySize;
1040  if(iGranularityEnd<=pcSlice->getSliceSegmentCurStartCUAddr()) 
1041  {
1042    iGranularityEnd+=max(iGranularitySize,(pcCU->getPic()->getNumPartInCU()>>(uiDepth<<1)));
1043  }
1044  // Set slice end parameter
1045  if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES&&!pcSlice->getFinalized()&&pcSlice->getSliceBits()+numberOfWrittenBits>pcSlice->getSliceArgument()<<3) 
1046  {
1047    pcSlice->setSliceSegmentCurEndCUAddr(iGranularityEnd);
1048    pcSlice->setSliceCurEndCUAddr(iGranularityEnd);
1049    return;
1050  }
1051  // Set dependent slice end parameter
1052  if(pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES&&!pcSlice->getFinalized()&&pcSlice->getSliceSegmentBits()+numberOfWrittenBits > pcSlice->getSliceSegmentArgument()<<3) 
1053  {
1054    pcSlice->setSliceSegmentCurEndCUAddr(iGranularityEnd);
1055    return;
1056  }
1057  if(granularityBoundary)
1058  {
1059    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
1060    pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);
1061    if (m_pcBitCounter)
1062    {
1063      m_pcEntropyCoder->resetBits();     
1064    }
1065  }
1066}
1067
1068/** Compute QP for each CU
1069 * \param pcCU Target CU
1070 * \param uiDepth CU depth
1071 * \returns quantization parameter
1072 */
1073Int TEncCu::xComputeQP( TComDataCU* pcCU, UInt uiDepth )
1074{
1075  Int iBaseQp = pcCU->getSlice()->getSliceQp();
1076  Int iQpOffset = 0;
1077  if ( m_pcEncCfg->getUseAdaptiveQP() )
1078  {
1079    TEncPic* pcEPic = dynamic_cast<TEncPic*>( pcCU->getPic() );
1080    UInt uiAQDepth = min( uiDepth, pcEPic->getMaxAQDepth()-1 );
1081    TEncPicQPAdaptationLayer* pcAQLayer = pcEPic->getAQLayer( uiAQDepth );
1082    UInt uiAQUPosX = pcCU->getCUPelX() / pcAQLayer->getAQPartWidth();
1083    UInt uiAQUPosY = pcCU->getCUPelY() / pcAQLayer->getAQPartHeight();
1084    UInt uiAQUStride = pcAQLayer->getAQPartStride();
1085    TEncQPAdaptationUnit* acAQU = pcAQLayer->getQPAdaptationUnit();
1086
1087    Double dMaxQScale = pow(2.0, m_pcEncCfg->getQPAdaptationRange()/6.0);
1088    Double dAvgAct = pcAQLayer->getAvgActivity();
1089    Double dCUAct = acAQU[uiAQUPosY * uiAQUStride + uiAQUPosX].getActivity();
1090    Double dNormAct = (dMaxQScale*dCUAct + dAvgAct) / (dCUAct + dMaxQScale*dAvgAct);
1091    Double dQpOffset = log(dNormAct) / log(2.0) * 6.0;
1092    iQpOffset = Int(floor( dQpOffset + 0.49999 ));
1093  }
1094#if REPN_FORMAT_IN_VPS
1095  return Clip3(-pcCU->getSlice()->getQpBDOffsetY(), MAX_QP, iBaseQp+iQpOffset );
1096#else
1097  return Clip3(-pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQp+iQpOffset );
1098#endif
1099}
1100
1101/** encode a CU block recursively
1102 * \param pcCU
1103 * \param uiAbsPartIdx
1104 * \param uiDepth
1105 * \returns Void
1106 */
1107Void TEncCu::xEncodeCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
1108{
1109  TComPic* pcPic = pcCU->getPic();
1110 
1111  Bool bBoundary = false;
1112  UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1113  UInt uiRPelX   = uiLPelX + (g_uiMaxCUWidth>>uiDepth)  - 1;
1114  UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1115  UInt uiBPelY   = uiTPelY + (g_uiMaxCUHeight>>uiDepth) - 1;
1116 
1117  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
1118#if HIGHER_LAYER_IRAP_SKIP_FLAG
1119  if (m_pcEncCfg->getSkipPictureAtArcSwitch() && m_pcEncCfg->getAdaptiveResolutionChange() > 0 && pcSlice->getLayerId() == 1 && pcSlice->getPOC() == m_pcEncCfg->getAdaptiveResolutionChange())
1120  {
1121    pcCU->setSkipFlagSubParts(true, uiAbsPartIdx, uiDepth);
1122  }
1123#endif
1124  // If slice start is within this cu...
1125  Bool bSliceStart = pcSlice->getSliceSegmentCurStartCUAddr() > pcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx && 
1126    pcSlice->getSliceSegmentCurStartCUAddr() < pcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+( pcPic->getNumPartInCU() >> (uiDepth<<1) );
1127  // We need to split, so don't try these modes.
1128#if REPN_FORMAT_IN_VPS
1129  if(!bSliceStart&&( uiRPelX < pcSlice->getPicWidthInLumaSamples()           ) && ( uiBPelY < pcSlice->getPicHeightInLumaSamples()           ) )
1130#else
1131  if(!bSliceStart&&( uiRPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiBPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1132#endif
1133  {
1134    m_pcEntropyCoder->encodeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
1135  }
1136  else
1137  {
1138    bBoundary = true;
1139  }
1140 
1141  if( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < (g_uiMaxCUDepth-g_uiAddCUDepth) ) ) || bBoundary )
1142  {
1143    UInt uiQNumParts = ( pcPic->getNumPartInCU() >> (uiDepth<<1) )>>2;
1144    if( (g_uiMaxCUWidth>>uiDepth) == pcCU->getSlice()->getPPS()->getMinCuDQPSize() && pcCU->getSlice()->getPPS()->getUseDQP())
1145    {
1146      setdQPFlag(true);
1147    }
1148    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++, uiAbsPartIdx+=uiQNumParts )
1149    {
1150      uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1151      uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1152      Bool bInSlice = pcCU->getSCUAddr()+uiAbsPartIdx+uiQNumParts>pcSlice->getSliceSegmentCurStartCUAddr()&&pcCU->getSCUAddr()+uiAbsPartIdx<pcSlice->getSliceSegmentCurEndCUAddr();
1153#if REPN_FORMAT_IN_VPS
1154      if(bInSlice&&( uiLPelX < pcSlice->getPicWidthInLumaSamples()           ) && ( uiTPelY < pcSlice->getPicHeightInLumaSamples()           ) )
1155#else
1156      if(bInSlice&&( uiLPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1157#endif
1158      {
1159        xEncodeCU( pcCU, uiAbsPartIdx, uiDepth+1 );
1160      }
1161    }
1162    return;
1163  }
1164 
1165  if( (g_uiMaxCUWidth>>uiDepth) >= pcCU->getSlice()->getPPS()->getMinCuDQPSize() && pcCU->getSlice()->getPPS()->getUseDQP())
1166  {
1167    setdQPFlag(true);
1168  }
1169  if (pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
1170  {
1171    m_pcEntropyCoder->encodeCUTransquantBypassFlag( pcCU, uiAbsPartIdx );
1172  }
1173  if( !pcCU->getSlice()->isIntra() )
1174  {
1175    m_pcEntropyCoder->encodeSkipFlag( pcCU, uiAbsPartIdx );
1176  }
1177 
1178  if( pcCU->isSkipped( uiAbsPartIdx ) )
1179  {
1180    m_pcEntropyCoder->encodeMergeIndex( pcCU, uiAbsPartIdx );
1181    finishCU(pcCU,uiAbsPartIdx,uiDepth);
1182    return;
1183  }
1184  m_pcEntropyCoder->encodePredMode( pcCU, uiAbsPartIdx );
1185 
1186  m_pcEntropyCoder->encodePartSize( pcCU, uiAbsPartIdx, uiDepth );
1187 
1188  if (pcCU->isIntra( uiAbsPartIdx ) && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N )
1189  {
1190    m_pcEntropyCoder->encodeIPCMInfo( pcCU, uiAbsPartIdx );
1191
1192    if(pcCU->getIPCMFlag(uiAbsPartIdx))
1193    {
1194      // Encode slice finish
1195      finishCU(pcCU,uiAbsPartIdx,uiDepth);
1196      return;
1197    }
1198  }
1199
1200  // prediction Info ( Intra : direction mode, Inter : Mv, reference idx )
1201  m_pcEntropyCoder->encodePredInfo( pcCU, uiAbsPartIdx );
1202 
1203  // Encode Coefficients
1204  Bool bCodeDQP = getdQPFlag();
1205  m_pcEntropyCoder->encodeCoeff( pcCU, uiAbsPartIdx, uiDepth, pcCU->getWidth (uiAbsPartIdx), pcCU->getHeight(uiAbsPartIdx), bCodeDQP );
1206  setdQPFlag( bCodeDQP );
1207
1208  // --- write terminating bit ---
1209  finishCU(pcCU,uiAbsPartIdx,uiDepth);
1210}
1211
1212Int xCalcHADs8x8_ISlice(Pel *piOrg, Int iStrideOrg) 
1213{
1214  Int k, i, j, jj;
1215  Int diff[64], m1[8][8], m2[8][8], m3[8][8], iSumHad = 0;
1216
1217  for( k = 0; k < 64; k += 8 )
1218  {
1219    diff[k+0] = piOrg[0] ;
1220    diff[k+1] = piOrg[1] ;
1221    diff[k+2] = piOrg[2] ;
1222    diff[k+3] = piOrg[3] ;
1223    diff[k+4] = piOrg[4] ;
1224    diff[k+5] = piOrg[5] ;
1225    diff[k+6] = piOrg[6] ;
1226    diff[k+7] = piOrg[7] ;
1227 
1228    piOrg += iStrideOrg;
1229  }
1230 
1231  //horizontal
1232  for (j=0; j < 8; j++)
1233  {
1234    jj = j << 3;
1235    m2[j][0] = diff[jj  ] + diff[jj+4];
1236    m2[j][1] = diff[jj+1] + diff[jj+5];
1237    m2[j][2] = diff[jj+2] + diff[jj+6];
1238    m2[j][3] = diff[jj+3] + diff[jj+7];
1239    m2[j][4] = diff[jj  ] - diff[jj+4];
1240    m2[j][5] = diff[jj+1] - diff[jj+5];
1241    m2[j][6] = diff[jj+2] - diff[jj+6];
1242    m2[j][7] = diff[jj+3] - diff[jj+7];
1243   
1244    m1[j][0] = m2[j][0] + m2[j][2];
1245    m1[j][1] = m2[j][1] + m2[j][3];
1246    m1[j][2] = m2[j][0] - m2[j][2];
1247    m1[j][3] = m2[j][1] - m2[j][3];
1248    m1[j][4] = m2[j][4] + m2[j][6];
1249    m1[j][5] = m2[j][5] + m2[j][7];
1250    m1[j][6] = m2[j][4] - m2[j][6];
1251    m1[j][7] = m2[j][5] - m2[j][7];
1252   
1253    m2[j][0] = m1[j][0] + m1[j][1];
1254    m2[j][1] = m1[j][0] - m1[j][1];
1255    m2[j][2] = m1[j][2] + m1[j][3];
1256    m2[j][3] = m1[j][2] - m1[j][3];
1257    m2[j][4] = m1[j][4] + m1[j][5];
1258    m2[j][5] = m1[j][4] - m1[j][5];
1259    m2[j][6] = m1[j][6] + m1[j][7];
1260    m2[j][7] = m1[j][6] - m1[j][7];
1261  }
1262 
1263  //vertical
1264  for (i=0; i < 8; i++)
1265  {
1266    m3[0][i] = m2[0][i] + m2[4][i];
1267    m3[1][i] = m2[1][i] + m2[5][i];
1268    m3[2][i] = m2[2][i] + m2[6][i];
1269    m3[3][i] = m2[3][i] + m2[7][i];
1270    m3[4][i] = m2[0][i] - m2[4][i];
1271    m3[5][i] = m2[1][i] - m2[5][i];
1272    m3[6][i] = m2[2][i] - m2[6][i];
1273    m3[7][i] = m2[3][i] - m2[7][i];
1274   
1275    m1[0][i] = m3[0][i] + m3[2][i];
1276    m1[1][i] = m3[1][i] + m3[3][i];
1277    m1[2][i] = m3[0][i] - m3[2][i];
1278    m1[3][i] = m3[1][i] - m3[3][i];
1279    m1[4][i] = m3[4][i] + m3[6][i];
1280    m1[5][i] = m3[5][i] + m3[7][i];
1281    m1[6][i] = m3[4][i] - m3[6][i];
1282    m1[7][i] = m3[5][i] - m3[7][i];
1283   
1284    m2[0][i] = m1[0][i] + m1[1][i];
1285    m2[1][i] = m1[0][i] - m1[1][i];
1286    m2[2][i] = m1[2][i] + m1[3][i];
1287    m2[3][i] = m1[2][i] - m1[3][i];
1288    m2[4][i] = m1[4][i] + m1[5][i];
1289    m2[5][i] = m1[4][i] - m1[5][i];
1290    m2[6][i] = m1[6][i] + m1[7][i];
1291    m2[7][i] = m1[6][i] - m1[7][i];
1292  }
1293 
1294  for (i = 0; i < 8; i++)
1295  {
1296    for (j = 0; j < 8; j++)
1297    {
1298      iSumHad += abs(m2[i][j]);
1299    }
1300  }
1301  iSumHad -= abs(m2[0][0]);
1302  iSumHad =(iSumHad+2)>>2;
1303  return(iSumHad);
1304}
1305
1306Int  TEncCu::updateLCUDataISlice(TComDataCU* pcCU, Int LCUIdx, Int width, Int height)
1307{
1308  Int  xBl, yBl; 
1309  const Int iBlkSize = 8;
1310
1311  Pel* pOrgInit   = pcCU->getPic()->getPicYuvOrg()->getLumaAddr(pcCU->getAddr(), 0);
1312  Int  iStrideOrig = pcCU->getPic()->getPicYuvOrg()->getStride();
1313  Pel  *pOrg;
1314
1315  Int iSumHad = 0;
1316  for ( yBl=0; (yBl+iBlkSize)<=height; yBl+= iBlkSize)
1317  {
1318    for ( xBl=0; (xBl+iBlkSize)<=width; xBl+= iBlkSize)
1319    {
1320      pOrg = pOrgInit + iStrideOrig*yBl + xBl; 
1321      iSumHad += xCalcHADs8x8_ISlice(pOrg, iStrideOrig);
1322    }
1323  }
1324  return(iSumHad);
1325}
1326
1327/** check RD costs for a CU block encoded with merge
1328 * \param rpcBestCU
1329 * \param rpcTempCU
1330 * \returns Void
1331 */
1332#if HIGHER_LAYER_IRAP_SKIP_FLAG
1333Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool *earlyDetectionSkipMode, Bool bUseSkip )
1334#else
1335Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool *earlyDetectionSkipMode )
1336#endif
1337{
1338  assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );
1339  TComMvField  cMvFieldNeighbours[ 2 * MRG_MAX_NUM_CANDS ]; // double length for mv of both lists
1340  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
1341  Int numValidMergeCand = 0;
1342
1343  for( UInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )
1344  {
1345    uhInterDirNeighbours[ui] = 0;
1346  }
1347  UChar uhDepth = rpcTempCU->getDepth( 0 );
1348  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
1349  rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );
1350  rpcTempCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
1351
1352  Int mergeCandBuffer[MRG_MAX_NUM_CANDS];
1353  for( UInt ui = 0; ui < numValidMergeCand; ++ui )
1354  {
1355    mergeCandBuffer[ui] = 0;
1356  }
1357
1358  Bool bestIsSkip = false;
1359
1360  UInt iteration;
1361  if ( rpcTempCU->isLosslessCoded(0))
1362  {
1363    iteration = 1;
1364  }
1365  else 
1366  {
1367    iteration = 2;
1368  }
1369
1370#if HIGHER_LAYER_IRAP_SKIP_FLAG
1371  for( UInt uiNoResidual = bUseSkip?1:0; uiNoResidual < iteration; ++uiNoResidual )
1372#else
1373  for( UInt uiNoResidual = 0; uiNoResidual < iteration; ++uiNoResidual )
1374#endif
1375  {
1376    for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
1377    {
1378#if REF_IDX_ME_ZEROMV
1379      Bool bZeroMVILR = rpcTempCU->xCheckZeroMVILRMerge(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]);
1380      if(bZeroMVILR)
1381      {
1382#endif
1383#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
1384      if (!(rpcTempCU->isInterLayerReference(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]) && m_disableILP))
1385      {
1386#endif
1387      if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))
1388      {
1389        if( !(bestIsSkip && uiNoResidual == 0) )
1390        {
1391          // set MC parameters
1392          rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth ); // interprets depth relative to LCU level
1393          rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(),     0, uhDepth );
1394          rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
1395          rpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth ); // interprets depth relative to LCU level
1396          rpcTempCU->setMergeIndexSubParts( uiMergeCand, 0, 0, uhDepth ); // interprets depth relative to LCU level
1397          rpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth ); // interprets depth relative to LCU level
1398          rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level
1399          rpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level
1400         
1401          // do MC
1402          m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
1403          // estimate residual and encode everything
1404          m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,
1405                                                    m_ppcOrigYuv    [uhDepth],
1406                                                    m_ppcPredYuvTemp[uhDepth],
1407                                                    m_ppcResiYuvTemp[uhDepth],
1408                                                    m_ppcResiYuvBest[uhDepth],
1409                                                    m_ppcRecoYuvTemp[uhDepth],
1410                                                    (uiNoResidual? true:false));
1411         
1412         
1413          if ( uiNoResidual == 0 && rpcTempCU->getQtRootCbf(0) == 0 )
1414          {
1415            // If no residual when allowing for one, then set mark to not try case where residual is forced to 0
1416            mergeCandBuffer[uiMergeCand] = 1;
1417          }
1418         
1419          rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf(0) == 0, 0, uhDepth );
1420          Int orgQP = rpcTempCU->getQP( 0 );
1421          xCheckDQP( rpcTempCU );
1422          xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
1423          rpcTempCU->initEstData( uhDepth, orgQP );
1424         
1425          if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip )
1426          {
1427            bestIsSkip = rpcBestCU->getQtRootCbf(0) == 0;
1428          }
1429        }
1430      }
1431#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
1432      }
1433#endif
1434#if REF_IDX_ME_ZEROMV
1435      }
1436#endif
1437  }
1438
1439  if(uiNoResidual == 0 && m_pcEncCfg->getUseEarlySkipDetection())
1440  {
1441    if(rpcBestCU->getQtRootCbf( 0 ) == 0)
1442    {
1443      if( rpcBestCU->getMergeFlag( 0 ))
1444      {
1445        *earlyDetectionSkipMode = true;
1446      }
1447      else
1448      {
1449        Int absoulte_MV=0;
1450        for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
1451        {
1452          if ( rpcBestCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
1453          {
1454            TComCUMvField* pcCUMvField = rpcBestCU->getCUMvField(RefPicList( uiRefListIdx ));
1455            Int iHor = pcCUMvField->getMvd( 0 ).getAbsHor();
1456            Int iVer = pcCUMvField->getMvd( 0 ).getAbsVer();
1457            absoulte_MV+=iHor+iVer;
1458          }
1459        }
1460
1461        if(absoulte_MV == 0)
1462        {
1463          *earlyDetectionSkipMode = true;
1464        }
1465      }
1466    }
1467  }
1468 }
1469}
1470
1471
1472#if AMP_MRG
1473Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize, Bool bUseMRG)
1474#else
1475Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
1476#endif
1477{
1478  UChar uhDepth = rpcTempCU->getDepth( 0 );
1479 
1480  rpcTempCU->setDepthSubParts( uhDepth, 0 );
1481 
1482  rpcTempCU->setSkipFlagSubParts( false, 0, uhDepth );
1483
1484  rpcTempCU->setPartSizeSubParts  ( ePartSize,  0, uhDepth );
1485  rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );
1486  rpcTempCU->setCUTransquantBypassSubParts  ( m_pcEncCfg->getCUTransquantBypassFlagValue(),      0, uhDepth );
1487 
1488#if AMP_MRG
1489  rpcTempCU->setMergeAMP (true);
1490  m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth], false, bUseMRG );
1491#else 
1492  m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
1493#endif
1494
1495#if AMP_MRG
1496  if ( !rpcTempCU->getMergeAMP() )
1497  {
1498    return;
1499  }
1500#endif
1501
1502  m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false );
1503  rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1504
1505  xCheckDQP( rpcTempCU );
1506  xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
1507}
1508
1509Void TEncCu::xCheckRDCostIntra( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize eSize )
1510{
1511  UInt uiDepth = rpcTempCU->getDepth( 0 );
1512 
1513  rpcTempCU->setSkipFlagSubParts( false, 0, uiDepth );
1514
1515  rpcTempCU->setPartSizeSubParts( eSize, 0, uiDepth );
1516  rpcTempCU->setPredModeSubParts( MODE_INTRA, 0, uiDepth );
1517  rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uiDepth );
1518 
1519  Bool bSeparateLumaChroma = true; // choose estimation mode
1520  UInt uiPreCalcDistC      = 0;
1521  if( !bSeparateLumaChroma )
1522  {
1523    m_pcPredSearch->preestChromaPredMode( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth] );
1524  }
1525  m_pcPredSearch  ->estIntraPredQT      ( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], uiPreCalcDistC, bSeparateLumaChroma );
1526
1527  m_ppcRecoYuvTemp[uiDepth]->copyToPicLuma(rpcTempCU->getPic()->getPicYuvRec(), rpcTempCU->getAddr(), rpcTempCU->getZorderIdxInCU() );
1528 
1529  m_pcPredSearch  ->estIntraPredChromaQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], uiPreCalcDistC );
1530 
1531  m_pcEntropyCoder->resetBits();
1532  if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
1533  {
1534    m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, 0,          true );
1535  }
1536  m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, 0,          true );
1537  m_pcEntropyCoder->encodePredMode( rpcTempCU, 0,          true );
1538  m_pcEntropyCoder->encodePartSize( rpcTempCU, 0, uiDepth, true );
1539  m_pcEntropyCoder->encodePredInfo( rpcTempCU, 0,          true );
1540  m_pcEntropyCoder->encodeIPCMInfo(rpcTempCU, 0, true );
1541
1542  // Encode Coefficients
1543  Bool bCodeDQP = getdQPFlag();
1544  m_pcEntropyCoder->encodeCoeff( rpcTempCU, 0, uiDepth, rpcTempCU->getWidth (0), rpcTempCU->getHeight(0), bCodeDQP );
1545  setdQPFlag( bCodeDQP );
1546 
1547  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
1548 
1549  rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
1550  if(m_pcEncCfg->getUseSBACRD())
1551  {
1552    rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
1553  }
1554  rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1555 
1556  xCheckDQP( rpcTempCU );
1557  xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth);
1558}
1559
1560/** Check R-D costs for a CU with PCM mode.
1561 * \param rpcBestCU pointer to best mode CU data structure
1562 * \param rpcTempCU pointer to testing mode CU data structure
1563 * \returns Void
1564 *
1565 * \note Current PCM implementation encodes sample values in a lossless way. The distortion of PCM mode CUs are zero. PCM mode is selected if the best mode yields bits greater than that of PCM mode.
1566 */
1567Void TEncCu::xCheckIntraPCM( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
1568{
1569  UInt uiDepth = rpcTempCU->getDepth( 0 );
1570
1571  rpcTempCU->setSkipFlagSubParts( false, 0, uiDepth );
1572
1573  rpcTempCU->setIPCMFlag(0, true);
1574  rpcTempCU->setIPCMFlagSubParts (true, 0, rpcTempCU->getDepth(0));
1575  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
1576  rpcTempCU->setPredModeSubParts( MODE_INTRA, 0, uiDepth );
1577  rpcTempCU->setTrIdxSubParts ( 0, 0, uiDepth );
1578  rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uiDepth );
1579
1580  m_pcPredSearch->IPCMSearch( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth]);
1581
1582  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
1583
1584  m_pcEntropyCoder->resetBits();
1585  if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
1586  {
1587    m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, 0,          true );
1588  }
1589  m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, 0,          true );
1590  m_pcEntropyCoder->encodePredMode ( rpcTempCU, 0,          true );
1591  m_pcEntropyCoder->encodePartSize ( rpcTempCU, 0, uiDepth, true );
1592  m_pcEntropyCoder->encodeIPCMInfo ( rpcTempCU, 0, true );
1593
1594  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
1595
1596  rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
1597  if(m_pcEncCfg->getUseSBACRD())
1598  {
1599    rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
1600  }
1601  rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1602
1603  xCheckDQP( rpcTempCU );
1604  xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth );
1605}
1606
1607/** check whether current try is the best with identifying the depth of current try
1608 * \param rpcBestCU
1609 * \param rpcTempCU
1610 * \returns Void
1611 */
1612Void TEncCu::xCheckBestMode( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth )
1613{
1614  if( rpcTempCU->getTotalCost() < rpcBestCU->getTotalCost() )
1615  {
1616    TComYuv* pcYuv;
1617    // Change Information data
1618    TComDataCU* pcCU = rpcBestCU;
1619    rpcBestCU = rpcTempCU;
1620    rpcTempCU = pcCU;
1621
1622    // Change Prediction data
1623    pcYuv = m_ppcPredYuvBest[uiDepth];
1624    m_ppcPredYuvBest[uiDepth] = m_ppcPredYuvTemp[uiDepth];
1625    m_ppcPredYuvTemp[uiDepth] = pcYuv;
1626
1627    // Change Reconstruction data
1628    pcYuv = m_ppcRecoYuvBest[uiDepth];
1629    m_ppcRecoYuvBest[uiDepth] = m_ppcRecoYuvTemp[uiDepth];
1630    m_ppcRecoYuvTemp[uiDepth] = pcYuv;
1631
1632    pcYuv = NULL;
1633    pcCU  = NULL;
1634
1635    if( m_bUseSBACRD )  // store temp best CI for next CU coding
1636      m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]->store(m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]);
1637  }
1638}
1639
1640Void TEncCu::xCheckDQP( TComDataCU* pcCU )
1641{
1642  UInt uiDepth = pcCU->getDepth( 0 );
1643
1644  if( pcCU->getSlice()->getPPS()->getUseDQP() && (g_uiMaxCUWidth>>uiDepth) >= pcCU->getSlice()->getPPS()->getMinCuDQPSize() )
1645  {
1646    if ( pcCU->getCbf( 0, TEXT_LUMA, 0 ) || pcCU->getCbf( 0, TEXT_CHROMA_U, 0 ) || pcCU->getCbf( 0, TEXT_CHROMA_V, 0 ) )
1647    {
1648#if !RDO_WITHOUT_DQP_BITS
1649      m_pcEntropyCoder->resetBits();
1650      m_pcEntropyCoder->encodeQP( pcCU, 0, false );
1651      pcCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
1652      if(m_pcEncCfg->getUseSBACRD())
1653      {
1654        pcCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
1655      }
1656      pcCU->getTotalCost() = m_pcRdCost->calcRdCost( pcCU->getTotalBits(), pcCU->getTotalDistortion() );
1657#endif
1658    }
1659    else
1660    {
1661      pcCU->setQPSubParts( pcCU->getRefQP( 0 ), 0, uiDepth ); // set QP to default QP
1662    }
1663  }
1664}
1665
1666Void TEncCu::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
1667{
1668  pDst->iN = pSrc->iN;
1669  for (Int i = 0; i < pSrc->iN; i++)
1670  {
1671    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
1672  }
1673}
1674Void TEncCu::xCopyYuv2Pic(TComPic* rpcPic, UInt uiCUAddr, UInt uiAbsPartIdx, UInt uiDepth, UInt uiSrcDepth, TComDataCU* pcCU, UInt uiLPelX, UInt uiTPelY )
1675{
1676  UInt uiRPelX   = uiLPelX + (g_uiMaxCUWidth>>uiDepth)  - 1;
1677  UInt uiBPelY   = uiTPelY + (g_uiMaxCUHeight>>uiDepth) - 1;
1678  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
1679  Bool bSliceStart = pcSlice->getSliceSegmentCurStartCUAddr() > rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx && 
1680    pcSlice->getSliceSegmentCurStartCUAddr() < rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+( pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1) );
1681  Bool bSliceEnd   = pcSlice->getSliceSegmentCurEndCUAddr() > rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx && 
1682    pcSlice->getSliceSegmentCurEndCUAddr() < rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+( pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1) );
1683#if REPN_FORMAT_IN_VPS
1684  if(!bSliceEnd && !bSliceStart && ( uiRPelX < pcSlice->getPicWidthInLumaSamples()           ) && ( uiBPelY < pcSlice->getPicHeightInLumaSamples()           ) )
1685#else
1686  if(!bSliceEnd && !bSliceStart && ( uiRPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiBPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1687#endif
1688  {
1689    UInt uiAbsPartIdxInRaster = g_auiZscanToRaster[uiAbsPartIdx];
1690    UInt uiSrcBlkWidth = rpcPic->getNumPartInWidth() >> (uiSrcDepth);
1691    UInt uiBlkWidth    = rpcPic->getNumPartInWidth() >> (uiDepth);
1692    UInt uiPartIdxX = ( ( uiAbsPartIdxInRaster % rpcPic->getNumPartInWidth() ) % uiSrcBlkWidth) / uiBlkWidth;
1693    UInt uiPartIdxY = ( ( uiAbsPartIdxInRaster / rpcPic->getNumPartInWidth() ) % uiSrcBlkWidth) / uiBlkWidth;
1694    UInt uiPartIdx = uiPartIdxY * ( uiSrcBlkWidth / uiBlkWidth ) + uiPartIdxX;
1695    m_ppcRecoYuvBest[uiSrcDepth]->copyToPicYuv( rpcPic->getPicYuvRec (), uiCUAddr, uiAbsPartIdx, uiDepth - uiSrcDepth, uiPartIdx);
1696  }
1697  else
1698  {
1699    UInt uiQNumParts = ( pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1) )>>2;
1700
1701    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++, uiAbsPartIdx+=uiQNumParts )
1702    {
1703      UInt uiSubCULPelX   = uiLPelX + ( g_uiMaxCUWidth >>(uiDepth+1) )*( uiPartUnitIdx &  1 );
1704      UInt uiSubCUTPelY   = uiTPelY + ( g_uiMaxCUHeight>>(uiDepth+1) )*( uiPartUnitIdx >> 1 );
1705
1706      Bool bInSlice = rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+uiQNumParts > pcSlice->getSliceSegmentCurStartCUAddr() && 
1707        rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx < pcSlice->getSliceSegmentCurEndCUAddr();
1708#if REPN_FORMAT_IN_VPS
1709      if(bInSlice&&( uiSubCULPelX < pcSlice->getPicWidthInLumaSamples()           ) && ( uiSubCUTPelY < pcSlice->getPicHeightInLumaSamples()           ) )
1710#else
1711      if(bInSlice&&( uiSubCULPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiSubCUTPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1712#endif
1713      {
1714        xCopyYuv2Pic( rpcPic, uiCUAddr, uiAbsPartIdx, uiDepth+1, uiSrcDepth, pcCU, uiSubCULPelX, uiSubCUTPelY );   // Copy Yuv data to picture Yuv
1715      }
1716    }
1717  }
1718}
1719
1720Void TEncCu::xCopyYuv2Tmp( UInt uiPartUnitIdx, UInt uiNextDepth )
1721{
1722  UInt uiCurrDepth = uiNextDepth - 1;
1723  m_ppcRecoYuvBest[uiNextDepth]->copyToPartYuv( m_ppcRecoYuvTemp[uiCurrDepth], uiPartUnitIdx );
1724}
1725
1726/** Function for filling the PCM buffer of a CU using its original sample array
1727 * \param pcCU pointer to current CU
1728 * \param pcOrgYuv pointer to original sample array
1729 * \returns Void
1730 */
1731Void TEncCu::xFillPCMBuffer     ( TComDataCU*& pCU, TComYuv* pOrgYuv )
1732{
1733
1734  UInt   width        = pCU->getWidth(0);
1735  UInt   height       = pCU->getHeight(0);
1736
1737  Pel*   pSrcY = pOrgYuv->getLumaAddr(0, width); 
1738  Pel*   pDstY = pCU->getPCMSampleY();
1739  UInt   srcStride = pOrgYuv->getStride();
1740
1741  for(Int y = 0; y < height; y++ )
1742  {
1743    for(Int x = 0; x < width; x++ )
1744    {
1745      pDstY[x] = pSrcY[x];
1746    }
1747    pDstY += width;
1748    pSrcY += srcStride;
1749  }
1750
1751  Pel* pSrcCb       = pOrgYuv->getCbAddr();
1752  Pel* pSrcCr       = pOrgYuv->getCrAddr();;
1753
1754  Pel* pDstCb       = pCU->getPCMSampleCb();
1755  Pel* pDstCr       = pCU->getPCMSampleCr();;
1756
1757  UInt srcStrideC = pOrgYuv->getCStride();
1758  UInt heightC   = height >> 1;
1759  UInt widthC    = width  >> 1;
1760
1761  for(Int y = 0; y < heightC; y++ )
1762  {
1763    for(Int x = 0; x < widthC; x++ )
1764    {
1765      pDstCb[x] = pSrcCb[x];
1766      pDstCr[x] = pSrcCr[x];
1767    }
1768    pDstCb += widthC;
1769    pDstCr += widthC;
1770    pSrcCb += srcStrideC;
1771    pSrcCr += srcStrideC;
1772  }
1773}
1774
1775#if ADAPTIVE_QP_SELECTION
1776/** Collect ARL statistics from one block
1777  */
1778Int TEncCu::xTuCollectARLStats(TCoeff* rpcCoeff, Int* rpcArlCoeff, Int NumCoeffInCU, Double* cSum, UInt* numSamples )
1779{
1780  for( Int n = 0; n < NumCoeffInCU; n++ )
1781  {
1782    Int u = abs( rpcCoeff[ n ] );
1783    Int absc = rpcArlCoeff[ n ];
1784
1785    if( u != 0 )
1786    {
1787      if( u < LEVEL_RANGE )
1788      {
1789        cSum[ u ] += ( Double )absc;
1790        numSamples[ u ]++;
1791      }
1792      else 
1793      {
1794        cSum[ LEVEL_RANGE ] += ( Double )absc - ( Double )( u << ARL_C_PRECISION );
1795        numSamples[ LEVEL_RANGE ]++;
1796      }
1797    }
1798  }
1799
1800  return 0;
1801}
1802
1803#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
1804Bool TEncCu::xCheckTileSetConstraint( TComDataCU*& rpcCU )
1805{
1806  Bool disableILP = false;
1807
1808  if (rpcCU->getLayerId() == (m_pcEncCfg->getNumLayer() - 1)  && m_pcEncCfg->getInterLayerConstrainedTileSetsSEIEnabled() && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(rpcCU->getAddr()) >= 0)
1809  {
1810    if (rpcCU->getPic()->getPicSym()->getTileSetType(rpcCU->getAddr()) == 2)
1811    {
1812      disableILP = true;
1813    }
1814    if (rpcCU->getPic()->getPicSym()->getTileSetType(rpcCU->getAddr()) == 1)
1815    {
1816      Int currCUaddr = rpcCU->getAddr();
1817      Int frameWitdhInCU  = rpcCU->getPic()->getPicSym()->getFrameWidthInCU();
1818      Int frameHeightInCU = rpcCU->getPic()->getPicSym()->getFrameHeightInCU();
1819      Bool leftCUExists   = (currCUaddr % frameWitdhInCU) > 0;
1820      Bool aboveCUExists  = (currCUaddr / frameWitdhInCU) > 0;
1821      Bool rightCUExists  = (currCUaddr % frameWitdhInCU) < (frameWitdhInCU - 1);
1822      Bool belowCUExists  = (currCUaddr / frameWitdhInCU) < (frameHeightInCU - 1);
1823      Int currTileSetIdx  = rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr);
1824      // Check if CU is at tile set boundary
1825      if ( (leftCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr-1) != currTileSetIdx) ||
1826           (leftCUExists && aboveCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr-frameWitdhInCU-1) != currTileSetIdx) ||
1827           (aboveCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr-frameWitdhInCU) != currTileSetIdx) ||
1828           (aboveCUExists && rightCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr-frameWitdhInCU+1) != currTileSetIdx) ||
1829           (rightCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr+1) != currTileSetIdx) ||
1830           (rightCUExists && belowCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr+frameWitdhInCU+1) != currTileSetIdx) ||
1831           (belowCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr+frameWitdhInCU) != currTileSetIdx) ||
1832           (belowCUExists && leftCUExists && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(currCUaddr+frameWitdhInCU-1) != currTileSetIdx) )
1833      {
1834        disableILP = true;  // Disable ILP in tile set boundary CU
1835      }
1836    }
1837  }
1838
1839  return disableILP;
1840}
1841
1842Void TEncCu::xVerifyTileSetConstraint( TComDataCU*& rpcCU )
1843{
1844  if (rpcCU->getLayerId() == (m_pcEncCfg->getNumLayer() - 1)  && m_pcEncCfg->getInterLayerConstrainedTileSetsSEIEnabled() && rpcCU->getPic()->getPicSym()->getTileSetIdxMap(rpcCU->getAddr()) >= 0 &&
1845      m_disableILP)
1846  {
1847    UInt numPartitions = rpcCU->getPic()->getNumPartInCU();
1848    for (UInt i = 0; i < numPartitions; i++)
1849    {
1850      if (!rpcCU->isIntra(i))
1851      {
1852        for (UInt refList = 0; refList < 2; refList++)
1853        {
1854          if (rpcCU->getInterDir(i) & (1<<refList))
1855          {
1856            TComCUMvField *mvField = rpcCU->getCUMvField(RefPicList(refList));
1857            if (mvField->getRefIdx(i) >= 0)
1858            {
1859              assert(!(rpcCU->getSlice()->getRefPic(RefPicList(refList), mvField->getRefIdx(i))->isILR(rpcCU->getLayerId())));
1860            }
1861          }
1862        }
1863      }
1864    }
1865  }
1866}
1867#endif
1868
1869/** Collect ARL statistics from one LCU
1870 * \param pcCU
1871 */
1872Void TEncCu::xLcuCollectARLStats(TComDataCU* rpcCU )
1873{
1874  Double cSum[ LEVEL_RANGE + 1 ];     //: the sum of DCT coefficients corresponding to datatype and quantization output
1875  UInt numSamples[ LEVEL_RANGE + 1 ]; //: the number of coefficients corresponding to datatype and quantization output
1876
1877  TCoeff* pCoeffY = rpcCU->getCoeffY();
1878  Int* pArlCoeffY = rpcCU->getArlCoeffY();
1879
1880  UInt uiMinCUWidth = g_uiMaxCUWidth >> g_uiMaxCUDepth;
1881  UInt uiMinNumCoeffInCU = 1 << uiMinCUWidth;
1882
1883  memset( cSum, 0, sizeof( Double )*(LEVEL_RANGE+1) );
1884  memset( numSamples, 0, sizeof( UInt )*(LEVEL_RANGE+1) );
1885
1886  // Collect stats to cSum[][] and numSamples[][]
1887  for(Int i = 0; i < rpcCU->getTotalNumPart(); i ++ )
1888  {
1889    UInt uiTrIdx = rpcCU->getTransformIdx(i);
1890
1891    if(rpcCU->getPredictionMode(i) == MODE_INTER)
1892    if( rpcCU->getCbf( i, TEXT_LUMA, uiTrIdx ) )
1893    {
1894      xTuCollectARLStats(pCoeffY, pArlCoeffY, uiMinNumCoeffInCU, cSum, numSamples);
1895    }//Note that only InterY is processed. QP rounding is based on InterY data only.
1896   
1897    pCoeffY  += uiMinNumCoeffInCU;
1898    pArlCoeffY  += uiMinNumCoeffInCU;
1899  }
1900
1901  for(Int u=1; u<LEVEL_RANGE;u++)
1902  {
1903    m_pcTrQuant->getSliceSumC()[u] += cSum[ u ] ;
1904    m_pcTrQuant->getSliceNSamples()[u] += numSamples[ u ] ;
1905  }
1906  m_pcTrQuant->getSliceSumC()[LEVEL_RANGE] += cSum[ LEVEL_RANGE ] ;
1907  m_pcTrQuant->getSliceNSamples()[LEVEL_RANGE] += numSamples[ LEVEL_RANGE ] ;
1908}
1909#endif
1910
1911#if (ENCODER_FAST_MODE)
1912Void TEncCu::xCheckRDCostILRUni(TComDataCU *&rpcBestCU, TComDataCU *&rpcTempCU, UInt refLayerId)
1913{
1914  UChar uhDepth = rpcTempCU->getDepth( 0 );
1915  rpcTempCU->setDepthSubParts( uhDepth, 0 );
1916#if SKIP_FLAG
1917  rpcTempCU->setSkipFlagSubParts( false, 0, uhDepth );
1918#endif
1919  rpcTempCU->setPartSizeSubParts  ( SIZE_2Nx2N,  0, uhDepth );  //2Nx2N
1920  rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );
1921  rpcTempCU->setCUTransquantBypassSubParts  ( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );
1922  Bool exitILR = m_pcPredSearch->predInterSearchILRUni( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth], refLayerId );
1923  if(!exitILR)
1924  {
1925     return;
1926  }
1927  m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false );
1928  rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1929  xCheckDQP( rpcTempCU );
1930  xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
1931  return;
1932}
1933#endif
1934//! \}
Note: See TracBrowser for help on using the repository browser.