source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibEncoder/TEncCu.cpp @ 824

Last change on this file since 824 was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

File size: 72.0 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    for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
474    {
475      if (isAddLowestQP && (iQP == iMinQP))
476      {
477        iQP = lowestQP;
478      }
479      // variables for fast encoder decision
480      bEarlySkip  = false;
481      bTrySplit    = true;
482      fRD_Skip    = MAX_DOUBLE;
483
484      rpcTempCU->initEstData( uiDepth, iQP );
485
486      // do inter modes, SKIP and 2Nx2N
487      if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
488      {
489        // 2Nx2N
490        if(m_pcEncCfg->getUseEarlySkipDetection())
491        {
492          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData( uiDepth, iQP );//by Competition for inter_2Nx2N
493        }
494        // SKIP
495        xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode );//by Merge for inter_2Nx2N
496        rpcTempCU->initEstData( uiDepth, iQP );
497
498        // fast encoder decision for early skip
499        if ( m_pcEncCfg->getUseFastEnc() )
500        {
501          Int iIdx = g_aucConvertToBit[ rpcBestCU->getWidth(0) ];
502          if ( aiNum [ iIdx ] > 5 && fRD_Skip < EARLY_SKIP_THRES*afCost[ iIdx ]/aiNum[ iIdx ] )
503          {
504            bEarlySkip = true;
505            bTrySplit  = false;
506          }
507        }
508
509    if(!m_pcEncCfg->getUseEarlySkipDetection())
510    {
511        // 2Nx2N, NxN
512        if ( !bEarlySkip )
513        {
514          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData( uiDepth, iQP );
515          if(m_pcEncCfg->getUseCbfFastMode())
516          {
517            doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
518          }
519        }
520    }
521
522      }
523
524      if( (g_uiMaxCUWidth>>uiDepth) >= rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() )
525      {
526        if(iQP == iBaseQP)
527        {
528          bTrySplitDQP = bTrySplit;
529        }
530      }
531      else
532      {
533        bTrySplitDQP = bTrySplit;
534      }
535      if (isAddLowestQP && (iQP == lowestQP))
536      {
537        iQP = iMinQP;
538      }
539    }
540
541  if(!earlyDetectionSkipMode)
542  {
543    for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
544    {
545      if (isAddLowestQP && (iQP == iMinQP))
546      {
547        iQP = lowestQP;
548      }
549      rpcTempCU->initEstData( uiDepth, iQP );
550
551      // do inter modes, NxN, 2NxN, and Nx2N
552      if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
553      {
554        // 2Nx2N, NxN
555        if ( !bEarlySkip )
556        {
557          if(!( (rpcBestCU->getWidth(0)==8) && (rpcBestCU->getHeight(0)==8) ))
558        {
559          if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth && doNotBlockPu)
560          {
561            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN   );
562            rpcTempCU->initEstData( uiDepth, iQP );
563          }
564        }
565        }
566
567        { // 2NxN, Nx2N
568          if(doNotBlockPu)
569          {
570            xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_Nx2N  );
571            rpcTempCU->initEstData( uiDepth, iQP );
572            if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_Nx2N )
573            {
574              doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
575            }
576          }
577          if(doNotBlockPu)
578          {
579            xCheckRDCostInter      ( rpcBestCU, rpcTempCU, SIZE_2NxN  );
580            rpcTempCU->initEstData( uiDepth, iQP );
581            if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxN)
582            {
583              doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
584            }
585          }
586        }
587
588#if 1
589        //! Try AMP (SIZE_2NxnU, SIZE_2NxnD, SIZE_nLx2N, SIZE_nRx2N)
590        if( pcPic->getSlice(0)->getSPS()->getAMPAcc(uiDepth) )
591        {
592#if AMP_ENC_SPEEDUP       
593          Bool bTestAMP_Hor = false, bTestAMP_Ver = false;
594
595#if AMP_MRG
596          Bool bTestMergeAMP_Hor = false, bTestMergeAMP_Ver = false;
597
598          deriveTestModeAMP (rpcBestCU, eParentPartSize, bTestAMP_Hor, bTestAMP_Ver, bTestMergeAMP_Hor, bTestMergeAMP_Ver);
599#else
600          deriveTestModeAMP (rpcBestCU, eParentPartSize, bTestAMP_Hor, bTestAMP_Ver);
601#endif
602
603          //! Do horizontal AMP
604          if ( bTestAMP_Hor )
605          {
606            if(doNotBlockPu)
607            {
608              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnU );
609              rpcTempCU->initEstData( uiDepth, iQP );
610              if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnU )
611              {
612                doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
613              }
614            }
615            if(doNotBlockPu)
616            {
617              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnD );
618              rpcTempCU->initEstData( uiDepth, iQP );
619              if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnD )
620              {
621                doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
622              }
623            }
624          }
625#if AMP_MRG
626          else if ( bTestMergeAMP_Hor ) 
627          {
628            if(doNotBlockPu)
629            {
630              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnU, true );
631              rpcTempCU->initEstData( uiDepth, iQP );
632              if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnU )
633              {
634                doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
635              }
636            }
637            if(doNotBlockPu)
638            {
639              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnD, true );
640              rpcTempCU->initEstData( uiDepth, iQP );
641              if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_2NxnD )
642              {
643                doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
644              }
645            }
646          }
647#endif
648
649          //! Do horizontal AMP
650          if ( bTestAMP_Ver )
651          {
652            if(doNotBlockPu)
653            {
654              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nLx2N );
655              rpcTempCU->initEstData( uiDepth, iQP );
656              if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_nLx2N )
657              {
658                doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
659              }
660            }
661            if(doNotBlockPu)
662            {
663              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nRx2N );
664              rpcTempCU->initEstData( uiDepth, iQP );
665            }
666          }
667#if AMP_MRG
668          else if ( bTestMergeAMP_Ver )
669          {
670            if(doNotBlockPu)
671            {
672              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nLx2N, true );
673              rpcTempCU->initEstData( uiDepth, iQP );
674              if(m_pcEncCfg->getUseCbfFastMode() && rpcBestCU->getPartitionSize(0) == SIZE_nLx2N )
675              {
676                doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
677              }
678            }
679            if(doNotBlockPu)
680            {
681              xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nRx2N, true );
682              rpcTempCU->initEstData( uiDepth, iQP );
683            }
684          }
685#endif
686
687#else
688          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnU );
689          rpcTempCU->initEstData( uiDepth, iQP );
690          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2NxnD );
691          rpcTempCU->initEstData( uiDepth, iQP );
692          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nLx2N );
693          rpcTempCU->initEstData( uiDepth, iQP );
694
695          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_nRx2N );
696          rpcTempCU->initEstData( uiDepth, iQP );
697
698#endif
699        }   
700#endif
701      }
702
703      // initialize PCM flag
704      rpcTempCU->setIPCMFlag( 0, false);
705      rpcTempCU->setIPCMFlagSubParts ( false, 0, uiDepth); //SUB_LCU_DQP
706
707      // do normal intra modes
708      if ( !bEarlySkip )
709      {
710        // speedup for inter frames
711        if( rpcBestCU->getSlice()->getSliceType() == I_SLICE || 
712          rpcBestCU->getCbf( 0, TEXT_LUMA     ) != 0   ||
713          rpcBestCU->getCbf( 0, TEXT_CHROMA_U ) != 0   ||
714          rpcBestCU->getCbf( 0, TEXT_CHROMA_V ) != 0     ) // avoid very complex intra if it is unlikely
715        {
716          xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_2Nx2N );
717          rpcTempCU->initEstData( uiDepth, iQP );
718          if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth )
719          {
720            if( rpcTempCU->getWidth(0) > ( 1 << rpcTempCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() ) )
721            {
722              xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_NxN   );
723              rpcTempCU->initEstData( uiDepth, iQP );
724            }
725          }
726        }
727      }
728
729      // test PCM
730      if(pcPic->getSlice(0)->getSPS()->getUsePCM()
731        && rpcTempCU->getWidth(0) <= (1<<pcPic->getSlice(0)->getSPS()->getPCMLog2MaxSize())
732        && rpcTempCU->getWidth(0) >= (1<<pcPic->getSlice(0)->getSPS()->getPCMLog2MinSize()) )
733      {
734        UInt uiRawBits = (g_uiBitDepth * rpcBestCU->getWidth(0) * rpcBestCU->getHeight(0) * 3 / 2);
735        UInt uiBestBits = rpcBestCU->getTotalBits();
736        if((uiBestBits > uiRawBits) || (rpcBestCU->getTotalCost() > m_pcRdCost->calcRdCost(uiRawBits, 0)))
737        {
738          xCheckIntraPCM (rpcBestCU, rpcTempCU);
739          rpcTempCU->initEstData( uiDepth, iQP );
740        }
741      }
742#if INTRA_BL
743      if(m_pcPicYuvRecBase)
744      {
745        xCheckRDCostIntraBL( rpcBestCU, rpcTempCU );
746        rpcTempCU->initEstData( uiDepth, iQP );
747      }
748#endif
749      if (isAddLowestQP && (iQP == lowestQP))
750      {
751        iQP = iMinQP;
752      }
753    }
754
755  }
756
757    m_pcEntropyCoder->resetBits();
758    m_pcEntropyCoder->encodeSplitFlag( rpcBestCU, 0, uiDepth, true );
759    rpcBestCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
760    if(m_pcEncCfg->getUseSBACRD())
761    {
762      rpcBestCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
763    }
764    rpcBestCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcBestCU->getTotalBits(), rpcBestCU->getTotalDistortion() );
765
766    // accumulate statistics for early skip
767    if ( m_pcEncCfg->getUseFastEnc() )
768    {
769      if ( rpcBestCU->isSkipped(0) )
770      {
771        Int iIdx = g_aucConvertToBit[ rpcBestCU->getWidth(0) ];
772        afCost[ iIdx ] += rpcBestCU->getTotalCost();
773        aiNum [ iIdx ] ++;
774      }
775    }
776
777    // Early CU determination
778    if( m_pcEncCfg->getUseEarlyCU() && rpcBestCU->isSkipped(0) )
779    {
780      bSubBranch = false;
781    }
782    else
783    {
784      bSubBranch = true;
785    }
786  }
787  else if(!(bSliceEnd && bInsidePicture))
788  {
789    bBoundary = true;
790  }
791
792  // copy orginal YUV samples to PCM buffer
793  if( rpcBestCU->isLosslessCoded(0) && (rpcBestCU->getIPCMFlag(0) == false))
794  {
795    xFillPCMBuffer(rpcBestCU, m_ppcOrigYuv[uiDepth]);
796  }
797  if( (g_uiMaxCUWidth>>uiDepth) == rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() )
798  {
799    Int idQP = m_pcEncCfg->getMaxDeltaQP();
800    iMinQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP-idQP );
801    iMaxQP = Clip3( -rpcTempCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQP+idQP );
802    if ( (rpcTempCU->getSlice()->getSPS()->getUseLossless()) && (lowestQP < iMinQP) && rpcTempCU->getSlice()->getPPS()->getUseDQP() )
803    {
804      isAddLowestQP = true;
805      iMinQP = iMinQP - 1;     
806    }
807  }
808  else if( (g_uiMaxCUWidth>>uiDepth) > rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() )
809  {
810    iMinQP = iBaseQP;
811    iMaxQP = iBaseQP;
812  }
813  else
814  {
815    Int iStartQP;
816    if( pcPic->getCU( rpcTempCU->getAddr() )->getDependentSliceStartCU(rpcTempCU->getZorderIdxInCU()) == pcSlice->getDependentSliceCurStartCUAddr())
817    {
818      iStartQP = rpcTempCU->getQP(0);
819    }
820    else
821    {
822      UInt uiCurSliceStartPartIdx = pcSlice->getDependentSliceCurStartCUAddr() % pcPic->getNumPartInCU() - rpcTempCU->getZorderIdxInCU();
823      iStartQP = rpcTempCU->getQP(uiCurSliceStartPartIdx);
824    }
825    iMinQP = iStartQP;
826    iMaxQP = iStartQP;
827  }
828  if(m_pcEncCfg->getUseRateCtrl())
829  {
830    Int qp = m_pcRateCtrl->getUnitQP();
831    iMinQP  = Clip3( MIN_QP, MAX_QP, qp);
832    iMaxQP  = Clip3( MIN_QP, MAX_QP, qp);
833  }
834  for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
835  {
836      if (isAddLowestQP && (iQP == iMinQP))
837      {
838        iQP = lowestQP;
839      }
840    rpcTempCU->initEstData( uiDepth, iQP );
841
842    // further split
843    if( bSubBranch && bTrySplitDQP && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth )
844    {
845      UChar       uhNextDepth         = uiDepth+1;
846      TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
847      TComDataCU* pcSubTempPartCU     = m_ppcTempCU[uhNextDepth];
848
849      for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )
850      {
851        pcSubBestPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
852        pcSubTempPartCU->initSubCU( rpcTempCU, uiPartUnitIdx, uhNextDepth, iQP );           // clear sub partition datas or init.
853
854        Bool bInSlice = pcSubBestPartCU->getSCUAddr()+pcSubBestPartCU->getTotalNumPart()>pcSlice->getDependentSliceCurStartCUAddr()&&pcSubBestPartCU->getSCUAddr()<pcSlice->getDependentSliceCurEndCUAddr();
855        if(bInSlice && ( pcSubBestPartCU->getCUPelX() < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( pcSubBestPartCU->getCUPelY() < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
856        {
857          if( m_bUseSBACRD )
858          {
859            if ( 0 == uiPartUnitIdx) //initialize RD with previous depth buffer
860            {
861              m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
862            }
863            else
864            {
865              m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
866            }
867          }
868
869#if AMP_ENC_SPEEDUP
870          if ( rpcBestCU->isIntra(0) )
871          {
872            xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, SIZE_NONE );
873          }
874          else
875          {
876            xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth, rpcBestCU->getPartitionSize(0) );
877          }
878#else
879          xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth );
880#endif
881
882          rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );         // Keep best part data to current temporary data.
883          xCopyYuv2Tmp( pcSubBestPartCU->getTotalNumPart()*uiPartUnitIdx, uhNextDepth );
884        }
885        else if (bInSlice)
886        {
887          pcSubBestPartCU->copyToPic( uhNextDepth );
888          rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );
889        }
890      }
891
892      if( !bBoundary )
893      {
894        m_pcEntropyCoder->resetBits();
895        m_pcEntropyCoder->encodeSplitFlag( rpcTempCU, 0, uiDepth, true );
896
897        rpcTempCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
898        if(m_pcEncCfg->getUseSBACRD())
899        {
900          rpcTempCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
901        }
902      }
903      rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
904
905      if( (g_uiMaxCUWidth>>uiDepth) == rpcTempCU->getSlice()->getPPS()->getMinCuDQPSize() && rpcTempCU->getSlice()->getPPS()->getUseDQP())
906      {
907        Bool hasResidual = false;
908        for( UInt uiBlkIdx = 0; uiBlkIdx < rpcTempCU->getTotalNumPart(); uiBlkIdx ++)
909        {
910          if( ( pcPic->getCU( rpcTempCU->getAddr() )->getDependentSliceStartCU(uiBlkIdx+rpcTempCU->getZorderIdxInCU()) == rpcTempCU->getSlice()->getDependentSliceCurStartCUAddr() ) && 
911              ( rpcTempCU->getCbf( uiBlkIdx, TEXT_LUMA ) || rpcTempCU->getCbf( uiBlkIdx, TEXT_CHROMA_U ) || rpcTempCU->getCbf( uiBlkIdx, TEXT_CHROMA_V ) ) )
912          {
913            hasResidual = true;
914            break;
915          }
916        }
917
918        UInt uiTargetPartIdx;
919        if ( pcPic->getCU( rpcTempCU->getAddr() )->getDependentSliceStartCU(rpcTempCU->getZorderIdxInCU()) != pcSlice->getDependentSliceCurStartCUAddr() )
920        {
921          uiTargetPartIdx = pcSlice->getDependentSliceCurStartCUAddr() % pcPic->getNumPartInCU() - rpcTempCU->getZorderIdxInCU();
922        }
923        else
924        {
925          uiTargetPartIdx = 0;
926        }
927        if ( hasResidual )
928        {
929#if !RDO_WITHOUT_DQP_BITS
930          m_pcEntropyCoder->resetBits();
931          m_pcEntropyCoder->encodeQP( rpcTempCU, uiTargetPartIdx, false );
932          rpcTempCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
933          if(m_pcEncCfg->getUseSBACRD())
934          {
935            rpcTempCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
936          }
937          rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
938#endif
939
940          Bool foundNonZeroCbf = false;
941          rpcTempCU->setQPSubCUs( rpcTempCU->getRefQP( uiTargetPartIdx ), rpcTempCU, 0, uiDepth, foundNonZeroCbf );
942          assert( foundNonZeroCbf );
943        }
944        else
945        {
946          rpcTempCU->setQPSubParts( rpcTempCU->getRefQP( uiTargetPartIdx ), 0, uiDepth ); // set QP to default QP
947        }
948      }
949
950      if( m_bUseSBACRD )
951      {
952        m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
953      }
954      Bool bEntropyLimit=false;
955      Bool bSliceLimit=false;
956      bSliceLimit=rpcBestCU->getSlice()->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE&&(rpcBestCU->getTotalBits()>rpcBestCU->getSlice()->getSliceArgument()<<3);
957      if(rpcBestCU->getSlice()->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE&&m_pcEncCfg->getUseSBACRD())
958      {
959        if(rpcBestCU->getTotalBins()>rpcBestCU->getSlice()->getDependentSliceArgument())
960        {
961          bEntropyLimit=true;
962        }
963      }
964      else if(rpcBestCU->getSlice()->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE)
965      {
966        if(rpcBestCU->getTotalBits()>rpcBestCU->getSlice()->getDependentSliceArgument())
967        {
968          bEntropyLimit=true;
969        }
970      }
971#if !REMOVE_FGS
972      if(rpcBestCU->getDepth(0)>=rpcBestCU->getSlice()->getPPS()->getSliceGranularity())
973#endif
974      {
975        bSliceLimit=false;
976        bEntropyLimit=false;
977      }
978      if(bSliceLimit||bEntropyLimit)
979      {
980        rpcBestCU->getTotalCost()=rpcTempCU->getTotalCost()+1;
981      }
982      xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth);                                  // RD compare current larger prediction
983    }                                                                                  // with sub partitioned prediction.
984      if (isAddLowestQP && (iQP == lowestQP))
985      {
986        iQP = iMinQP;
987      }
988  }
989
990  rpcBestCU->copyToPic(uiDepth);                                                     // Copy Best data to Picture for next partition prediction.
991
992  xCopyYuv2Pic( rpcBestCU->getPic(), rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU(), uiDepth, uiDepth, rpcBestCU, uiLPelX, uiTPelY );   // Copy Yuv data to picture Yuv
993  if( bBoundary ||(bSliceEnd && bInsidePicture))
994  {
995    return;
996  }
997
998  // Assert if Best prediction mode is NONE
999  // Selected mode's RD-cost must be not MAX_DOUBLE.
1000  assert( rpcBestCU->getPartitionSize ( 0 ) != SIZE_NONE  );
1001  assert( rpcBestCU->getPredictionMode( 0 ) != MODE_NONE  );
1002  assert( rpcBestCU->getTotalCost     (   ) != MAX_DOUBLE );
1003}
1004
1005/** finish encoding a cu and handle end-of-slice conditions
1006 * \param pcCU
1007 * \param uiAbsPartIdx
1008 * \param uiDepth
1009 * \returns Void
1010 */
1011Void TEncCu::finishCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
1012{
1013  TComPic* pcPic = pcCU->getPic();
1014  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
1015
1016  //Calculate end address
1017  UInt uiCUAddr = pcCU->getSCUAddr()+uiAbsPartIdx;
1018
1019  UInt uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurEndCUAddr()-1) % pcPic->getNumPartInCU();
1020  UInt uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurEndCUAddr()-1) / pcPic->getNumPartInCU();
1021  UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1022  UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1023  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1024  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1025  while(uiPosX>=uiWidth||uiPosY>=uiHeight)
1026  {
1027    uiInternalAddress--;
1028    uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1029    uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1030  }
1031  uiInternalAddress++;
1032  if(uiInternalAddress==pcCU->getPic()->getNumPartInCU())
1033  {
1034    uiInternalAddress = 0;
1035    uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1036  }
1037  UInt uiRealEndAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
1038
1039  // Encode slice finish
1040  Bool bTerminateSlice = false;
1041  if (uiCUAddr+(pcCU->getPic()->getNumPartInCU()>>(uiDepth<<1)) == uiRealEndAddress)
1042  {
1043    bTerminateSlice = true;
1044  }
1045#if REMOVE_FGS
1046  UInt uiGranularityWidth = g_uiMaxCUWidth;
1047#else
1048  UInt uiGranularityWidth = g_uiMaxCUWidth>>(pcSlice->getPPS()->getSliceGranularity());
1049#endif
1050  uiPosX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1051  uiPosY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1052  Bool granularityBoundary=((uiPosX+pcCU->getWidth(uiAbsPartIdx))%uiGranularityWidth==0||(uiPosX+pcCU->getWidth(uiAbsPartIdx)==uiWidth))
1053    &&((uiPosY+pcCU->getHeight(uiAbsPartIdx))%uiGranularityWidth==0||(uiPosY+pcCU->getHeight(uiAbsPartIdx)==uiHeight));
1054 
1055  if(granularityBoundary && (!(pcCU->getIPCMFlag(uiAbsPartIdx) && ( pcCU->getNumSucIPCM() > 1 ))))
1056  {
1057    // The 1-terminating bit is added to all streams, so don't add it here when it's 1.
1058    if (!bTerminateSlice)
1059      m_pcEntropyCoder->encodeTerminatingBit( bTerminateSlice ? 1 : 0 );
1060  }
1061 
1062  Int numberOfWrittenBits = 0;
1063  if (m_pcBitCounter)
1064  {
1065    numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
1066  }
1067 
1068  // Calculate slice end IF this CU puts us over slice bit size.
1069#if REMOVE_FGS
1070  unsigned iGranularitySize = pcCU->getPic()->getNumPartInCU();
1071#else
1072  unsigned iGranularitySize = pcCU->getPic()->getNumPartInCU()>>(pcSlice->getPPS()->getSliceGranularity()<<1);
1073#endif
1074  int iGranularityEnd = ((pcCU->getSCUAddr()+uiAbsPartIdx)/iGranularitySize)*iGranularitySize;
1075  if(iGranularityEnd<=pcSlice->getDependentSliceCurStartCUAddr()) 
1076  {
1077    iGranularityEnd+=max(iGranularitySize,(pcCU->getPic()->getNumPartInCU()>>(uiDepth<<1)));
1078  }
1079  // Set slice end parameter
1080  if(pcSlice->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE&&!pcSlice->getFinalized()&&pcSlice->getSliceBits()+numberOfWrittenBits>pcSlice->getSliceArgument()<<3) 
1081  {
1082    pcSlice->setDependentSliceCurEndCUAddr(iGranularityEnd);
1083    pcSlice->setSliceCurEndCUAddr(iGranularityEnd);
1084    return;
1085  }
1086  // Set dependent slice end parameter
1087  if(m_pcEncCfg->getUseSBACRD()) 
1088  {
1089    TEncBinCABAC *pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
1090    UInt uiBinsCoded = pppcRDSbacCoder->getBinsCoded();
1091    if(pcSlice->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE&&!pcSlice->getFinalized()&&pcSlice->getDependentSliceCounter()+uiBinsCoded>pcSlice->getDependentSliceArgument())
1092    {
1093      pcSlice->setDependentSliceCurEndCUAddr(iGranularityEnd);
1094      return;
1095    }
1096  }
1097  else
1098  {
1099    if(pcSlice->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE&&!pcSlice->getFinalized()&&pcSlice->getDependentSliceCounter()+numberOfWrittenBits>pcSlice->getDependentSliceArgument()) 
1100    {
1101      pcSlice->setDependentSliceCurEndCUAddr(iGranularityEnd);
1102      return;
1103    }
1104  }
1105  if(granularityBoundary)
1106  {
1107    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
1108    if(m_pcEncCfg->getUseSBACRD()) 
1109    {
1110      TEncBinCABAC *pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
1111      pcSlice->setDependentSliceCounter(pcSlice->getDependentSliceCounter()+pppcRDSbacCoder->getBinsCoded());
1112      pppcRDSbacCoder->setBinsCoded( 0 );
1113    }
1114    else 
1115    {
1116      pcSlice->setDependentSliceCounter(pcSlice->getDependentSliceCounter()+numberOfWrittenBits);
1117    }
1118    if (m_pcBitCounter)
1119    {
1120      m_pcEntropyCoder->resetBits();     
1121    }
1122  }
1123}
1124
1125/** Compute QP for each CU
1126 * \param pcCU Target CU
1127 * \param uiDepth CU depth
1128 * \returns quantization parameter
1129 */
1130Int TEncCu::xComputeQP( TComDataCU* pcCU, UInt uiDepth )
1131{
1132  Int iBaseQp = pcCU->getSlice()->getSliceQp();
1133  Int iQpOffset = 0;
1134  if ( m_pcEncCfg->getUseAdaptiveQP() )
1135  {
1136    TEncPic* pcEPic = dynamic_cast<TEncPic*>( pcCU->getPic() );
1137    UInt uiAQDepth = min( uiDepth, pcEPic->getMaxAQDepth()-1 );
1138    TEncPicQPAdaptationLayer* pcAQLayer = pcEPic->getAQLayer( uiAQDepth );
1139    UInt uiAQUPosX = pcCU->getCUPelX() / pcAQLayer->getAQPartWidth();
1140    UInt uiAQUPosY = pcCU->getCUPelY() / pcAQLayer->getAQPartHeight();
1141    UInt uiAQUStride = pcAQLayer->getAQPartStride();
1142    TEncQPAdaptationUnit* acAQU = pcAQLayer->getQPAdaptationUnit();
1143
1144    Double dMaxQScale = pow(2.0, m_pcEncCfg->getQPAdaptationRange()/6.0);
1145    Double dAvgAct = pcAQLayer->getAvgActivity();
1146    Double dCUAct = acAQU[uiAQUPosY * uiAQUStride + uiAQUPosX].getActivity();
1147    Double dNormAct = (dMaxQScale*dCUAct + dAvgAct) / (dCUAct + dMaxQScale*dAvgAct);
1148    Double dQpOffset = log(dNormAct) / log(2.0) * 6.0;
1149    iQpOffset = Int(floor( dQpOffset + 0.49999 ));
1150  }
1151  return Clip3(-pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, iBaseQp+iQpOffset );
1152}
1153
1154/** encode a CU block recursively
1155 * \param pcCU
1156 * \param uiAbsPartIdx
1157 * \param uiDepth
1158 * \returns Void
1159 */
1160Void TEncCu::xEncodeCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
1161{
1162  TComPic* pcPic = pcCU->getPic();
1163 
1164  Bool bBoundary = false;
1165  UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1166  UInt uiRPelX   = uiLPelX + (g_uiMaxCUWidth>>uiDepth)  - 1;
1167  UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1168  UInt uiBPelY   = uiTPelY + (g_uiMaxCUHeight>>uiDepth) - 1;
1169 
1170  if( getCheckBurstIPCMFlag() )
1171  {
1172    pcCU->setLastCUSucIPCMFlag( checkLastCUSucIPCM( pcCU, uiAbsPartIdx ));
1173    pcCU->setNumSucIPCM( countNumSucIPCM ( pcCU, uiAbsPartIdx ) );
1174  }
1175
1176  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
1177  // If slice start is within this cu...
1178  Bool bSliceStart = pcSlice->getDependentSliceCurStartCUAddr() > pcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx && 
1179    pcSlice->getDependentSliceCurStartCUAddr() < pcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+( pcPic->getNumPartInCU() >> (uiDepth<<1) );
1180  // We need to split, so don't try these modes.
1181  if(!bSliceStart&&( uiRPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiBPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1182  {
1183    m_pcEntropyCoder->encodeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
1184  }
1185  else
1186  {
1187    bBoundary = true;
1188  }
1189 
1190  if( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < (g_uiMaxCUDepth-g_uiAddCUDepth) ) ) || bBoundary )
1191  {
1192    UInt uiQNumParts = ( pcPic->getNumPartInCU() >> (uiDepth<<1) )>>2;
1193    if( (g_uiMaxCUWidth>>uiDepth) == pcCU->getSlice()->getPPS()->getMinCuDQPSize() && pcCU->getSlice()->getPPS()->getUseDQP())
1194    {
1195      setdQPFlag(true);
1196    }
1197    pcCU->setNumSucIPCM(0);
1198    pcCU->setLastCUSucIPCMFlag(false);
1199    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++, uiAbsPartIdx+=uiQNumParts )
1200    {
1201      uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1202      uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1203      Bool bInSlice = pcCU->getSCUAddr()+uiAbsPartIdx+uiQNumParts>pcSlice->getDependentSliceCurStartCUAddr()&&pcCU->getSCUAddr()+uiAbsPartIdx<pcSlice->getDependentSliceCurEndCUAddr();
1204      if(bInSlice&&( uiLPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1205      {
1206        xEncodeCU( pcCU, uiAbsPartIdx, uiDepth+1 );
1207      }
1208    }
1209    return;
1210  }
1211 
1212  if( (g_uiMaxCUWidth>>uiDepth) >= pcCU->getSlice()->getPPS()->getMinCuDQPSize() && pcCU->getSlice()->getPPS()->getUseDQP())
1213  {
1214    setdQPFlag(true);
1215  }
1216  if (pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
1217  {
1218    m_pcEntropyCoder->encodeCUTransquantBypassFlag( pcCU, uiAbsPartIdx );
1219  }
1220  if( !pcCU->getSlice()->isIntra() )
1221  {
1222    m_pcEntropyCoder->encodeSkipFlag( pcCU, uiAbsPartIdx );
1223  }
1224 
1225  if( pcCU->isSkipped( uiAbsPartIdx ) )
1226  {
1227    m_pcEntropyCoder->encodeMergeIndex( pcCU, uiAbsPartIdx, 0 );
1228    finishCU(pcCU,uiAbsPartIdx,uiDepth);
1229    return;
1230  }
1231#if INTRA_BL
1232  m_pcEntropyCoder->encodeIntraBLFlag( pcCU, uiAbsPartIdx );
1233  if ( !pcCU->isIntraBL( uiAbsPartIdx ) )
1234  {
1235#endif
1236  m_pcEntropyCoder->encodePredMode( pcCU, uiAbsPartIdx );
1237 
1238  m_pcEntropyCoder->encodePartSize( pcCU, uiAbsPartIdx, uiDepth );
1239 
1240  if (pcCU->isIntra( uiAbsPartIdx ) && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N )
1241  {
1242    m_pcEntropyCoder->encodeIPCMInfo( pcCU, uiAbsPartIdx );
1243
1244    if(pcCU->getIPCMFlag(uiAbsPartIdx))
1245    {
1246      // Encode slice finish
1247      finishCU(pcCU,uiAbsPartIdx,uiDepth);
1248      return;
1249    }
1250  }
1251
1252  // prediction Info ( Intra : direction mode, Inter : Mv, reference idx )
1253  m_pcEntropyCoder->encodePredInfo( pcCU, uiAbsPartIdx );
1254#if INTRA_BL
1255  }
1256#endif
1257 
1258  // Encode Coefficients
1259  Bool bCodeDQP = getdQPFlag();
1260  m_pcEntropyCoder->encodeCoeff( pcCU, uiAbsPartIdx, uiDepth, pcCU->getWidth (uiAbsPartIdx), pcCU->getHeight(uiAbsPartIdx), bCodeDQP );
1261  setdQPFlag( bCodeDQP );
1262
1263  // --- write terminating bit ---
1264  finishCU(pcCU,uiAbsPartIdx,uiDepth);
1265}
1266
1267/** check RD costs for a CU block encoded with merge
1268 * \param rpcBestCU
1269 * \param rpcTempCU
1270 * \returns Void
1271 */
1272Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool *earlyDetectionSkipMode )
1273{
1274  assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );
1275  TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
1276  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
1277  Int numValidMergeCand = 0;
1278
1279  for( UInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )
1280  {
1281    uhInterDirNeighbours[ui] = 0;
1282  }
1283  UChar uhDepth = rpcTempCU->getDepth( 0 );
1284  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
1285  rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );
1286  rpcTempCU->getInterMergeCandidates( 0, 0, uhDepth, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
1287
1288  Int mergeCandBuffer[MRG_MAX_NUM_CANDS];
1289  for( UInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )
1290  {
1291    mergeCandBuffer[ui] = 0;
1292  }
1293
1294  Bool bestIsSkip = false;
1295
1296  UInt iteration;
1297  if ( rpcTempCU->isLosslessCoded(0))
1298  {
1299    iteration = 1;
1300  }
1301  else 
1302  {
1303    iteration = 2;
1304  }
1305
1306  for( UInt uiNoResidual = 0; uiNoResidual < iteration; ++uiNoResidual )
1307  {
1308    for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
1309    {
1310      {
1311        if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))
1312        {
1313
1314        if( !(bestIsSkip && uiNoResidual == 0) )
1315        {
1316          // set MC parameters
1317          rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth ); // interprets depth relative to LCU level
1318          rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(),     0, uhDepth );
1319          rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
1320          rpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth ); // interprets depth relative to LCU level
1321          rpcTempCU->setMergeIndexSubParts( uiMergeCand, 0, 0, uhDepth ); // interprets depth relative to LCU level
1322          rpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth ); // interprets depth relative to LCU level
1323          rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level
1324          rpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level
1325
1326       // do MC
1327       m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
1328       // estimate residual and encode everything
1329       m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,
1330         m_ppcOrigYuv    [uhDepth],
1331         m_ppcPredYuvTemp[uhDepth],
1332         m_ppcResiYuvTemp[uhDepth],
1333         m_ppcResiYuvBest[uhDepth],
1334         m_ppcRecoYuvTemp[uhDepth],
1335         (uiNoResidual? true:false));
1336
1337
1338       if(uiNoResidual==0)
1339       {
1340         if(rpcTempCU->getQtRootCbf(0) == 0)
1341         {
1342           mergeCandBuffer[uiMergeCand] = 1;
1343         }
1344       }
1345
1346#if SKIP_FLAG
1347       rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf(0) == 0, 0, uhDepth );
1348#endif
1349          Int orgQP = rpcTempCU->getQP( 0 );
1350          xCheckDQP( rpcTempCU );
1351          xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
1352          rpcTempCU->initEstData( uhDepth, orgQP );
1353
1354
1355      if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip )
1356      {
1357        bestIsSkip = rpcBestCU->getQtRootCbf(0) == 0;
1358      }
1359
1360    }
1361    }
1362   }
1363  }
1364
1365  if(uiNoResidual == 0 && m_pcEncCfg->getUseEarlySkipDetection())
1366  {
1367    if(rpcBestCU->getQtRootCbf( 0 ) == 0)
1368    {
1369      if( rpcBestCU->getMergeFlag( 0 ))
1370      {
1371        *earlyDetectionSkipMode = true;
1372      }
1373      else
1374      {
1375        Int absoulte_MV=0;
1376        for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
1377        {
1378          if ( rpcBestCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
1379          {
1380            TComCUMvField* pcCUMvField = rpcBestCU->getCUMvField(RefPicList( uiRefListIdx ));
1381            Int iHor = pcCUMvField->getMvd( 0 ).getAbsHor();
1382            Int iVer = pcCUMvField->getMvd( 0 ).getAbsVer();
1383            absoulte_MV+=iHor+iVer;
1384          }
1385        }
1386
1387        if(absoulte_MV == 0)
1388        {
1389          *earlyDetectionSkipMode = true;
1390        }
1391      }
1392    }
1393  }
1394 }
1395}
1396
1397
1398#if AMP_MRG
1399Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize, Bool bUseMRG)
1400#else
1401Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
1402#endif
1403{
1404  UChar uhDepth = rpcTempCU->getDepth( 0 );
1405 
1406  rpcTempCU->setDepthSubParts( uhDepth, 0 );
1407 
1408#if SKIP_FLAG
1409  rpcTempCU->setSkipFlagSubParts( false, 0, uhDepth );
1410#endif
1411
1412  rpcTempCU->setPartSizeSubParts  ( ePartSize,  0, uhDepth );
1413  rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );
1414  rpcTempCU->setCUTransquantBypassSubParts  ( m_pcEncCfg->getCUTransquantBypassFlagValue(),      0, uhDepth );
1415 
1416#if AMP_MRG
1417  rpcTempCU->setMergeAMP (true);
1418  m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth], false, bUseMRG );
1419#else 
1420  m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
1421#endif
1422
1423#if AMP_MRG
1424  if ( !rpcTempCU->getMergeAMP() )
1425  {
1426    return;
1427  }
1428#endif
1429
1430  m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false );
1431  rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1432
1433  xCheckDQP( rpcTempCU );
1434  xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
1435}
1436
1437Void TEncCu::xCheckRDCostIntra( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize eSize )
1438{
1439  UInt uiDepth = rpcTempCU->getDepth( 0 );
1440 
1441#if SKIP_FLAG
1442  rpcTempCU->setSkipFlagSubParts( false, 0, uiDepth );
1443#endif
1444
1445  rpcTempCU->setPartSizeSubParts( eSize, 0, uiDepth );
1446  rpcTempCU->setPredModeSubParts( MODE_INTRA, 0, uiDepth );
1447  rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uiDepth );
1448 
1449  Bool bSeparateLumaChroma = true; // choose estimation mode
1450  UInt uiPreCalcDistC      = 0;
1451  if( !bSeparateLumaChroma )
1452  {
1453    m_pcPredSearch->preestChromaPredMode( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth] );
1454  }
1455  m_pcPredSearch  ->estIntraPredQT      ( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], uiPreCalcDistC, bSeparateLumaChroma );
1456
1457  m_ppcRecoYuvTemp[uiDepth]->copyToPicLuma(rpcTempCU->getPic()->getPicYuvRec(), rpcTempCU->getAddr(), rpcTempCU->getZorderIdxInCU() );
1458 
1459  m_pcPredSearch  ->estIntraPredChromaQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], uiPreCalcDistC );
1460 
1461  m_pcEntropyCoder->resetBits();
1462#if INTRA_BL
1463  m_pcEntropyCoder->encodeIntraBLFlag ( rpcTempCU, 0,       true );
1464#endif
1465  if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
1466  {
1467    m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, 0,          true );
1468  }
1469  m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, 0,          true );
1470  m_pcEntropyCoder->encodePredMode( rpcTempCU, 0,          true );
1471  m_pcEntropyCoder->encodePartSize( rpcTempCU, 0, uiDepth, true );
1472  m_pcEntropyCoder->encodePredInfo( rpcTempCU, 0,          true );
1473  m_pcEntropyCoder->encodeIPCMInfo(rpcTempCU, 0, true );
1474
1475  // Encode Coefficients
1476  Bool bCodeDQP = getdQPFlag();
1477  m_pcEntropyCoder->encodeCoeff( rpcTempCU, 0, uiDepth, rpcTempCU->getWidth (0), rpcTempCU->getHeight(0), bCodeDQP );
1478  setdQPFlag( bCodeDQP );
1479 
1480  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
1481 
1482  rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
1483  if(m_pcEncCfg->getUseSBACRD())
1484  {
1485    rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
1486  }
1487  rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1488 
1489  xCheckDQP( rpcTempCU );
1490  xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth);
1491}
1492#if INTRA_BL
1493Void TEncCu::xCheckRDCostIntraBL( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
1494{
1495  UInt uiDepth = rpcTempCU->getDepth( 0 );
1496#if SKIP_FLAG
1497  rpcTempCU->setSkipFlagSubParts( false, 0, uiDepth );
1498#endif
1499 
1500  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
1501  rpcTempCU->setPredModeSubParts( MODE_INTRA_BL, 0, uiDepth ); 
1502  rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uiDepth );
1503
1504  m_pcPredSearch->setBaseRecPic( m_pcPicYuvRecBase ); 
1505  m_pcPredSearch->estIntraBLPredQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth] );
1506
1507  m_pcEntropyCoder->resetBits();
1508  m_pcEntropyCoder->encodeIntraBLFlag ( rpcTempCU, 0,       true );
1509  m_pcEntropyCoder->encodeSkipFlag( rpcTempCU, 0,       true );
1510  if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
1511  {
1512    m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, 0,          true );
1513  }
1514
1515  // Encode Coefficients
1516  Bool bCodeDQP = getdQPFlag();
1517  m_pcEntropyCoder->encodeCoeff( rpcTempCU, 0, uiDepth, rpcTempCU->getWidth (0), rpcTempCU->getHeight(0), bCodeDQP );
1518  setdQPFlag( bCodeDQP );
1519 
1520  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
1521 
1522  rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
1523  if(m_pcEncCfg->getUseSBACRD())
1524  {
1525    rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
1526  }
1527  rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1528 
1529  xCheckDQP( rpcTempCU );
1530  xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth);
1531}
1532#endif
1533
1534
1535/** Check R-D costs for a CU with PCM mode.
1536 * \param rpcBestCU pointer to best mode CU data structure
1537 * \param rpcTempCU pointer to testing mode CU data structure
1538 * \returns Void
1539 *
1540 * \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.
1541 */
1542Void TEncCu::xCheckIntraPCM( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
1543{
1544  UInt uiDepth = rpcTempCU->getDepth( 0 );
1545
1546  rpcTempCU->setCUTransquantBypassSubParts(false, 0, uiDepth);
1547
1548#if SKIP_FLAG
1549  rpcTempCU->setSkipFlagSubParts( false, 0, uiDepth );
1550#endif
1551
1552  rpcTempCU->setIPCMFlag(0, true);
1553  rpcTempCU->setIPCMFlagSubParts (true, 0, rpcTempCU->getDepth(0));
1554  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
1555  rpcTempCU->setPredModeSubParts( MODE_INTRA, 0, uiDepth );
1556  rpcTempCU->setTrIdxSubParts ( 0, 0, uiDepth );
1557  rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uiDepth );
1558
1559  m_pcPredSearch->IPCMSearch( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth]);
1560
1561  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
1562
1563  m_pcEntropyCoder->resetBits();
1564#if INTRA_BL
1565  m_pcEntropyCoder->encodeIntraBLFlag ( rpcTempCU, 0,       true );
1566#endif
1567  if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
1568  {
1569    m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, 0,          true );
1570  }
1571  m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, 0,          true );
1572  m_pcEntropyCoder->encodePredMode ( rpcTempCU, 0,          true );
1573  m_pcEntropyCoder->encodePartSize ( rpcTempCU, 0, uiDepth, true );
1574  m_pcEntropyCoder->encodeIPCMInfo ( rpcTempCU, 0, true );
1575
1576  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
1577
1578  rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
1579  if(m_pcEncCfg->getUseSBACRD())
1580  {
1581    rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
1582  }
1583  rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1584
1585  xCheckDQP( rpcTempCU );
1586  xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth );
1587}
1588
1589// check whether current try is the best
1590Void TEncCu::xCheckBestMode( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
1591{
1592  if( rpcTempCU->getTotalCost() < rpcBestCU->getTotalCost() )
1593  {
1594    TComYuv* pcYuv;
1595    UChar uhDepth = rpcBestCU->getDepth(0);
1596
1597    // Change Information data
1598    TComDataCU* pcCU = rpcBestCU;
1599    rpcBestCU = rpcTempCU;
1600    rpcTempCU = pcCU;
1601   
1602    // Change Prediction data
1603    pcYuv = m_ppcPredYuvBest[uhDepth];
1604    m_ppcPredYuvBest[uhDepth] = m_ppcPredYuvTemp[uhDepth];
1605    m_ppcPredYuvTemp[uhDepth] = pcYuv;
1606   
1607    // Change Reconstruction data
1608    pcYuv = m_ppcRecoYuvBest[uhDepth];
1609    m_ppcRecoYuvBest[uhDepth] = m_ppcRecoYuvTemp[uhDepth];
1610    m_ppcRecoYuvTemp[uhDepth] = pcYuv;
1611   
1612    pcYuv = NULL;
1613    pcCU  = NULL;
1614   
1615    if( m_bUseSBACRD )  // store temp best CI for next CU coding
1616      m_pppcRDSbacCoder[uhDepth][CI_TEMP_BEST]->store(m_pppcRDSbacCoder[uhDepth][CI_NEXT_BEST]);
1617  }
1618}
1619
1620/** check whether current try is the best with identifying the depth of current try
1621 * \param rpcBestCU
1622 * \param rpcTempCU
1623 * \returns Void
1624 */
1625Void TEncCu::xCheckBestMode( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth )
1626{
1627  if( rpcTempCU->getTotalCost() < rpcBestCU->getTotalCost() )
1628  {
1629    TComYuv* pcYuv;
1630    // Change Information data
1631    TComDataCU* pcCU = rpcBestCU;
1632    rpcBestCU = rpcTempCU;
1633    rpcTempCU = pcCU;
1634
1635    // Change Prediction data
1636    pcYuv = m_ppcPredYuvBest[uiDepth];
1637    m_ppcPredYuvBest[uiDepth] = m_ppcPredYuvTemp[uiDepth];
1638    m_ppcPredYuvTemp[uiDepth] = pcYuv;
1639
1640    // Change Reconstruction data
1641    pcYuv = m_ppcRecoYuvBest[uiDepth];
1642    m_ppcRecoYuvBest[uiDepth] = m_ppcRecoYuvTemp[uiDepth];
1643    m_ppcRecoYuvTemp[uiDepth] = pcYuv;
1644
1645    pcYuv = NULL;
1646    pcCU  = NULL;
1647
1648    if( m_bUseSBACRD )  // store temp best CI for next CU coding
1649      m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]->store(m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]);
1650  }
1651}
1652
1653Void TEncCu::xCheckDQP( TComDataCU* pcCU )
1654{
1655  UInt uiDepth = pcCU->getDepth( 0 );
1656
1657  if( pcCU->getSlice()->getPPS()->getUseDQP() && (g_uiMaxCUWidth>>uiDepth) >= pcCU->getSlice()->getPPS()->getMinCuDQPSize() )
1658  {
1659    if ( pcCU->getCbf( 0, TEXT_LUMA, 0 ) || pcCU->getCbf( 0, TEXT_CHROMA_U, 0 ) || pcCU->getCbf( 0, TEXT_CHROMA_V, 0 ) )
1660    {
1661#if !RDO_WITHOUT_DQP_BITS
1662      m_pcEntropyCoder->resetBits();
1663      m_pcEntropyCoder->encodeQP( pcCU, 0, false );
1664      pcCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
1665      if(m_pcEncCfg->getUseSBACRD())
1666      {
1667        pcCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
1668      }
1669      pcCU->getTotalCost() = m_pcRdCost->calcRdCost( pcCU->getTotalBits(), pcCU->getTotalDistortion() );
1670#endif
1671    }
1672    else
1673    {
1674      pcCU->setQPSubParts( pcCU->getRefQP( 0 ), 0, uiDepth ); // set QP to default QP
1675    }
1676  }
1677}
1678
1679/** Check whether the last CU shares the same root as the current CU and is IPCM or not. 
1680 * \param pcCU
1681 * \param uiCurAbsPartIdx
1682 * \returns Bool
1683 */
1684Bool TEncCu::checkLastCUSucIPCM( TComDataCU* pcCU, UInt uiCurAbsPartIdx )
1685{
1686  Bool lastCUSucIPCMFlag = false;
1687
1688  UInt curDepth = pcCU->getDepth(uiCurAbsPartIdx);
1689  UInt shift = ((pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx())->getSPS()->getMaxCUDepth() - curDepth)<<1);
1690  UInt startPartUnitIdx = ((uiCurAbsPartIdx&(0x03<<shift))>>shift);
1691
1692  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
1693  if( pcSlice->getDependentSliceCurStartCUAddr() == ( pcCU->getSCUAddr() + uiCurAbsPartIdx ) )
1694  {
1695    return false;
1696  }
1697
1698  if(curDepth > 0 && startPartUnitIdx > 0)
1699  {
1700    Int lastValidPartIdx = pcCU->getLastValidPartIdx((Int) uiCurAbsPartIdx );
1701
1702    if( lastValidPartIdx >= 0 )
1703    {
1704      if(( pcCU->getSliceStartCU( uiCurAbsPartIdx ) == pcCU->getSliceStartCU( (UInt) lastValidPartIdx ))
1705        && 
1706        ( pcCU->getDepth( uiCurAbsPartIdx ) == pcCU->getDepth( (UInt) lastValidPartIdx )) 
1707        && 
1708        pcCU->getIPCMFlag( (UInt) lastValidPartIdx ) )
1709      {
1710        lastCUSucIPCMFlag = true;
1711      }
1712    }
1713  }
1714
1715  return  lastCUSucIPCMFlag;
1716}
1717
1718/** Count the number of successive IPCM CUs sharing the same root.
1719 * \param pcCU
1720 * \param uiCurAbsPartIdx
1721 * \returns Int
1722 */
1723Int TEncCu::countNumSucIPCM ( TComDataCU* pcCU, UInt uiCurAbsPartIdx )
1724{
1725  Int numSucIPCM = 0;
1726  UInt CurDepth = pcCU->getDepth(uiCurAbsPartIdx);
1727
1728  if( pcCU->getIPCMFlag(uiCurAbsPartIdx) )
1729  {
1730    if(CurDepth == 0)
1731    {
1732       numSucIPCM = 1;
1733    }
1734    else 
1735    {
1736      TComPic* pcPic = pcCU->getPic();
1737      TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
1738      UInt qNumParts = ( pcPic->getNumPartInCU() >> ((CurDepth-1)<<1) )>>2;
1739
1740      Bool continueFlag = true;
1741      UInt absPartIdx = uiCurAbsPartIdx;
1742      UInt shift = ((pcSlice->getSPS()->getMaxCUDepth() - CurDepth)<<1);
1743      UInt startPartUnitIdx = ((uiCurAbsPartIdx&(0x03<<shift))>>shift);
1744
1745      for ( UInt partUnitIdx = startPartUnitIdx; partUnitIdx < 4 && continueFlag; partUnitIdx++, absPartIdx+=qNumParts )
1746      {
1747        UInt lPelX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[absPartIdx] ];
1748        UInt tPelY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[absPartIdx] ];
1749        Bool inSliceFlag = ( pcCU->getSCUAddr()+absPartIdx+qNumParts>pcSlice->getDependentSliceCurStartCUAddr() ) && ( pcCU->getSCUAddr()+absPartIdx < pcSlice->getDependentSliceCurEndCUAddr());
1750
1751        if( inSliceFlag && ( lPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( tPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1752        {
1753          UInt uiDepth = pcCU->getDepth(absPartIdx);
1754
1755          if( ( CurDepth == uiDepth) && pcCU->getIPCMFlag( absPartIdx ) )
1756          {
1757            numSucIPCM++;
1758          }
1759          else
1760          {
1761            continueFlag = false;
1762          }
1763        }
1764      }
1765    }
1766  }
1767
1768  return numSucIPCM;
1769}
1770
1771Void TEncCu::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
1772{
1773  pDst->iN = pSrc->iN;
1774  for (Int i = 0; i < pSrc->iN; i++)
1775  {
1776    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
1777  }
1778}
1779Void TEncCu::xCopyYuv2Pic(TComPic* rpcPic, UInt uiCUAddr, UInt uiAbsPartIdx, UInt uiDepth, UInt uiSrcDepth, TComDataCU* pcCU, UInt uiLPelX, UInt uiTPelY )
1780{
1781  UInt uiRPelX   = uiLPelX + (g_uiMaxCUWidth>>uiDepth)  - 1;
1782  UInt uiBPelY   = uiTPelY + (g_uiMaxCUHeight>>uiDepth) - 1;
1783  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
1784  Bool bSliceStart = pcSlice->getDependentSliceCurStartCUAddr() > rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx && 
1785    pcSlice->getDependentSliceCurStartCUAddr() < rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+( pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1) );
1786  Bool bSliceEnd   = pcSlice->getDependentSliceCurEndCUAddr() > rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx && 
1787    pcSlice->getDependentSliceCurEndCUAddr() < rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+( pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1) );
1788  if(!bSliceEnd && !bSliceStart && ( uiRPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiBPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1789  {
1790    UInt uiAbsPartIdxInRaster = g_auiZscanToRaster[uiAbsPartIdx];
1791    UInt uiSrcBlkWidth = rpcPic->getNumPartInWidth() >> (uiSrcDepth);
1792    UInt uiBlkWidth    = rpcPic->getNumPartInWidth() >> (uiDepth);
1793    UInt uiPartIdxX = ( ( uiAbsPartIdxInRaster % rpcPic->getNumPartInWidth() ) % uiSrcBlkWidth) / uiBlkWidth;
1794    UInt uiPartIdxY = ( ( uiAbsPartIdxInRaster / rpcPic->getNumPartInWidth() ) % uiSrcBlkWidth) / uiBlkWidth;
1795    UInt uiPartIdx = uiPartIdxY * ( uiSrcBlkWidth / uiBlkWidth ) + uiPartIdxX;
1796    m_ppcRecoYuvBest[uiSrcDepth]->copyToPicYuv( rpcPic->getPicYuvRec (), uiCUAddr, uiAbsPartIdx, uiDepth - uiSrcDepth, uiPartIdx);
1797  }
1798  else
1799  {
1800    UInt uiQNumParts = ( pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1) )>>2;
1801
1802    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++, uiAbsPartIdx+=uiQNumParts )
1803    {
1804      UInt uiSubCULPelX   = uiLPelX + ( g_uiMaxCUWidth >>(uiDepth+1) )*( uiPartUnitIdx &  1 );
1805      UInt uiSubCUTPelY   = uiTPelY + ( g_uiMaxCUHeight>>(uiDepth+1) )*( uiPartUnitIdx >> 1 );
1806
1807      Bool bInSlice = rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx+uiQNumParts > pcSlice->getDependentSliceCurStartCUAddr() && 
1808        rpcPic->getPicSym()->getInverseCUOrderMap(pcCU->getAddr())*pcCU->getPic()->getNumPartInCU()+uiAbsPartIdx < pcSlice->getDependentSliceCurEndCUAddr();
1809      if(bInSlice&&( uiSubCULPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiSubCUTPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
1810      {
1811        xCopyYuv2Pic( rpcPic, uiCUAddr, uiAbsPartIdx, uiDepth+1, uiSrcDepth, pcCU, uiSubCULPelX, uiSubCUTPelY );   // Copy Yuv data to picture Yuv
1812      }
1813    }
1814  }
1815}
1816
1817Void TEncCu::xCopyYuv2Tmp( UInt uiPartUnitIdx, UInt uiNextDepth )
1818{
1819  UInt uiCurrDepth = uiNextDepth - 1;
1820  m_ppcRecoYuvBest[uiNextDepth]->copyToPartYuv( m_ppcRecoYuvTemp[uiCurrDepth], uiPartUnitIdx );
1821}
1822
1823/** Function for filling the PCM buffer of a CU using its original sample array
1824 * \param pcCU pointer to current CU
1825 * \param pcOrgYuv pointer to original sample array
1826 * \returns Void
1827 */
1828Void TEncCu::xFillPCMBuffer     ( TComDataCU*& pCU, TComYuv* pOrgYuv )
1829{
1830
1831  UInt   width        = pCU->getWidth(0);
1832  UInt   height       = pCU->getHeight(0);
1833
1834  Pel*   pSrcY = pOrgYuv->getLumaAddr(0, width); 
1835  Pel*   pDstY = pCU->getPCMSampleY();
1836  UInt   srcStride = pOrgYuv->getStride();
1837
1838  for(Int y = 0; y < height; y++ )
1839  {
1840    for(Int x = 0; x < width; x++ )
1841    {
1842      pDstY[x] = pSrcY[x];
1843    }
1844    pDstY += width;
1845    pSrcY += srcStride;
1846  }
1847
1848  Pel* pSrcCb       = pOrgYuv->getCbAddr();
1849  Pel* pSrcCr       = pOrgYuv->getCrAddr();;
1850
1851  Pel* pDstCb       = pCU->getPCMSampleCb();
1852  Pel* pDstCr       = pCU->getPCMSampleCr();;
1853
1854  UInt srcStrideC = pOrgYuv->getCStride();
1855  UInt heightC   = height >> 1;
1856  UInt widthC    = width  >> 1;
1857
1858  for(Int y = 0; y < heightC; y++ )
1859  {
1860    for(Int x = 0; x < widthC; x++ )
1861    {
1862      pDstCb[x] = pSrcCb[x];
1863      pDstCr[x] = pSrcCr[x];
1864    }
1865    pDstCb += widthC;
1866    pDstCr += widthC;
1867    pSrcCb += srcStrideC;
1868    pSrcCr += srcStrideC;
1869  }
1870}
1871
1872#if ADAPTIVE_QP_SELECTION
1873/** Collect ARL statistics from one block
1874  */
1875Int TEncCu::xTuCollectARLStats(TCoeff* rpcCoeff, Int* rpcArlCoeff, Int NumCoeffInCU, Double* cSum, UInt* numSamples )
1876{
1877  for( Int n = 0; n < NumCoeffInCU; n++ )
1878  {
1879    Int u = abs( rpcCoeff[ n ] );
1880    Int absc = rpcArlCoeff[ n ];
1881
1882    if( u != 0 )
1883    {
1884      if( u < LEVEL_RANGE )
1885      {
1886        cSum[ u ] += ( Double )absc;
1887        numSamples[ u ]++;
1888      }
1889      else 
1890      {
1891        cSum[ LEVEL_RANGE ] += ( Double )absc - ( Double )( u << ARL_C_PRECISION );
1892        numSamples[ LEVEL_RANGE ]++;
1893      }
1894    }
1895  }
1896
1897  return 0;
1898}
1899
1900/** Collect ARL statistics from one LCU
1901 * \param pcCU
1902 */
1903Void TEncCu::xLcuCollectARLStats(TComDataCU* rpcCU )
1904{
1905  Double cSum[ LEVEL_RANGE + 1 ];     //: the sum of DCT coefficients corresponding to datatype and quantization output
1906  UInt numSamples[ LEVEL_RANGE + 1 ]; //: the number of coefficients corresponding to datatype and quantization output
1907
1908  TCoeff* pCoeffY = rpcCU->getCoeffY();
1909  Int* pArlCoeffY = rpcCU->getArlCoeffY();
1910
1911  UInt uiMinCUWidth = g_uiMaxCUWidth >> g_uiMaxCUDepth;
1912  UInt uiMinNumCoeffInCU = 1 << uiMinCUWidth;
1913
1914  memset( cSum, 0, sizeof( Double )*(LEVEL_RANGE+1) );
1915  memset( numSamples, 0, sizeof( UInt )*(LEVEL_RANGE+1) );
1916
1917  // Collect stats to cSum[][] and numSamples[][]
1918  for(Int i = 0; i < rpcCU->getTotalNumPart(); i ++ )
1919  {
1920    UInt uiTrIdx = rpcCU->getTransformIdx(i);
1921
1922    if(rpcCU->getPredictionMode(i) == MODE_INTER)
1923    if( rpcCU->getCbf( i, TEXT_LUMA, uiTrIdx ) )
1924    {
1925      xTuCollectARLStats(pCoeffY, pArlCoeffY, uiMinNumCoeffInCU, cSum, numSamples);
1926    }//Note that only InterY is processed. QP rounding is based on InterY data only.
1927   
1928    pCoeffY  += uiMinNumCoeffInCU;
1929    pArlCoeffY  += uiMinNumCoeffInCU;
1930  }
1931
1932  for(Int u=1; u<LEVEL_RANGE;u++)
1933  {
1934    m_pcTrQuant->getSliceSumC()[u] += cSum[ u ] ;
1935    m_pcTrQuant->getSliceNSamples()[u] += numSamples[ u ] ;
1936  }
1937  m_pcTrQuant->getSliceSumC()[LEVEL_RANGE] += cSum[ LEVEL_RANGE ] ;
1938  m_pcTrQuant->getSliceNSamples()[LEVEL_RANGE] += numSamples[ LEVEL_RANGE ] ;
1939}
1940#endif
1941//! \}
Note: See TracBrowser for help on using the repository browser.