source: SHVCSoftware/branches/SHM-4.1-dev/source/Lib/TLibEncoder/TEncCu.cpp @ 525

Last change on this file since 525 was 524, checked in by ericsson, 12 years ago

JCTVC-O0199: Skip picture at ARC switch (MACRO: HIGHER_LAYER_IRAP_SKIP_FLAG)

Support for coding higher layer picture as skip at ARC switching by setting SkipPictureAtArcSwitch to 1.

From: Jonatan Samuelsson <jonatan.samuelsson@…>

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