source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncCu.cpp @ 539

Last change on this file since 539 was 539, checked in by orange, 11 years ago

Integrated QTLPC and added new line mark at the end of TComWedgelet.cpp for MERL

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