source: SHVCSoftware/branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncCu.cpp @ 503

Last change on this file since 503 was 34, checked in by seregin, 12 years ago

Merge with trunk

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