source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComDataCU.cpp

Last change on this file was 1413, checked in by tech, 6 years ago

Merged HTM-16.2-dev@1412

  • Property svn:eol-style set to native
File size: 203.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-2017, 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     TComDataCU.cpp
35    \brief    CU data structure
36    \todo     not all entities are documented
37*/
38
39#include "TComDataCU.h"
40#include "TComTU.h"
41#include "TComPic.h"
42
43//! \ingroup TLibCommon
44//! \{
45
46// ====================================================================================================================
47// Constructor / destructor / create / destroy
48// ====================================================================================================================
49
50TComDataCU::TComDataCU()
51{
52  m_pcPic              = NULL;
53  m_pcSlice            = NULL;
54  m_puhDepth           = NULL;
55
56  m_skipFlag           = NULL;
57#if NH_3D
58  m_bDISFlag           = NULL;
59  m_ucDISType          = NULL;
60#endif
61  m_pePartSize         = NULL;
62  m_pePredMode         = NULL;
63  m_CUTransquantBypass = NULL;
64  m_puhWidth           = NULL;
65  m_puhHeight          = NULL;
66  m_phQP               = NULL;
67  m_ChromaQpAdj        = NULL;
68  m_pbMergeFlag        = NULL;
69  m_puhMergeIndex      = NULL;
70  for(UInt i=0; i<MAX_NUM_CHANNEL_TYPE; i++)
71  {
72    m_puhIntraDir[i]     = NULL;
73  }
74  m_puhInterDir        = NULL;
75  m_puhTrIdx           = NULL;
76
77  for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
78  {
79    m_puhCbf[comp]                        = NULL;
80    m_crossComponentPredictionAlpha[comp] = NULL;
81    m_puhTransformSkip[comp]              = NULL;
82    m_pcTrCoeff[comp]                     = NULL;
83#if ADAPTIVE_QP_SELECTION
84    m_pcArlCoeff[comp]                    = NULL;
85#endif
86    m_pcIPCMSample[comp]                  = NULL;
87    m_explicitRdpcmMode[comp]             = NULL;
88  }
89#if ADAPTIVE_QP_SELECTION
90  m_ArlCoeffIsAliasedAllocation = false;
91#endif
92  m_pbIPCMFlag         = NULL;
93
94  m_pCtuAboveLeft      = NULL;
95  m_pCtuAboveRight     = NULL;
96  m_pCtuAbove          = NULL;
97  m_pCtuLeft           = NULL;
98
99  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
100  {
101    m_apiMVPIdx[i]       = NULL;
102    m_apiMVPNum[i]       = NULL;
103  }
104
105#if NH_3D
106  for( Int i = 0; i < NUM_DMM; i++ )
107  {
108    m_dmmDeltaDC[i][0] = NULL; 
109    m_dmmDeltaDC[i][1] = NULL;
110  }
111  m_dmm1WedgeTabIdx = NULL;
112
113  m_pbSDCFlag             = NULL;
114  m_apSegmentDCOffset[0]  = NULL;
115  m_apSegmentDCOffset[1]  = NULL;
116#endif
117
118  m_bDecSubCu          = false;
119
120#if NH_3D
121  m_pDvInfo              = NULL;
122  m_piVSPFlag            = NULL;
123  m_pbSPIVMPFlag         = NULL;
124  m_puhARPW              = NULL;
125  m_pbICFlag             = NULL;
126  m_pbDBBPFlag         = NULL;
127#endif
128
129}
130
131TComDataCU::~TComDataCU()
132{
133}
134
135Void TComDataCU::create( ChromaFormat chromaFormatIDC, UInt uiNumPartition, UInt uiWidth, UInt uiHeight, Bool bDecSubCu, Int unitSize
136#if ADAPTIVE_QP_SELECTION
137                        , TCoeff *pParentARLBuffer
138#endif
139                        )
140{
141  m_bDecSubCu = bDecSubCu;
142
143  m_pcPic              = NULL;
144  m_pcSlice            = NULL;
145  m_uiNumPartition     = uiNumPartition;
146  m_unitSize = unitSize;
147
148  if ( !bDecSubCu )
149  {
150    m_phQP               = (SChar*    )xMalloc(SChar,    uiNumPartition);
151    m_puhDepth           = (UChar*    )xMalloc(UChar,    uiNumPartition);
152    m_puhWidth           = (UChar*    )xMalloc(UChar,    uiNumPartition);
153    m_puhHeight          = (UChar*    )xMalloc(UChar,    uiNumPartition);
154
155    m_ChromaQpAdj        = new UChar[ uiNumPartition ];
156    m_skipFlag           = new Bool[ uiNumPartition ];
157#if NH_3D
158    m_bDISFlag           = new Bool[ uiNumPartition ];
159    m_ucDISType          = (UChar*)xMalloc(UChar, uiNumPartition);
160#endif
161    m_pePartSize         = new SChar[ uiNumPartition ];
162    memset( m_pePartSize, NUMBER_OF_PART_SIZES,uiNumPartition * sizeof( *m_pePartSize ) );
163    m_pePredMode         = new SChar[ uiNumPartition ];
164    m_CUTransquantBypass = new Bool[ uiNumPartition ];
165
166    m_pbMergeFlag        = (Bool*  )xMalloc(Bool,   uiNumPartition);
167    m_puhMergeIndex      = (UChar* )xMalloc(UChar,  uiNumPartition);
168#if NH_3D
169    m_piVSPFlag          = (SChar* )xMalloc(SChar, uiNumPartition);
170    m_pbSPIVMPFlag       = (Bool*  )xMalloc(Bool,   uiNumPartition);
171#endif
172
173    for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
174    {
175      m_puhIntraDir[ch] = (UChar* )xMalloc(UChar,  uiNumPartition);
176    }
177    m_puhInterDir        = (UChar* )xMalloc(UChar,  uiNumPartition);
178
179    m_puhTrIdx           = (UChar* )xMalloc(UChar,  uiNumPartition);
180
181    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
182    {
183      const RefPicList rpl=RefPicList(i);
184      m_apiMVPIdx[rpl]       = new SChar[ uiNumPartition ];
185      m_apiMVPNum[rpl]       = new SChar[ uiNumPartition ];
186      memset( m_apiMVPIdx[rpl], -1,uiNumPartition * sizeof( SChar ) );
187    }
188
189#if NH_3D
190    m_pDvInfo            = (DisInfo* )xMalloc(DisInfo,  uiNumPartition);
191#endif
192
193
194    for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
195    {
196      const ComponentID compID = ComponentID(comp);
197      const UInt chromaShift = getComponentScaleX(compID, chromaFormatIDC) + getComponentScaleY(compID, chromaFormatIDC);
198      const UInt totalSize   = (uiWidth * uiHeight) >> chromaShift;
199
200      m_crossComponentPredictionAlpha[compID] = (SChar* )xMalloc(SChar,  uiNumPartition);
201      m_puhTransformSkip[compID]              = (UChar* )xMalloc(UChar,  uiNumPartition);
202      m_explicitRdpcmMode[compID]             = (UChar* )xMalloc(UChar,  uiNumPartition);
203      m_puhCbf[compID]                        = (UChar* )xMalloc(UChar,  uiNumPartition);
204      m_pcTrCoeff[compID]                     = (TCoeff*)xMalloc(TCoeff, totalSize);
205      memset( m_pcTrCoeff[compID], 0, (totalSize * sizeof( TCoeff )) );
206
207#if ADAPTIVE_QP_SELECTION
208      if( pParentARLBuffer != 0 )
209      {
210        m_pcArlCoeff[compID] = pParentARLBuffer;
211        m_ArlCoeffIsAliasedAllocation = true;
212        pParentARLBuffer += totalSize;
213      }
214      else
215      {
216        m_pcArlCoeff[compID] = (TCoeff*)xMalloc(TCoeff, totalSize);
217        m_ArlCoeffIsAliasedAllocation = false;
218      }
219#endif
220      m_pcIPCMSample[compID] = (Pel*   )xMalloc(Pel , totalSize);
221    }
222
223    m_pbIPCMFlag         = (Bool*  )xMalloc(Bool, uiNumPartition);
224
225    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
226    {
227      m_acCUMvField[i].create( uiNumPartition );
228    }
229
230#if NH_3D
231    m_puhARPW            = (UChar*  )xMalloc(UChar,   uiNumPartition);
232    m_pbICFlag           = (Bool* )xMalloc(Bool,   uiNumPartition);
233    for( Int i = 0; i < NUM_DMM; i++ )
234    {
235      m_dmmDeltaDC[i][0] = (Pel* )xMalloc(Pel, uiNumPartition); 
236      m_dmmDeltaDC[i][1] = (Pel* )xMalloc(Pel, uiNumPartition);
237    }
238    m_dmm1WedgeTabIdx    = (UInt*)xMalloc(UInt, uiNumPartition);
239    m_pbSDCFlag             = (Bool*)xMalloc(Bool, uiNumPartition);
240    m_apSegmentDCOffset[0]  = (Pel*)xMalloc(Pel, uiNumPartition);
241    m_apSegmentDCOffset[1]  = (Pel*)xMalloc(Pel, uiNumPartition);
242    m_pbDBBPFlag         = (Bool*  )xMalloc(Bool,   uiNumPartition);
243#endif
244
245  }
246  else
247  {
248    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
249    {
250      m_acCUMvField[i].setNumPartition(uiNumPartition );
251    }
252  }
253
254  // create motion vector fields
255
256  m_pCtuAboveLeft      = NULL;
257  m_pCtuAboveRight     = NULL;
258  m_pCtuAbove          = NULL;
259  m_pCtuLeft           = NULL;
260}
261
262Void TComDataCU::destroy()
263{
264  // encoder-side buffer free
265  if ( !m_bDecSubCu )
266  {
267    if ( m_phQP )
268    {
269      xFree(m_phQP);
270      m_phQP = NULL;
271    }
272    if ( m_puhDepth )
273    {
274      xFree(m_puhDepth);
275      m_puhDepth = NULL;
276    }
277    if ( m_puhWidth )
278    {
279      xFree(m_puhWidth);
280      m_puhWidth = NULL;
281    }
282    if ( m_puhHeight )
283    {
284      xFree(m_puhHeight);
285      m_puhHeight = NULL;
286    }
287
288    if ( m_skipFlag )
289    {
290      delete[] m_skipFlag;
291      m_skipFlag = NULL;
292    }
293
294#if NH_3D
295    if ( m_bDISFlag           ) { delete[] m_bDISFlag;   m_bDISFlag     = NULL; }
296    if ( m_ucDISType         ) { xFree(m_ucDISType);  m_ucDISType    = NULL; }
297#endif
298
299    if ( m_pePartSize )
300    {
301      delete[] m_pePartSize;
302      m_pePartSize = NULL;
303    }
304    if ( m_pePredMode )
305    {
306      delete[] m_pePredMode;
307      m_pePredMode = NULL;
308    }
309    if ( m_ChromaQpAdj )
310    {
311      delete[] m_ChromaQpAdj;
312      m_ChromaQpAdj = NULL;
313    }
314    if ( m_CUTransquantBypass )
315    {
316      delete[] m_CUTransquantBypass;
317      m_CUTransquantBypass = NULL;
318    }
319    if ( m_puhInterDir )
320    {
321      xFree(m_puhInterDir);
322      m_puhInterDir = NULL;
323    }
324    if ( m_pbMergeFlag )
325    {
326      xFree(m_pbMergeFlag);
327      m_pbMergeFlag = NULL;
328    }
329    if ( m_puhMergeIndex )
330    {
331      xFree(m_puhMergeIndex);
332      m_puhMergeIndex  = NULL;
333    }
334
335#if NH_3D
336    if ( m_piVSPFlag )
337    {
338      xFree(m_piVSPFlag);
339      m_piVSPFlag = NULL;
340    }
341    if ( m_pbSPIVMPFlag       ) { xFree(m_pbSPIVMPFlag);           m_pbSPIVMPFlag         = NULL; }
342#endif
343
344
345    for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
346    {
347      xFree(m_puhIntraDir[ch]);
348      m_puhIntraDir[ch] = NULL;
349    }
350
351    if ( m_puhTrIdx )
352    {
353      xFree(m_puhTrIdx);
354      m_puhTrIdx = NULL;
355    }
356
357    for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
358    {
359      if ( m_crossComponentPredictionAlpha[comp] )
360      {
361        xFree(m_crossComponentPredictionAlpha[comp]);
362        m_crossComponentPredictionAlpha[comp] = NULL;
363      }
364      if ( m_puhTransformSkip[comp] )
365      {
366        xFree(m_puhTransformSkip[comp]);
367        m_puhTransformSkip[comp] = NULL;
368      }
369      if ( m_puhCbf[comp] )
370      {
371        xFree(m_puhCbf[comp]);
372        m_puhCbf[comp] = NULL;
373      }
374      if ( m_pcTrCoeff[comp] )
375      {
376        xFree(m_pcTrCoeff[comp]);
377        m_pcTrCoeff[comp] = NULL;
378      }
379      if ( m_explicitRdpcmMode[comp] )
380      {
381        xFree(m_explicitRdpcmMode[comp]);
382        m_explicitRdpcmMode[comp] = NULL;
383      }
384
385#if ADAPTIVE_QP_SELECTION
386      if (!m_ArlCoeffIsAliasedAllocation)
387      {
388        if ( m_pcArlCoeff[comp] )
389        {
390          xFree(m_pcArlCoeff[comp]);
391          m_pcArlCoeff[comp] = NULL;
392        }
393      }
394#endif
395
396      if ( m_pcIPCMSample[comp] )
397      {
398        xFree(m_pcIPCMSample[comp]);
399        m_pcIPCMSample[comp] = NULL;
400      }
401    }
402    if ( m_pbIPCMFlag )
403    {
404      xFree(m_pbIPCMFlag );
405      m_pbIPCMFlag = NULL;
406    }
407
408    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
409    {
410      const RefPicList rpl=RefPicList(i);
411      if ( m_apiMVPIdx[rpl] )
412      {
413        delete[] m_apiMVPIdx[rpl];
414        m_apiMVPIdx[rpl] = NULL;
415      }
416      if ( m_apiMVPNum[rpl] )
417      {
418        delete[] m_apiMVPNum[rpl];
419        m_apiMVPNum[rpl] = NULL;
420      }
421    }
422
423    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
424    {
425      const RefPicList rpl=RefPicList(i);
426      m_acCUMvField[rpl].destroy();
427    }
428#if NH_3D
429    if ( m_pDvInfo            ) { xFree(m_pDvInfo);             m_pDvInfo           = NULL; }
430    if ( m_puhARPW            ) { xFree(m_puhARPW);             m_puhARPW           = NULL; }
431    if ( m_pbICFlag           ) { xFree(m_pbICFlag);            m_pbICFlag          = NULL; }
432    for( Int i = 0; i < NUM_DMM; i++ )
433    {
434      if ( m_dmmDeltaDC[i][0] ) { xFree( m_dmmDeltaDC[i][0] ); m_dmmDeltaDC[i][0] = NULL; }
435      if ( m_dmmDeltaDC[i][1] ) { xFree( m_dmmDeltaDC[i][1] ); m_dmmDeltaDC[i][1] = NULL; }
436    }
437    if ( m_dmm1WedgeTabIdx    ) { xFree( m_dmm1WedgeTabIdx );  m_dmm1WedgeTabIdx = NULL;  }
438    if ( m_pbSDCFlag            ) { xFree(m_pbSDCFlag);             m_pbSDCFlag             = NULL; }
439    if ( m_apSegmentDCOffset[0] ) { xFree(m_apSegmentDCOffset[0]);  m_apSegmentDCOffset[0]  = NULL; }
440    if ( m_apSegmentDCOffset[1] ) { xFree(m_apSegmentDCOffset[1]);  m_apSegmentDCOffset[1]  = NULL; }
441    if ( m_pbDBBPFlag           ) { xFree(m_pbDBBPFlag);          m_pbDBBPFlag        = NULL; }
442#endif
443
444  }
445
446  m_pcPic              = NULL;
447  m_pcSlice            = NULL;
448
449  m_pCtuAboveLeft      = NULL;
450  m_pCtuAboveRight     = NULL;
451  m_pCtuAbove          = NULL;
452  m_pCtuLeft           = NULL;
453
454}
455
456Bool TComDataCU::CUIsFromSameTile            ( const TComDataCU *pCU /* Can be NULL */) const
457{
458  return pCU!=NULL &&
459         pCU->getSlice() != NULL &&
460         m_pcPic->getPicSym()->getTileIdxMap( pCU->getCtuRsAddr() ) == m_pcPic->getPicSym()->getTileIdxMap(getCtuRsAddr());
461}
462
463Bool TComDataCU::CUIsFromSameSliceAndTile    ( const TComDataCU *pCU /* Can be NULL */) const
464{
465  return pCU!=NULL &&
466         pCU->getSlice() != NULL &&
467         pCU->getSlice()->getSliceCurStartCtuTsAddr() == getSlice()->getSliceCurStartCtuTsAddr() &&
468         m_pcPic->getPicSym()->getTileIdxMap( pCU->getCtuRsAddr() ) == m_pcPic->getPicSym()->getTileIdxMap(getCtuRsAddr())
469         ;
470}
471
472Bool TComDataCU::CUIsFromSameSliceTileAndWavefrontRow( const TComDataCU *pCU /* Can be NULL */) const
473{
474  return CUIsFromSameSliceAndTile(pCU)
475         && (!getSlice()->getPPS()->getEntropyCodingSyncEnabledFlag() || getPic()->getCtu(getCtuRsAddr())->getCUPelY() == getPic()->getCtu(pCU->getCtuRsAddr())->getCUPelY());
476}
477
478Bool TComDataCU::isLastSubCUOfCtu(const UInt absPartIdx) const
479{
480  const TComSPS &sps=*(getSlice()->getSPS());
481
482  const UInt picWidth = sps.getPicWidthInLumaSamples();
483  const UInt picHeight = sps.getPicHeightInLumaSamples();
484  const UInt granularityWidth = sps.getMaxCUWidth();
485
486  const UInt cuPosX = getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[absPartIdx] ];
487  const UInt cuPosY = getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[absPartIdx] ];
488
489  return (((cuPosX+getWidth( absPartIdx))%granularityWidth==0||(cuPosX+getWidth( absPartIdx)==picWidth ))
490       && ((cuPosY+getHeight(absPartIdx))%granularityWidth==0||(cuPosY+getHeight(absPartIdx)==picHeight)));
491}
492
493// ====================================================================================================================
494// Public member functions
495// ====================================================================================================================
496
497// --------------------------------------------------------------------------------------------------------------------
498// Initialization
499// --------------------------------------------------------------------------------------------------------------------
500
501/**
502 Initialize top-level CU: create internal buffers and set initial values before encoding the CTU.
503 
504 \param  pcPic       picture (TComPic) class pointer
505 \param  ctuRsAddr   CTU address in raster scan order
506 */
507Void TComDataCU::initCtu( TComPic* pcPic, UInt ctuRsAddr )
508{
509
510  const UInt maxCUWidth = pcPic->getPicSym()->getSPS().getMaxCUWidth();
511  const UInt maxCUHeight= pcPic->getPicSym()->getSPS().getMaxCUHeight();
512  m_pcPic              = pcPic;
513  m_pcSlice            = pcPic->getSlice(pcPic->getCurrSliceIdx());
514  m_ctuRsAddr          = ctuRsAddr;
515  m_uiCUPelX           = ( ctuRsAddr % pcPic->getFrameWidthInCtus() ) * maxCUWidth;
516  m_uiCUPelY           = ( ctuRsAddr / pcPic->getFrameWidthInCtus() ) * maxCUHeight;
517  m_absZIdxInCtu       = 0;
518  m_dTotalCost         = MAX_DOUBLE;
519  m_uiTotalDistortion  = 0;
520  m_uiTotalBits        = 0;
521  m_uiTotalBins        = 0;
522  m_uiNumPartition     = pcPic->getNumPartitionsInCtu();
523
524  memset( m_skipFlag          , false,                      m_uiNumPartition * sizeof( *m_skipFlag ) );
525
526#if NH_3D
527    memset( m_bDISFlag        , false,                      m_uiNumPartition * sizeof( *m_bDISFlag ) );
528    memset( m_ucDISType       , false,                      m_uiNumPartition * sizeof( *m_ucDISType ) );
529#endif
530
531  memset( m_pePartSize        , NUMBER_OF_PART_SIZES,       m_uiNumPartition * sizeof( *m_pePartSize ) );
532  memset( m_pePredMode        , NUMBER_OF_PREDICTION_MODES, m_uiNumPartition * sizeof( *m_pePredMode ) );
533  memset( m_CUTransquantBypass, false,                      m_uiNumPartition * sizeof( *m_CUTransquantBypass) );
534  memset( m_puhDepth          , 0,                          m_uiNumPartition * sizeof( *m_puhDepth ) );
535  memset( m_puhTrIdx          , 0,                          m_uiNumPartition * sizeof( *m_puhTrIdx ) );
536  memset( m_puhWidth          , maxCUWidth,                 m_uiNumPartition * sizeof( *m_puhWidth ) );
537  memset( m_puhHeight         , maxCUHeight,                m_uiNumPartition * sizeof( *m_puhHeight ) );
538
539#if NH_3D
540  memset( m_pbICFlag          , false,                      m_uiNumPartition * sizeof( *m_pbICFlag ) );
541#endif
542  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
543  {
544    const RefPicList rpl=RefPicList(i);
545    memset( m_apiMVPIdx[rpl]  , -1,                         m_uiNumPartition * sizeof( *m_apiMVPIdx[rpl] ) );
546    memset( m_apiMVPNum[rpl]  , -1,                         m_uiNumPartition * sizeof( *m_apiMVPNum[rpl] ) );
547  }
548  memset( m_phQP              , getSlice()->getSliceQp(),   m_uiNumPartition * sizeof( *m_phQP ) );
549  memset( m_ChromaQpAdj       , 0,                          m_uiNumPartition * sizeof( *m_ChromaQpAdj ) );
550  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
551  {
552    memset( m_crossComponentPredictionAlpha[comp] , 0,                     m_uiNumPartition * sizeof( *m_crossComponentPredictionAlpha[comp] ) );
553    memset( m_puhTransformSkip[comp]              , 0,                     m_uiNumPartition * sizeof( *m_puhTransformSkip[comp]) );
554    memset( m_puhCbf[comp]                        , 0,                     m_uiNumPartition * sizeof( *m_puhCbf[comp] ) );
555    memset( m_explicitRdpcmMode[comp]             , NUMBER_OF_RDPCM_MODES, m_uiNumPartition * sizeof( *m_explicitRdpcmMode[comp] ) );
556  }
557  memset( m_pbMergeFlag       , false,                    m_uiNumPartition * sizeof( *m_pbMergeFlag ) );
558  memset( m_puhMergeIndex     , 0,                        m_uiNumPartition * sizeof( *m_puhMergeIndex ) );
559
560#if NH_3D
561  memset( m_piVSPFlag         , 0,                        m_uiNumPartition * sizeof( *m_piVSPFlag ) );
562  memset( m_pbSPIVMPFlag      , 0,                     m_uiNumPartition * sizeof( *m_pbSPIVMPFlag ) );   
563  memset( m_pbSDCFlag, false, m_uiNumPartition * sizeof( *m_pbSDCFlag ) );
564  memset( m_pbDBBPFlag , false, m_uiNumPartition * sizeof( *m_pbDBBPFlag ));
565#endif
566
567  for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
568  {
569    memset( m_puhIntraDir[ch] , ((ch==0) ? DC_IDX : 0),   m_uiNumPartition * sizeof( *(m_puhIntraDir[ch]) ) );
570  }
571
572#if NH_3D
573  memset( m_puhARPW      ,      0,        m_uiNumPartition * sizeof( *m_puhARPW )         );
574  for( Int i = 0; i < NUM_DMM; i++ )
575  {
576    memset( m_dmmDeltaDC[i][0], 0,                        m_uiNumPartition * sizeof( *m_dmmDeltaDC[i][0] ) );
577    memset( m_dmmDeltaDC[i][1], 0,                        m_uiNumPartition * sizeof( *m_dmmDeltaDC[i][1] ) );
578  }
579    memset( m_dmm1WedgeTabIdx,    0,                        m_uiNumPartition * sizeof( *m_dmm1WedgeTabIdx   ) );
580    memset( m_pbSDCFlag      ,     false,                m_uiNumPartition * sizeof( *m_pbSDCFlag ) );
581    memset( m_apSegmentDCOffset[0],     0,                m_uiNumPartition * sizeof( *m_apSegmentDCOffset[0] ) );
582    memset( m_apSegmentDCOffset[1],     0,                m_uiNumPartition * sizeof( *m_apSegmentDCOffset[1] ) );
583#endif
584
585  memset( m_puhInterDir       , 0,                        m_uiNumPartition * sizeof( *m_puhInterDir ) );
586  memset( m_pbIPCMFlag        , false,                    m_uiNumPartition * sizeof( *m_pbIPCMFlag ) );
587
588  const UInt numCoeffY    = maxCUWidth*maxCUHeight;
589  for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
590  {
591    const UInt componentShift = m_pcPic->getComponentScaleX(ComponentID(comp)) + m_pcPic->getComponentScaleY(ComponentID(comp));
592    memset( m_pcTrCoeff[comp], 0, sizeof(TCoeff)* numCoeffY>>componentShift );
593#if ADAPTIVE_QP_SELECTION
594    memset( m_pcArlCoeff[comp], 0, sizeof(TCoeff)* numCoeffY>>componentShift );
595#endif
596  }
597
598  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
599  {
600    m_acCUMvField[i].clearMvField();
601  }
602
603  // Setting neighbor CU
604  m_pCtuLeft        = NULL;
605  m_pCtuAbove       = NULL;
606  m_pCtuAboveLeft   = NULL;
607  m_pCtuAboveRight  = NULL;
608
609  UInt frameWidthInCtus = pcPic->getFrameWidthInCtus();
610  if ( m_ctuRsAddr % frameWidthInCtus )
611  {
612    m_pCtuLeft = pcPic->getCtu( m_ctuRsAddr - 1 );
613  }
614
615  if ( m_ctuRsAddr / frameWidthInCtus )
616  {
617    m_pCtuAbove = pcPic->getCtu( m_ctuRsAddr - frameWidthInCtus );
618  }
619
620  if ( m_pCtuLeft && m_pCtuAbove )
621  {
622    m_pCtuAboveLeft = pcPic->getCtu( m_ctuRsAddr - frameWidthInCtus - 1 );
623  }
624
625  if ( m_pCtuAbove && ( (m_ctuRsAddr%frameWidthInCtus) < (frameWidthInCtus-1) )  )
626  {
627    m_pCtuAboveRight = pcPic->getCtu( m_ctuRsAddr - frameWidthInCtus + 1 );
628  }
629}
630
631
632/** Initialize prediction data with enabling sub-CTU-level delta QP.
633*   - set CU width and CU height according to depth
634*   - set qp value according to input qp
635*   - set last-coded qp value according to input last-coded qp
636*
637* \param  uiDepth            depth of the current CU
638* \param  qp                 qp for the current CU
639* \param  bTransquantBypass  true for transquant bypass
640*/
641Void TComDataCU::initEstData( const UInt uiDepth, const Int qp, const Bool bTransquantBypass )
642{
643  m_dTotalCost         = MAX_DOUBLE;
644  m_uiTotalDistortion  = 0;
645  m_uiTotalBits        = 0;
646  m_uiTotalBins        = 0;
647
648  const UChar uhWidth  = getSlice()->getSPS()->getMaxCUWidth()  >> uiDepth;
649  const UChar uhHeight = getSlice()->getSPS()->getMaxCUHeight() >> uiDepth;
650
651  for (UInt ui = 0; ui < m_uiNumPartition; ui++)
652  {
653    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
654    {
655      const RefPicList rpl=RefPicList(i);
656      m_apiMVPIdx[rpl][ui]  = -1;
657      m_apiMVPNum[rpl][ui]  = -1;
658    }
659    m_puhDepth  [ui]    = uiDepth;
660    m_puhWidth  [ui]    = uhWidth;
661    m_puhHeight [ui]    = uhHeight;
662    m_puhTrIdx  [ui]    = 0;
663    for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
664    {
665      m_crossComponentPredictionAlpha[comp][ui] = 0;
666      m_puhTransformSkip             [comp][ui] = 0;
667      m_explicitRdpcmMode            [comp][ui] = NUMBER_OF_RDPCM_MODES;
668    }
669    m_skipFlag[ui]      = false;
670#if NH_3D
671    m_bDISFlag[ui]      = false;
672    m_ucDISType[ui]     = 0;
673#endif
674    m_pePartSize[ui]    = NUMBER_OF_PART_SIZES;
675    m_pePredMode[ui]    = NUMBER_OF_PREDICTION_MODES;
676    m_CUTransquantBypass[ui] = bTransquantBypass;
677    m_pbIPCMFlag[ui]    = 0;
678    m_phQP[ui]          = qp;
679    m_ChromaQpAdj[ui]   = 0;
680    m_pbMergeFlag[ui]   = 0;
681    m_puhMergeIndex[ui] = 0;
682#if NH_3D
683    m_piVSPFlag[ui]     = 0;
684    m_pbSPIVMPFlag[ui] = 0;
685#endif
686
687    for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
688    {
689      m_puhIntraDir[ch][ui] = ((ch==0) ? DC_IDX : 0);
690    }
691
692    m_puhInterDir[ui] = 0;
693    for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
694    {
695      m_puhCbf[comp][ui] = 0;
696    }
697#if NH_3D
698    m_puhARPW[ui] = 0;
699    m_pbICFlag[ui]  = false;
700    for( Int i = 0; i < NUM_DMM; i++ )
701    {
702      m_dmmDeltaDC[i][0]  [ui] = 0;
703      m_dmmDeltaDC[i][1]  [ui] = 0;
704    }
705    m_dmm1WedgeTabIdx     [ui] = 0;
706    m_pbSDCFlag           [ui] = false;
707    m_apSegmentDCOffset[0][ui] = 0;
708    m_apSegmentDCOffset[1][ui] = 0;
709    m_pbDBBPFlag          [ui] = false;
710#endif
711  }
712
713  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
714  {
715    m_acCUMvField[i].clearMvField();
716  }
717
718  const UInt numCoeffY = uhWidth*uhHeight;
719
720  for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
721  {
722    const ComponentID component = ComponentID(comp);
723    const UInt numCoeff = numCoeffY >> (getPic()->getComponentScaleX(component) + getPic()->getComponentScaleY(component));
724    memset( m_pcTrCoeff[comp],    0, numCoeff * sizeof( TCoeff ) );
725#if ADAPTIVE_QP_SELECTION
726    memset( m_pcArlCoeff[comp],   0, numCoeff * sizeof( TCoeff ) );
727#endif
728    memset( m_pcIPCMSample[comp], 0, numCoeff * sizeof( Pel) );
729  }
730}
731
732
733// initialize Sub partition
734Void TComDataCU::initSubCU( TComDataCU* pcCU, UInt uiPartUnitIdx, UInt uiDepth, Int qp )
735{
736  assert( uiPartUnitIdx<4 );
737
738  UInt uiPartOffset = ( pcCU->getTotalNumPart()>>2 )*uiPartUnitIdx;
739
740  m_pcPic              = pcCU->getPic();
741  m_pcSlice            = pcCU->getSlice();
742  m_ctuRsAddr          = pcCU->getCtuRsAddr();
743  m_absZIdxInCtu       = pcCU->getZorderIdxInCtu() + uiPartOffset;
744
745  const UChar uhWidth  = getSlice()->getSPS()->getMaxCUWidth()  >> uiDepth;
746  const UChar uhHeight = getSlice()->getSPS()->getMaxCUHeight() >> uiDepth;
747
748  m_uiCUPelX           = pcCU->getCUPelX() + ( uhWidth )*( uiPartUnitIdx &  1 );
749  m_uiCUPelY           = pcCU->getCUPelY() + ( uhHeight)*( uiPartUnitIdx >> 1 );
750
751  m_dTotalCost         = MAX_DOUBLE;
752  m_uiTotalDistortion  = 0;
753  m_uiTotalBits        = 0;
754  m_uiTotalBins        = 0;
755  m_uiNumPartition     = pcCU->getTotalNumPart() >> 2;
756
757  Int iSizeInUchar = sizeof( UChar  ) * m_uiNumPartition;
758  Int iSizeInBool  = sizeof( Bool   ) * m_uiNumPartition;
759  Int sizeInChar = sizeof( SChar  ) * m_uiNumPartition;
760
761  memset( m_phQP,              qp,  sizeInChar );
762  memset( m_pbMergeFlag,        0, iSizeInBool  );
763  memset( m_puhMergeIndex,      0, iSizeInUchar );
764#if NH_3D
765  memset( m_piVSPFlag,          0, sizeof( SChar ) * m_uiNumPartition );
766  memset( m_pbSPIVMPFlag,       0, sizeof( Bool  ) * m_uiNumPartition );
767#endif
768
769  for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
770  {
771    memset( m_puhIntraDir[ch],  ((ch==0) ? DC_IDX : 0), iSizeInUchar );
772  }
773
774  memset( m_puhInterDir,        0, iSizeInUchar );
775  memset( m_puhTrIdx,           0, iSizeInUchar );
776
777  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
778  {
779    memset( m_crossComponentPredictionAlpha[comp], 0, iSizeInUchar );
780    memset( m_puhTransformSkip[comp],              0, iSizeInUchar );
781    memset( m_puhCbf[comp],                        0, iSizeInUchar );
782    memset( m_explicitRdpcmMode[comp],             NUMBER_OF_RDPCM_MODES, iSizeInUchar );
783  }
784
785  memset( m_puhDepth,     uiDepth, iSizeInUchar );
786  memset( m_puhWidth,          uhWidth,  iSizeInUchar );
787  memset( m_puhHeight,         uhHeight, iSizeInUchar );
788  memset( m_pbIPCMFlag,        0, iSizeInBool  );
789#if NH_3D
790  memset( m_puhARPW,           0, iSizeInUchar  );
791  memset( m_pbICFlag,          0, iSizeInBool  );
792  for( Int i = 0; i < NUM_DMM; i++ )
793  {
794    memset( m_dmmDeltaDC[i][0], 0, sizeof(Pel ) * m_uiNumPartition );
795    memset( m_dmmDeltaDC[i][1], 0, sizeof(Pel ) * m_uiNumPartition );
796  }
797  memset( m_dmm1WedgeTabIdx,    0, sizeof(UInt) * m_uiNumPartition );
798  memset( m_pbSDCFlag,            0, sizeof(Bool) * m_uiNumPartition  );
799  memset( m_apSegmentDCOffset[0], 0, sizeof(Pel) * m_uiNumPartition   );
800  memset( m_apSegmentDCOffset[1], 0, sizeof(Pel) * m_uiNumPartition   );
801  memset( m_pbDBBPFlag,         0, sizeof(Bool) * m_uiNumPartition  );
802#endif
803
804  for (UInt ui = 0; ui < m_uiNumPartition; ui++)
805  {
806    m_skipFlag[ui]   = false;
807#if NH_3D
808    m_bDISFlag[ui]   = false;
809    m_ucDISType[ui]  = 0;
810#endif
811
812    m_pePartSize[ui] = NUMBER_OF_PART_SIZES;
813    m_pePredMode[ui] = NUMBER_OF_PREDICTION_MODES;
814    m_CUTransquantBypass[ui] = false;
815    m_ChromaQpAdj[ui] = 0;
816
817    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
818    {
819      const RefPicList rpl=RefPicList(i);
820      m_apiMVPIdx[rpl][ui] = -1;
821      m_apiMVPNum[rpl][ui] = -1;
822    }
823#if NH_3D
824    m_bDISFlag    [ui] = pcCU->getDISFlag(uiPartOffset+ui);
825    m_ucDISType   [ui] = pcCU->getDISType(uiPartOffset+ui);
826    m_piVSPFlag   [ui] = pcCU->m_piVSPFlag[uiPartOffset+ui];
827    m_pDvInfo     [ui] = pcCU->m_pDvInfo[uiPartOffset+ui];
828    m_pbSPIVMPFlag[ui] = pcCU->m_pbSPIVMPFlag[uiPartOffset+ui];
829    m_puhARPW     [ui] = pcCU->getARPW( uiPartOffset+ui );
830    m_pbICFlag    [ui] = pcCU->m_pbICFlag[uiPartOffset+ui];
831    for( Int i = 0; i < NUM_DMM; i++ )
832    {
833      m_dmmDeltaDC[i][0] [ui] = pcCU->m_dmmDeltaDC[i][0] [uiPartOffset+ui];
834      m_dmmDeltaDC[i][1] [ui] = pcCU->m_dmmDeltaDC[i][1] [uiPartOffset+ui];
835    }
836    m_dmm1WedgeTabIdx    [ui] = pcCU->m_dmm1WedgeTabIdx  [uiPartOffset+ui];
837    m_pbSDCFlag           [ui] = pcCU->m_pbSDCFlag            [ uiPartOffset + ui ];
838    m_apSegmentDCOffset[0][ui] = pcCU->m_apSegmentDCOffset[0] [ uiPartOffset + ui ];
839    m_apSegmentDCOffset[1][ui] = pcCU->m_apSegmentDCOffset[1] [ uiPartOffset + ui ];
840    m_pbDBBPFlag[ui]=pcCU->m_pbDBBPFlag[uiPartOffset+ui];
841#endif
842  }
843
844  const UInt numCoeffY    = uhWidth*uhHeight;
845  for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
846  {
847    const UInt componentShift = m_pcPic->getComponentScaleX(ComponentID(ch)) + m_pcPic->getComponentScaleY(ComponentID(ch));
848    memset( m_pcTrCoeff[ch],  0, sizeof(TCoeff)*(numCoeffY>>componentShift) );
849#if ADAPTIVE_QP_SELECTION
850    memset( m_pcArlCoeff[ch], 0, sizeof(TCoeff)*(numCoeffY>>componentShift) );
851#endif
852    memset( m_pcIPCMSample[ch], 0, sizeof(Pel)* (numCoeffY>>componentShift) );
853  }
854
855  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
856  {
857    m_acCUMvField[i].clearMvField();
858  }
859
860  m_pCtuLeft        = pcCU->getCtuLeft();
861  m_pCtuAbove       = pcCU->getCtuAbove();
862  m_pCtuAboveLeft   = pcCU->getCtuAboveLeft();
863  m_pCtuAboveRight  = pcCU->getCtuAboveRight();
864}
865
866Void TComDataCU::setOutsideCUPart( UInt uiAbsPartIdx, UInt uiDepth )
867{
868  const UInt     uiNumPartition = m_uiNumPartition >> (uiDepth << 1);
869  const UInt     uiSizeInUchar  = sizeof( UChar  ) * uiNumPartition;
870  const TComSPS &sps            = *(getSlice()->getSPS());
871  const UChar    uhWidth        = sps.getMaxCUWidth()  >> uiDepth;
872  const UChar    uhHeight       = sps.getMaxCUHeight() >> uiDepth;
873  memset( m_puhDepth    + uiAbsPartIdx,     uiDepth,  uiSizeInUchar );
874  memset( m_puhWidth    + uiAbsPartIdx,     uhWidth,  uiSizeInUchar );
875  memset( m_puhHeight   + uiAbsPartIdx,     uhHeight, uiSizeInUchar );
876}
877
878// --------------------------------------------------------------------------------------------------------------------
879// Copy
880// --------------------------------------------------------------------------------------------------------------------
881
882Void TComDataCU::copySubCU( TComDataCU* pcCU, UInt uiAbsPartIdx )
883{
884  UInt uiPart = uiAbsPartIdx;
885
886  m_pcPic              = pcCU->getPic();
887  m_pcSlice            = pcCU->getSlice();
888  m_ctuRsAddr          = pcCU->getCtuRsAddr();
889  m_absZIdxInCtu       = uiAbsPartIdx;
890
891  m_uiCUPelX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
892  m_uiCUPelY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
893
894  m_skipFlag=pcCU->getSkipFlag()          + uiPart;
895#if NH_3D
896  m_bDISFlag     = pcCU->getDISFlag()     + uiPart;
897  m_ucDISType    = pcCU->getDISType()     + uiPart;
898#endif
899
900  m_phQP=pcCU->getQP()                    + uiPart;
901  m_ChromaQpAdj = pcCU->getChromaQpAdj()  + uiPart;
902  m_pePartSize = pcCU->getPartitionSize() + uiPart;
903  m_pePredMode=pcCU->getPredictionMode()  + uiPart;
904  m_CUTransquantBypass  = pcCU->getCUTransquantBypass()+uiPart;
905#if NH_3D
906  m_pDvInfo             = pcCU->getDvInfo()           + uiPart;
907#endif
908  m_pbMergeFlag         = pcCU->getMergeFlag()        + uiPart;
909  m_puhMergeIndex       = pcCU->getMergeIndex()       + uiPart;
910#if NH_3D
911  m_piVSPFlag           = pcCU->getVSPFlag()          + uiPart;
912  m_pbSPIVMPFlag        = pcCU->getSPIVMPFlag()       + uiPart;
913  m_puhARPW             = pcCU->getARPW()             + uiPart;
914  m_pbICFlag            = pcCU->getICFlag()           + uiPart;
915#endif
916
917  for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
918  {
919    m_puhIntraDir[ch]   = pcCU->getIntraDir(ChannelType(ch)) + uiPart;
920  }
921
922  m_puhInterDir         = pcCU->getInterDir()         + uiPart;
923  m_puhTrIdx            = pcCU->getTransformIdx()     + uiPart;
924
925  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
926  {
927    m_crossComponentPredictionAlpha[comp] = pcCU->getCrossComponentPredictionAlpha(ComponentID(comp)) + uiPart;
928    m_puhTransformSkip[comp]              = pcCU->getTransformSkip(ComponentID(comp))                 + uiPart;
929    m_puhCbf[comp]                        = pcCU->getCbf(ComponentID(comp))                           + uiPart;
930    m_explicitRdpcmMode[comp]             = pcCU->getExplicitRdpcmMode(ComponentID(comp))             + uiPart;
931  }
932#if NH_3D
933  for( Int i = 0; i < NUM_DMM; i++ )
934  {
935    m_dmmDeltaDC[i][0] = pcCU->getDmmDeltaDC( (DmmID)i, 0 ) + uiPart;
936    m_dmmDeltaDC[i][1] = pcCU->getDmmDeltaDC( (DmmID)i, 1 ) + uiPart;
937  }
938  m_dmm1WedgeTabIdx    = pcCU->getDmm1WedgeTabIdx()  + uiPart;
939  m_pbSDCFlag               = pcCU->getSDCFlag()              + uiPart;
940  m_apSegmentDCOffset[0]    = pcCU->getSDCSegmentDCOffset(0)  + uiPart;
941  m_apSegmentDCOffset[1]    = pcCU->getSDCSegmentDCOffset(1)  + uiPart;
942  m_pbDBBPFlag              = pcCU->getDBBPFlag()         + uiPart;
943#endif
944
945  m_puhDepth=pcCU->getDepth()                     + uiPart;
946  m_puhWidth=pcCU->getWidth()                     + uiPart;
947  m_puhHeight=pcCU->getHeight()                   + uiPart;
948
949  m_pbIPCMFlag         = pcCU->getIPCMFlag()        + uiPart;
950
951  m_pCtuAboveLeft      = pcCU->getCtuAboveLeft();
952  m_pCtuAboveRight     = pcCU->getCtuAboveRight();
953  m_pCtuAbove          = pcCU->getCtuAbove();
954  m_pCtuLeft           = pcCU->getCtuLeft();
955
956  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
957  {
958    const RefPicList rpl=RefPicList(i);
959    m_apiMVPIdx[rpl]=pcCU->getMVPIdx(rpl)  + uiPart;
960    m_apiMVPNum[rpl]=pcCU->getMVPNum(rpl)  + uiPart;
961  }
962
963  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
964  {
965    const RefPicList rpl=RefPicList(i);
966    m_acCUMvField[rpl].linkToWithOffset( pcCU->getCUMvField(rpl), uiPart );
967  }
968
969  UInt uiMaxCuWidth=pcCU->getSlice()->getSPS()->getMaxCUWidth();
970  UInt uiMaxCuHeight=pcCU->getSlice()->getSPS()->getMaxCUHeight();
971
972  UInt uiCoffOffset = uiMaxCuWidth*uiMaxCuHeight*uiAbsPartIdx/pcCU->getPic()->getNumPartitionsInCtu();
973
974  for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
975  {
976    const ComponentID component = ComponentID(ch);
977    const UInt componentShift   = m_pcPic->getComponentScaleX(component) + m_pcPic->getComponentScaleY(component);
978    const UInt offset           = uiCoffOffset >> componentShift;
979    m_pcTrCoeff[ch] = pcCU->getCoeff(component) + offset;
980#if ADAPTIVE_QP_SELECTION
981    m_pcArlCoeff[ch] = pcCU->getArlCoeff(component) + offset;
982#endif
983    m_pcIPCMSample[ch] = pcCU->getPCMSample(component) + offset;
984  }
985}
986
987#if NH_3D
988Void TComDataCU::copyDVInfoFrom (TComDataCU* pcCU, UInt uiAbsPartIdx)
989{
990  m_pDvInfo            = pcCU->getDvInfo()                + uiAbsPartIdx;
991}
992#endif
993
994// Copy inter prediction info from the biggest CU
995#if NH_3D
996Void TComDataCU::copyInterPredInfoFrom    ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList   , Bool bNBDV )
997#else
998Void TComDataCU::copyInterPredInfoFrom    ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList )
999#endif
1000{
1001  m_pcPic              = pcCU->getPic();
1002  m_pcSlice            = pcCU->getSlice();
1003  m_ctuRsAddr          = pcCU->getCtuRsAddr();
1004  m_absZIdxInCtu       = uiAbsPartIdx;
1005
1006  Int iRastPartIdx     = g_auiZscanToRaster[uiAbsPartIdx];
1007  m_uiCUPelX           = pcCU->getCUPelX() + m_pcPic->getMinCUWidth ()*( iRastPartIdx % m_pcPic->getNumPartInCtuWidth() );
1008  m_uiCUPelY           = pcCU->getCUPelY() + m_pcPic->getMinCUHeight()*( iRastPartIdx / m_pcPic->getNumPartInCtuWidth() );
1009
1010  m_pCtuAboveLeft      = pcCU->getCtuAboveLeft();
1011  m_pCtuAboveRight     = pcCU->getCtuAboveRight();
1012  m_pCtuAbove          = pcCU->getCtuAbove();
1013  m_pCtuLeft           = pcCU->getCtuLeft();
1014
1015
1016  m_skipFlag           = pcCU->getSkipFlag ()             + uiAbsPartIdx;
1017#if NH_3D
1018  m_bDISFlag           = pcCU->getDISFlag ()              + uiAbsPartIdx;
1019  m_ucDISType          = pcCU->getDISType()               + uiAbsPartIdx;
1020#endif
1021
1022  m_pePartSize         = pcCU->getPartitionSize ()        + uiAbsPartIdx;
1023#if NH_3D
1024  if(bNBDV == true)
1025  {
1026    m_puhWidth           = pcCU->getWidth ()                + uiAbsPartIdx;
1027    m_puhHeight          = pcCU->getHeight()                + uiAbsPartIdx;
1028    m_puhDepth           = pcCU->getDepth ()                + uiAbsPartIdx;
1029  }
1030  else
1031  {
1032#endif
1033    m_pePredMode         = pcCU->getPredictionMode()        + uiAbsPartIdx;
1034    m_ChromaQpAdj        = pcCU->getChromaQpAdj()           + uiAbsPartIdx;
1035    m_CUTransquantBypass = pcCU->getCUTransquantBypass()    + uiAbsPartIdx;
1036    m_puhInterDir        = pcCU->getInterDir      ()        + uiAbsPartIdx;
1037
1038    m_puhDepth           = pcCU->getDepth ()                + uiAbsPartIdx;
1039    m_puhWidth           = pcCU->getWidth ()                + uiAbsPartIdx;
1040    m_puhHeight          = pcCU->getHeight()                + uiAbsPartIdx;
1041
1042    m_pbMergeFlag        = pcCU->getMergeFlag()             + uiAbsPartIdx;
1043    m_puhMergeIndex      = pcCU->getMergeIndex()            + uiAbsPartIdx;
1044#if NH_3D
1045    m_piVSPFlag          = pcCU->getVSPFlag()               + uiAbsPartIdx;
1046    m_pDvInfo            = pcCU->getDvInfo()                + uiAbsPartIdx;
1047    m_pbSPIVMPFlag       = pcCU->getSPIVMPFlag()            + uiAbsPartIdx;
1048#endif
1049    m_apiMVPIdx[eRefPicList] = pcCU->getMVPIdx(eRefPicList) + uiAbsPartIdx;
1050    m_apiMVPNum[eRefPicList] = pcCU->getMVPNum(eRefPicList) + uiAbsPartIdx;
1051#if NH_3D
1052    m_puhARPW            = pcCU->getARPW()                  + uiAbsPartIdx;
1053    m_pbDBBPFlag       = pcCU->getDBBPFlag()              + uiAbsPartIdx;
1054#endif
1055
1056    m_acCUMvField[ eRefPicList ].linkToWithOffset( pcCU->getCUMvField(eRefPicList), uiAbsPartIdx );
1057#if NH_3D
1058  }
1059  m_pbICFlag           = pcCU->getICFlag()                + uiAbsPartIdx;
1060#endif
1061
1062}
1063
1064// Copy small CU to bigger CU.
1065// One of quarter parts overwritten by predicted sub part.
1066Void TComDataCU::copyPartFrom( TComDataCU* pcCU, UInt uiPartUnitIdx, UInt uiDepth )
1067{
1068  assert( uiPartUnitIdx<4 );
1069
1070  m_dTotalCost         += pcCU->getTotalCost();
1071  m_uiTotalDistortion  += pcCU->getTotalDistortion();
1072  m_uiTotalBits        += pcCU->getTotalBits();
1073
1074  UInt uiOffset         = pcCU->getTotalNumPart()*uiPartUnitIdx;
1075  const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
1076  const UInt numValidChan=pcCU->getPic()->getChromaFormat()==CHROMA_400 ? 1:2;
1077
1078  UInt uiNumPartition = pcCU->getTotalNumPart();
1079  Int iSizeInUchar  = sizeof( UChar ) * uiNumPartition;
1080  Int iSizeInBool   = sizeof( Bool  ) * uiNumPartition;
1081
1082  Int sizeInChar  = sizeof( SChar ) * uiNumPartition;
1083  memcpy( m_skipFlag   + uiOffset, pcCU->getSkipFlag(),       sizeof( *m_skipFlag )   * uiNumPartition );
1084#if NH_3D
1085  memcpy( m_bDISFlag   + uiOffset, pcCU->getDISFlag(),        sizeof( *m_bDISFlag )   * uiNumPartition );
1086  memcpy( m_ucDISType  + uiOffset, pcCU->getDISType(),        sizeof( *m_ucDISType )  * uiNumPartition);
1087#endif
1088  memcpy( m_phQP       + uiOffset, pcCU->getQP(),             sizeInChar                        );
1089  memcpy( m_pePartSize + uiOffset, pcCU->getPartitionSize(),  sizeof( *m_pePartSize ) * uiNumPartition );
1090  memcpy( m_pePredMode + uiOffset, pcCU->getPredictionMode(), sizeof( *m_pePredMode ) * uiNumPartition );
1091  memcpy( m_ChromaQpAdj + uiOffset, pcCU->getChromaQpAdj(),   sizeof( *m_ChromaQpAdj ) * uiNumPartition );
1092  memcpy( m_CUTransquantBypass + uiOffset, pcCU->getCUTransquantBypass(), sizeof( *m_CUTransquantBypass ) * uiNumPartition );
1093  memcpy( m_pbMergeFlag         + uiOffset, pcCU->getMergeFlag(),         iSizeInBool  );
1094  memcpy( m_puhMergeIndex       + uiOffset, pcCU->getMergeIndex(),        iSizeInUchar );
1095#if NH_3D
1096  memcpy( m_piVSPFlag           + uiOffset, pcCU->getVSPFlag(),           sizeof( SChar ) * uiNumPartition );
1097  memcpy( m_pDvInfo             + uiOffset, pcCU->getDvInfo(),            sizeof( *m_pDvInfo ) * uiNumPartition );
1098  memcpy( m_pbSPIVMPFlag        + uiOffset, pcCU->getSPIVMPFlag(),        sizeof( Bool ) * uiNumPartition );
1099#endif
1100
1101  for (UInt ch=0; ch<numValidChan; ch++)
1102  {
1103    memcpy( m_puhIntraDir[ch]   + uiOffset, pcCU->getIntraDir(ChannelType(ch)), iSizeInUchar );
1104  }
1105
1106  memcpy( m_puhInterDir         + uiOffset, pcCU->getInterDir(),          iSizeInUchar );
1107  memcpy( m_puhTrIdx            + uiOffset, pcCU->getTransformIdx(),      iSizeInUchar );
1108
1109  for(UInt comp=0; comp<numValidComp; comp++)
1110  {
1111    memcpy( m_crossComponentPredictionAlpha[comp] + uiOffset, pcCU->getCrossComponentPredictionAlpha(ComponentID(comp)), iSizeInUchar );
1112    memcpy( m_puhTransformSkip[comp]              + uiOffset, pcCU->getTransformSkip(ComponentID(comp))                , iSizeInUchar );
1113    memcpy( m_puhCbf[comp]                        + uiOffset, pcCU->getCbf(ComponentID(comp))                          , iSizeInUchar );
1114    memcpy( m_explicitRdpcmMode[comp]             + uiOffset, pcCU->getExplicitRdpcmMode(ComponentID(comp))            , iSizeInUchar );
1115  }
1116#if NH_3D
1117  for( Int i = 0; i < NUM_DMM; i++ )
1118  {
1119    memcpy( m_dmmDeltaDC[i][0] + uiOffset, pcCU->getDmmDeltaDC( (DmmID)i, 0 ), sizeof(Pel ) * uiNumPartition );
1120    memcpy( m_dmmDeltaDC[i][1] + uiOffset, pcCU->getDmmDeltaDC( (DmmID)i, 1 ), sizeof(Pel ) * uiNumPartition );
1121  }
1122  memcpy( m_dmm1WedgeTabIdx    + uiOffset, pcCU->getDmm1WedgeTabIdx(),         sizeof(UInt) * uiNumPartition );
1123  memcpy( m_pbSDCFlag             + uiOffset, pcCU->getSDCFlag(), sizeof( *m_pbSDCFlag ) * uiNumPartition  );
1124  memcpy( m_apSegmentDCOffset[0]  + uiOffset, pcCU->getSDCSegmentDCOffset(0), sizeof( Pel ) * uiNumPartition);
1125  memcpy( m_apSegmentDCOffset[1]  + uiOffset, pcCU->getSDCSegmentDCOffset(1), sizeof( Pel ) * uiNumPartition);
1126  memcpy( m_pbDBBPFlag          + uiOffset, pcCU->getDBBPFlag(),          iSizeInBool  );
1127  memcpy( m_puhARPW             + uiOffset, pcCU->getARPW(),              iSizeInUchar );
1128#endif
1129
1130  memcpy( m_puhDepth  + uiOffset, pcCU->getDepth(),  iSizeInUchar );
1131  memcpy( m_puhWidth  + uiOffset, pcCU->getWidth(),  iSizeInUchar );
1132  memcpy( m_puhHeight + uiOffset, pcCU->getHeight(), iSizeInUchar );
1133
1134  memcpy( m_pbIPCMFlag + uiOffset, pcCU->getIPCMFlag(), iSizeInBool );
1135
1136  m_pCtuAboveLeft      = pcCU->getCtuAboveLeft();
1137  m_pCtuAboveRight     = pcCU->getCtuAboveRight();
1138  m_pCtuAbove          = pcCU->getCtuAbove();
1139  m_pCtuLeft           = pcCU->getCtuLeft();
1140
1141  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1142  {
1143    const RefPicList rpl=RefPicList(i);
1144    memcpy( m_apiMVPIdx[rpl] + uiOffset, pcCU->getMVPIdx(rpl), iSizeInUchar );
1145    memcpy( m_apiMVPNum[rpl] + uiOffset, pcCU->getMVPNum(rpl), iSizeInUchar );
1146  }
1147
1148  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1149  {
1150    const RefPicList rpl=RefPicList(i);
1151    m_acCUMvField[rpl].copyFrom( pcCU->getCUMvField( rpl ), pcCU->getTotalNumPart(), uiOffset );
1152  }
1153
1154  const UInt numCoeffY = (pcCU->getSlice()->getSPS()->getMaxCUWidth()*pcCU->getSlice()->getSPS()->getMaxCUHeight()) >> (uiDepth<<1);
1155  const UInt offsetY   = uiPartUnitIdx*numCoeffY;
1156  for (UInt ch=0; ch<numValidComp; ch++)
1157  {
1158    const ComponentID component = ComponentID(ch);
1159    const UInt componentShift   = m_pcPic->getComponentScaleX(component) + m_pcPic->getComponentScaleY(component);
1160    const UInt offset           = offsetY>>componentShift;
1161    memcpy( m_pcTrCoeff [ch] + offset, pcCU->getCoeff(component),    sizeof(TCoeff)*(numCoeffY>>componentShift) );
1162#if ADAPTIVE_QP_SELECTION
1163    memcpy( m_pcArlCoeff[ch] + offset, pcCU->getArlCoeff(component), sizeof(TCoeff)*(numCoeffY>>componentShift) );
1164#endif
1165    memcpy( m_pcIPCMSample[ch] + offset, pcCU->getPCMSample(component), sizeof(Pel)*(numCoeffY>>componentShift) );
1166  }
1167
1168#if NH_3D
1169  memcpy( m_pbICFlag            + uiOffset, pcCU->getICFlag(),            iSizeInBool );
1170#endif
1171
1172  m_uiTotalBins += pcCU->getTotalBins();
1173}
1174
1175// Copy current predicted part to a CU in picture.
1176// It is used to predict for next part
1177Void TComDataCU::copyToPic( UChar uhDepth )
1178{
1179  TComDataCU* pCtu = m_pcPic->getCtu( m_ctuRsAddr );
1180  const UInt numValidComp=pCtu->getPic()->getNumberValidComponents();
1181  const UInt numValidChan=pCtu->getPic()->getChromaFormat()==CHROMA_400 ? 1:2;
1182
1183  pCtu->getTotalCost()       = m_dTotalCost;
1184  pCtu->getTotalDistortion() = m_uiTotalDistortion;
1185  pCtu->getTotalBits()       = m_uiTotalBits;
1186
1187  Int iSizeInUchar  = sizeof( UChar ) * m_uiNumPartition;
1188  Int iSizeInBool   = sizeof( Bool  ) * m_uiNumPartition;
1189  Int sizeInChar  = sizeof( SChar ) * m_uiNumPartition;
1190
1191  memcpy( pCtu->getSkipFlag() + m_absZIdxInCtu, m_skipFlag, sizeof( *m_skipFlag ) * m_uiNumPartition );
1192#if NH_3D
1193  memcpy( pCtu->getDISFlag()  + m_absZIdxInCtu, m_bDISFlag, sizeof( *m_bDISFlag )  * m_uiNumPartition );
1194  memcpy( pCtu->getDISType()  + m_absZIdxInCtu, m_ucDISType, sizeof( *m_ucDISType ) * m_uiNumPartition );
1195#endif
1196
1197  memcpy( pCtu->getQP() + m_absZIdxInCtu, m_phQP, sizeInChar  );
1198#if NH_3D
1199  memcpy( pCtu->getDvInfo() + m_absZIdxInCtu, m_pDvInfo, sizeof(* m_pDvInfo) * m_uiNumPartition );
1200#endif
1201
1202  memcpy( pCtu->getPartitionSize()  + m_absZIdxInCtu, m_pePartSize, sizeof( *m_pePartSize ) * m_uiNumPartition );
1203  memcpy( pCtu->getPredictionMode() + m_absZIdxInCtu, m_pePredMode, sizeof( *m_pePredMode ) * m_uiNumPartition );
1204  memcpy( pCtu->getChromaQpAdj() + m_absZIdxInCtu, m_ChromaQpAdj, sizeof( *m_ChromaQpAdj ) * m_uiNumPartition );
1205  memcpy( pCtu->getCUTransquantBypass()+ m_absZIdxInCtu, m_CUTransquantBypass, sizeof( *m_CUTransquantBypass ) * m_uiNumPartition );
1206  memcpy( pCtu->getMergeFlag()         + m_absZIdxInCtu, m_pbMergeFlag,         iSizeInBool  );
1207  memcpy( pCtu->getMergeIndex()        + m_absZIdxInCtu, m_puhMergeIndex,       iSizeInUchar );
1208#if NH_3D
1209  memcpy( pCtu->getVSPFlag()           + m_absZIdxInCtu, m_piVSPFlag,           sizeof( SChar ) * m_uiNumPartition );
1210  memcpy( pCtu->getDvInfo()            + m_absZIdxInCtu, m_pDvInfo,             sizeof( *m_pDvInfo ) * m_uiNumPartition );
1211  memcpy( pCtu->getSPIVMPFlag()        + m_absZIdxInCtu, m_pbSPIVMPFlag,        sizeof( Bool ) * m_uiNumPartition );
1212#endif
1213
1214  for (UInt ch=0; ch<numValidChan; ch++)
1215  {
1216    memcpy( pCtu->getIntraDir(ChannelType(ch)) + m_absZIdxInCtu, m_puhIntraDir[ch], iSizeInUchar);
1217  }
1218
1219  memcpy( pCtu->getInterDir()          + m_absZIdxInCtu, m_puhInterDir,         iSizeInUchar );
1220  memcpy( pCtu->getTransformIdx()      + m_absZIdxInCtu, m_puhTrIdx,            iSizeInUchar );
1221
1222  for(UInt comp=0; comp<numValidComp; comp++)
1223  {
1224    memcpy( pCtu->getCrossComponentPredictionAlpha(ComponentID(comp)) + m_absZIdxInCtu, m_crossComponentPredictionAlpha[comp], iSizeInUchar );
1225    memcpy( pCtu->getTransformSkip(ComponentID(comp))                 + m_absZIdxInCtu, m_puhTransformSkip[comp],              iSizeInUchar );
1226    memcpy( pCtu->getCbf(ComponentID(comp))                           + m_absZIdxInCtu, m_puhCbf[comp],                        iSizeInUchar );
1227    memcpy( pCtu->getExplicitRdpcmMode(ComponentID(comp))             + m_absZIdxInCtu, m_explicitRdpcmMode[comp],             iSizeInUchar );
1228  }
1229
1230#if NH_3D
1231  for( Int i = 0; i < NUM_DMM; i++ )
1232  {
1233    memcpy( pCtu->getDmmDeltaDC( (DmmID)i, 0 ) + m_absZIdxInCtu, m_dmmDeltaDC[i][0], sizeof(Pel ) * m_uiNumPartition );
1234    memcpy( pCtu->getDmmDeltaDC( (DmmID)i, 1 ) + m_absZIdxInCtu, m_dmmDeltaDC[i][1], sizeof(Pel ) * m_uiNumPartition );
1235  }
1236
1237  memcpy( pCtu->getDmm1WedgeTabIdx()           + m_absZIdxInCtu, m_dmm1WedgeTabIdx,  sizeof(UInt) * m_uiNumPartition );
1238  memcpy( pCtu->getSDCFlag()             + m_absZIdxInCtu, m_pbSDCFlag, sizeof(Bool) * m_uiNumPartition );
1239  memcpy( pCtu->getSDCSegmentDCOffset(0) + m_absZIdxInCtu, m_apSegmentDCOffset[0], sizeof( Pel ) * m_uiNumPartition);
1240  memcpy( pCtu->getSDCSegmentDCOffset(1) + m_absZIdxInCtu, m_apSegmentDCOffset[1], sizeof( Pel ) * m_uiNumPartition);
1241  memcpy( pCtu->getDBBPFlag()          + m_absZIdxInCtu, m_pbDBBPFlag,          iSizeInBool  );
1242  memcpy( pCtu->getARPW()              + m_absZIdxInCtu, m_puhARPW,             iSizeInUchar );
1243#endif
1244
1245  memcpy( pCtu->getDepth()  + m_absZIdxInCtu, m_puhDepth,  iSizeInUchar );
1246  memcpy( pCtu->getWidth()  + m_absZIdxInCtu, m_puhWidth,  iSizeInUchar );
1247  memcpy( pCtu->getHeight() + m_absZIdxInCtu, m_puhHeight, iSizeInUchar );
1248
1249  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1250  {
1251    const RefPicList rpl=RefPicList(i);
1252    memcpy( pCtu->getMVPIdx(rpl) + m_absZIdxInCtu, m_apiMVPIdx[rpl], iSizeInUchar );
1253    memcpy( pCtu->getMVPNum(rpl) + m_absZIdxInCtu, m_apiMVPNum[rpl], iSizeInUchar );
1254  }
1255
1256  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1257  {
1258    const RefPicList rpl=RefPicList(i);
1259    m_acCUMvField[rpl].copyTo( pCtu->getCUMvField( rpl ), m_absZIdxInCtu );
1260  }
1261
1262  memcpy( pCtu->getIPCMFlag() + m_absZIdxInCtu, m_pbIPCMFlag,         iSizeInBool  );
1263
1264  const UInt numCoeffY    = (pCtu->getSlice()->getSPS()->getMaxCUWidth()*pCtu->getSlice()->getSPS()->getMaxCUHeight())>>(uhDepth<<1);
1265  const UInt offsetY      = m_absZIdxInCtu*m_pcPic->getMinCUWidth()*m_pcPic->getMinCUHeight();
1266  for (UInt comp=0; comp<numValidComp; comp++)
1267  {
1268    const ComponentID component = ComponentID(comp);
1269    const UInt componentShift   = m_pcPic->getComponentScaleX(component) + m_pcPic->getComponentScaleY(component);
1270    memcpy( pCtu->getCoeff(component)   + (offsetY>>componentShift), m_pcTrCoeff[component], sizeof(TCoeff)*(numCoeffY>>componentShift) );
1271#if ADAPTIVE_QP_SELECTION
1272    memcpy( pCtu->getArlCoeff(component) + (offsetY>>componentShift), m_pcArlCoeff[component], sizeof(TCoeff)*(numCoeffY>>componentShift) );
1273#endif
1274    memcpy( pCtu->getPCMSample(component) + (offsetY>>componentShift), m_pcIPCMSample[component], sizeof(Pel)*(numCoeffY>>componentShift) );
1275  }
1276
1277#if NH_3D
1278  memcpy( pCtu->getICFlag() + m_absZIdxInCtu, m_pbICFlag, sizeof( *m_pbICFlag ) * m_uiNumPartition );
1279#endif
1280  pCtu->getTotalBins() = m_uiTotalBins;
1281}
1282
1283// --------------------------------------------------------------------------------------------------------------------
1284// Other public functions
1285// --------------------------------------------------------------------------------------------------------------------
1286
1287const TComDataCU* TComDataCU::getPULeft( UInt& uiLPartUnitIdx,
1288                                   UInt uiCurrPartUnitIdx,
1289                                   Bool bEnforceSliceRestriction,
1290                                         Bool bEnforceTileRestriction ) const
1291{
1292  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1293  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_absZIdxInCtu];
1294  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1295
1296  if ( !RasterAddress::isZeroCol( uiAbsPartIdx, numPartInCtuWidth ) )
1297  {
1298    uiLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - 1 ];
1299    if ( RasterAddress::isEqualCol( uiAbsPartIdx, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1300    {
1301      return m_pcPic->getCtu( getCtuRsAddr() );
1302    }
1303    else
1304    {
1305      uiLPartUnitIdx -= m_absZIdxInCtu;
1306      return this;
1307    }
1308  }
1309
1310  uiLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + numPartInCtuWidth - 1 ];
1311  if ( (bEnforceSliceRestriction && !CUIsFromSameSlice(m_pCtuLeft)) || (bEnforceTileRestriction && !CUIsFromSameTile(m_pCtuLeft)) )
1312  {
1313    return NULL;
1314  }
1315  return m_pCtuLeft;
1316}
1317
1318
1319const TComDataCU* TComDataCU::getPUAbove( UInt& uiAPartUnitIdx,
1320                                    UInt uiCurrPartUnitIdx,
1321                                    Bool bEnforceSliceRestriction,
1322                                    Bool planarAtCtuBoundary,
1323                                          Bool bEnforceTileRestriction ) const
1324{
1325  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1326  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_absZIdxInCtu];
1327  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1328
1329  if ( !RasterAddress::isZeroRow( uiAbsPartIdx, numPartInCtuWidth ) )
1330  {
1331    uiAPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - numPartInCtuWidth ];
1332    if ( RasterAddress::isEqualRow( uiAbsPartIdx, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1333    {
1334      return m_pcPic->getCtu( getCtuRsAddr() );
1335    }
1336    else
1337    {
1338      uiAPartUnitIdx -= m_absZIdxInCtu;
1339      return this;
1340    }
1341  }
1342
1343  if(planarAtCtuBoundary)
1344  {
1345    return NULL;
1346  }
1347
1348  uiAPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + m_pcPic->getNumPartitionsInCtu() - numPartInCtuWidth ];
1349
1350  if ( (bEnforceSliceRestriction && !CUIsFromSameSlice(m_pCtuAbove)) || (bEnforceTileRestriction && !CUIsFromSameTile(m_pCtuAbove)) )
1351  {
1352    return NULL;
1353  }
1354  return m_pCtuAbove;
1355}
1356
1357const TComDataCU* TComDataCU::getPUAboveLeft( UInt& uiALPartUnitIdx, UInt uiCurrPartUnitIdx, Bool bEnforceSliceRestriction ) const
1358{
1359  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1360  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_absZIdxInCtu];
1361  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1362
1363  if ( !RasterAddress::isZeroCol( uiAbsPartIdx, numPartInCtuWidth ) )
1364  {
1365    if ( !RasterAddress::isZeroRow( uiAbsPartIdx, numPartInCtuWidth ) )
1366    {
1367      uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - numPartInCtuWidth - 1 ];
1368      if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdx, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1369      {
1370        return m_pcPic->getCtu( getCtuRsAddr() );
1371      }
1372      else
1373      {
1374        uiALPartUnitIdx -= m_absZIdxInCtu;
1375        return this;
1376      }
1377    }
1378    uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + getPic()->getNumPartitionsInCtu() - numPartInCtuWidth - 1 ];
1379    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAbove) )
1380    {
1381      return NULL;
1382    }
1383    return m_pCtuAbove;
1384  }
1385
1386  if ( !RasterAddress::isZeroRow( uiAbsPartIdx, numPartInCtuWidth ) )
1387  {
1388    uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - 1 ];
1389    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuLeft) )
1390    {
1391      return NULL;
1392    }
1393    return m_pCtuLeft;
1394  }
1395
1396  uiALPartUnitIdx = g_auiRasterToZscan[ m_pcPic->getNumPartitionsInCtu() - 1 ];
1397  if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAboveLeft) )
1398  {
1399    return NULL;
1400  }
1401  return m_pCtuAboveLeft;
1402}
1403
1404const TComDataCU* TComDataCU::getPUBelowLeft(UInt& uiBLPartUnitIdx,  UInt uiCurrPartUnitIdx, UInt uiPartUnitOffset, Bool bEnforceSliceRestriction) const
1405{
1406  UInt uiAbsPartIdxLB     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1407  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1408  UInt uiAbsZorderCUIdxLB = g_auiZscanToRaster[ m_absZIdxInCtu ] + ((m_puhHeight[0] / m_pcPic->getMinCUHeight()) - 1)*numPartInCtuWidth;
1409
1410  if( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxLB] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples())
1411  {
1412    uiBLPartUnitIdx = MAX_UINT;
1413    return NULL;
1414  }
1415
1416  if ( RasterAddress::lessThanRow( uiAbsPartIdxLB, m_pcPic->getNumPartInCtuHeight() - uiPartUnitOffset, numPartInCtuWidth ) )
1417  {
1418    if ( !RasterAddress::isZeroCol( uiAbsPartIdxLB, numPartInCtuWidth ) )
1419    {
1420      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxLB + uiPartUnitOffset * numPartInCtuWidth - 1 ] )
1421      {
1422        uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + uiPartUnitOffset * numPartInCtuWidth - 1 ];
1423        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxLB, uiAbsZorderCUIdxLB, numPartInCtuWidth ) )
1424        {
1425          return m_pcPic->getCtu( getCtuRsAddr() );
1426        }
1427        else
1428        {
1429          uiBLPartUnitIdx -= m_absZIdxInCtu;
1430          return this;
1431        }
1432      }
1433      uiBLPartUnitIdx = MAX_UINT;
1434      return NULL;
1435    }
1436    uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + (1+uiPartUnitOffset) * numPartInCtuWidth - 1 ];
1437    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuLeft) )
1438    {
1439      return NULL;
1440    }
1441    return m_pCtuLeft;
1442  }
1443
1444  uiBLPartUnitIdx = MAX_UINT;
1445  return NULL;
1446}
1447
1448const TComDataCU* TComDataCU::getPUAboveRight(UInt&  uiARPartUnitIdx, UInt uiCurrPartUnitIdx, UInt uiPartUnitOffset, Bool bEnforceSliceRestriction) const
1449{
1450  UInt uiAbsPartIdxRT     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1451  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[ m_absZIdxInCtu ] + (m_puhWidth[0] / m_pcPic->getMinCUWidth()) - 1;
1452  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1453
1454  if( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxRT] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
1455  {
1456    uiARPartUnitIdx = MAX_UINT;
1457    return NULL;
1458  }
1459
1460  if ( RasterAddress::lessThanCol( uiAbsPartIdxRT, numPartInCtuWidth - uiPartUnitOffset, numPartInCtuWidth ) )
1461  {
1462    if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, numPartInCtuWidth ) )
1463    {
1464      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxRT - numPartInCtuWidth + uiPartUnitOffset ] )
1465      {
1466        uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT - numPartInCtuWidth + uiPartUnitOffset ];
1467        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxRT, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1468        {
1469          return m_pcPic->getCtu( getCtuRsAddr() );
1470        }
1471        else
1472        {
1473          uiARPartUnitIdx -= m_absZIdxInCtu;
1474          return this;
1475        }
1476      }
1477      uiARPartUnitIdx = MAX_UINT;
1478      return NULL;
1479    }
1480
1481    uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT + m_pcPic->getNumPartitionsInCtu() - numPartInCtuWidth + uiPartUnitOffset ];
1482    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAbove) )
1483    {
1484      return NULL;
1485    }
1486    return m_pCtuAbove;
1487  }
1488
1489  if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, numPartInCtuWidth ) )
1490  {
1491    uiARPartUnitIdx = MAX_UINT;
1492    return NULL;
1493  }
1494
1495  uiARPartUnitIdx = g_auiRasterToZscan[ m_pcPic->getNumPartitionsInCtu() - numPartInCtuWidth + uiPartUnitOffset-1 ];
1496  if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAboveRight) )
1497  {
1498    return NULL;
1499  }
1500  return m_pCtuAboveRight;
1501}
1502
1503/** Get left QpMinCu
1504*\param   uiLPartUnitIdx
1505*\param   uiCurrAbsIdxInCtu
1506*\returns TComDataCU*   point of TComDataCU of left QpMinCu
1507*/
1508const TComDataCU* TComDataCU::getQpMinCuLeft( UInt& uiLPartUnitIdx, UInt uiCurrAbsIdxInCtu ) const
1509{
1510  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1511  const UInt maxCUDepth        = getSlice()->getSPS()->getMaxTotalCUDepth();
1512  const UInt maxCuDQPDepth     = getSlice()->getPPS()->getMaxCuDQPDepth();
1513  const UInt doubleDepthDifference = ((maxCUDepth - maxCuDQPDepth)<<1);
1514  UInt absZorderQpMinCUIdx = (uiCurrAbsIdxInCtu>>doubleDepthDifference)<<doubleDepthDifference;
1515  UInt absRorderQpMinCUIdx = g_auiZscanToRaster[absZorderQpMinCUIdx];
1516
1517  // check for left CTU boundary
1518  if ( RasterAddress::isZeroCol(absRorderQpMinCUIdx, numPartInCtuWidth) )
1519  {
1520    return NULL;
1521  }
1522
1523  // get index of left-CU relative to top-left corner of current quantization group
1524  uiLPartUnitIdx = g_auiRasterToZscan[absRorderQpMinCUIdx - 1];
1525
1526  // return pointer to current CTU
1527  return m_pcPic->getCtu( getCtuRsAddr() );
1528}
1529
1530/** Get Above QpMinCu
1531*\param   uiAPartUnitIdx
1532*\param   uiCurrAbsIdxInCtu
1533*\returns TComDataCU*   point of TComDataCU of above QpMinCu
1534*/
1535const TComDataCU* TComDataCU::getQpMinCuAbove( UInt& uiAPartUnitIdx, UInt uiCurrAbsIdxInCtu ) const
1536{
1537  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1538  const UInt maxCUDepth        = getSlice()->getSPS()->getMaxTotalCUDepth();
1539  const UInt maxCuDQPDepth     = getSlice()->getPPS()->getMaxCuDQPDepth();
1540  const UInt doubleDepthDifference = ((maxCUDepth - maxCuDQPDepth)<<1);
1541  UInt absZorderQpMinCUIdx = (uiCurrAbsIdxInCtu>>doubleDepthDifference)<<doubleDepthDifference;
1542  UInt absRorderQpMinCUIdx = g_auiZscanToRaster[absZorderQpMinCUIdx];
1543
1544  // check for top CTU boundary
1545  if ( RasterAddress::isZeroRow( absRorderQpMinCUIdx, numPartInCtuWidth) )
1546  {
1547    return NULL;
1548  }
1549
1550  // get index of top-CU relative to top-left corner of current quantization group
1551  uiAPartUnitIdx = g_auiRasterToZscan[absRorderQpMinCUIdx - numPartInCtuWidth];
1552
1553  // return pointer to current CTU
1554  return m_pcPic->getCtu( getCtuRsAddr() );
1555}
1556
1557
1558
1559/** Get reference QP from left QpMinCu or latest coded QP
1560*\param   uiCurrAbsIdxInCtu
1561*\returns SChar   reference QP value
1562*/
1563SChar TComDataCU::getRefQP( UInt uiCurrAbsIdxInCtu ) const
1564{
1565  UInt lPartIdx = MAX_UINT;
1566  UInt aPartIdx = MAX_UINT;
1567  const TComDataCU* cULeft  = getQpMinCuLeft ( lPartIdx, m_absZIdxInCtu + uiCurrAbsIdxInCtu );
1568  const TComDataCU* cUAbove = getQpMinCuAbove( aPartIdx, m_absZIdxInCtu + uiCurrAbsIdxInCtu );
1569  return (((cULeft? cULeft->getQP( lPartIdx ): getLastCodedQP( uiCurrAbsIdxInCtu )) + (cUAbove? cUAbove->getQP( aPartIdx ): getLastCodedQP( uiCurrAbsIdxInCtu )) + 1) >> 1);
1570}
1571
1572Int TComDataCU::getLastValidPartIdx( Int iAbsPartIdx ) const
1573{
1574  Int iLastValidPartIdx = iAbsPartIdx-1;
1575  while ( iLastValidPartIdx >= 0
1576       && getPredictionMode( iLastValidPartIdx ) == NUMBER_OF_PREDICTION_MODES )
1577  {
1578    UInt uiDepth = getDepth( iLastValidPartIdx );
1579    iLastValidPartIdx -= m_uiNumPartition>>(uiDepth<<1);
1580  }
1581  return iLastValidPartIdx;
1582}
1583
1584SChar TComDataCU::getLastCodedQP( UInt uiAbsPartIdx ) const
1585{
1586  UInt uiQUPartIdxMask = ~((1<<((getSlice()->getSPS()->getMaxTotalCUDepth() - getSlice()->getPPS()->getMaxCuDQPDepth())<<1))-1);
1587  Int iLastValidPartIdx = getLastValidPartIdx( uiAbsPartIdx&uiQUPartIdxMask ); // A idx will be invalid if it is off the right or bottom edge of the picture.
1588  // If this CU is in the first CTU of the slice and there is no valid part before this one, use slice QP
1589  if ( getPic()->getPicSym()->getCtuTsToRsAddrMap(getSlice()->getSliceCurStartCtuTsAddr()) == getCtuRsAddr() && Int(getZorderIdxInCtu())+iLastValidPartIdx<0)
1590  {
1591    return getSlice()->getSliceQp();
1592  }
1593  else if ( iLastValidPartIdx >= 0 )
1594  {
1595    // If there is a valid part within the current Sub-CU, use it
1596    return getQP( iLastValidPartIdx );
1597  }
1598  else
1599  {
1600    if ( getZorderIdxInCtu() > 0 )
1601    {
1602      // If this wasn't the first sub-cu within the Ctu, explore the CTU itself.
1603      return getPic()->getCtu( getCtuRsAddr() )->getLastCodedQP( getZorderIdxInCtu() ); // TODO - remove this recursion
1604    }
1605    else if ( getPic()->getPicSym()->getCtuRsToTsAddrMap(getCtuRsAddr()) > 0
1606      && CUIsFromSameSliceTileAndWavefrontRow(getPic()->getCtu(getPic()->getPicSym()->getCtuTsToRsAddrMap(getPic()->getPicSym()->getCtuRsToTsAddrMap(getCtuRsAddr())-1))) )
1607    {
1608      // If this isn't the first Ctu (how can it be due to the first 'if'?), and the previous Ctu is from the same tile, examine the previous Ctu.
1609      return getPic()->getCtu( getPic()->getPicSym()->getCtuTsToRsAddrMap(getPic()->getPicSym()->getCtuRsToTsAddrMap(getCtuRsAddr())-1) )->getLastCodedQP( getPic()->getNumPartitionsInCtu() );  // TODO - remove this recursion
1610    }
1611    else
1612    {
1613      // No other options available - use the slice-level QP.
1614      return getSlice()->getSliceQp();
1615    }
1616  }
1617}
1618
1619
1620/** Check whether the CU is coded in lossless coding mode.
1621 * \param   absPartIdx
1622 * \returns true if the CU is coded in lossless coding mode; false if otherwise
1623 */
1624Bool TComDataCU::isLosslessCoded(UInt absPartIdx) const
1625{
1626  return (getSlice()->getPPS()->getTransquantBypassEnabledFlag() && getCUTransquantBypass (absPartIdx));
1627}
1628
1629
1630/** Get allowed chroma intra modes
1631*   - fills uiModeList with chroma intra modes
1632*
1633*\param   [in]  uiAbsPartIdx
1634*\param   [out] uiModeList pointer to chroma intra modes array
1635*/
1636Void TComDataCU::getAllowedChromaDir( UInt uiAbsPartIdx, UInt uiModeList[NUM_CHROMA_MODE] ) const
1637{
1638  uiModeList[0] = PLANAR_IDX;
1639  uiModeList[1] = VER_IDX;
1640  uiModeList[2] = HOR_IDX;
1641  uiModeList[3] = DC_IDX;
1642  uiModeList[4] = DM_CHROMA_IDX;
1643  assert(4<NUM_CHROMA_MODE);
1644
1645  UInt uiLumaMode = getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx );
1646
1647  for( Int i = 0; i < NUM_CHROMA_MODE - 1; i++ )
1648  {
1649    if( uiLumaMode == uiModeList[i] )
1650    {
1651      uiModeList[i] = 34; // VER+8 mode
1652      break;
1653    }
1654  }
1655}
1656
1657/** Get most probable intra modes
1658*\param   uiAbsPartIdx    partition index
1659*\param   uiIntraDirPred  pointer to the array for MPM storage
1660*\param   compID          colour component ID
1661*\param   piMode          it is set with MPM mode in case both MPM are equal. It is used to restrict RD search at encode side.
1662*\returns Number of MPM
1663*/
1664Void TComDataCU::getIntraDirPredictor( UInt uiAbsPartIdx, Int uiIntraDirPred[NUM_MOST_PROBABLE_MODES], const ComponentID compID, Int* piMode ) const
1665{
1666  UInt        LeftPartIdx  = MAX_UINT;
1667  UInt        AbovePartIdx = MAX_UINT;
1668  Int         iLeftIntraDir, iAboveIntraDir;
1669  const TComSPS *sps=getSlice()->getSPS();
1670  const UInt partsPerMinCU = 1<<(2*(sps->getMaxTotalCUDepth() - sps->getLog2DiffMaxMinCodingBlockSize()));
1671
1672  const ChannelType chType = toChannelType(compID);
1673  const ChromaFormat chForm = getPic()->getChromaFormat();
1674  // Get intra direction of left PU
1675  const TComDataCU *pcCULeft = getPULeft( LeftPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1676
1677  if (isChroma(compID))
1678  {
1679    LeftPartIdx = getChromasCorrespondingPULumaIdx(LeftPartIdx, chForm, partsPerMinCU);
1680  }
1681  iLeftIntraDir  = pcCULeft ? ( pcCULeft->isIntra( LeftPartIdx ) ? pcCULeft->getIntraDir( chType, LeftPartIdx ) : DC_IDX ) : DC_IDX;
1682#if NH_3D
1683  mapDmmToIntraDir( iLeftIntraDir );
1684#endif
1685
1686  // Get intra direction of above PU
1687  const TComDataCU *pcCUAbove = getPUAbove( AbovePartIdx, m_absZIdxInCtu + uiAbsPartIdx, true, true );
1688
1689  if (isChroma(compID))
1690  {
1691    AbovePartIdx = getChromasCorrespondingPULumaIdx(AbovePartIdx, chForm, partsPerMinCU);
1692  }
1693  iAboveIntraDir = pcCUAbove ? ( pcCUAbove->isIntra( AbovePartIdx ) ? pcCUAbove->getIntraDir( chType, AbovePartIdx ) : DC_IDX ) : DC_IDX;
1694#if NH_3D
1695  mapDmmToIntraDir( iAboveIntraDir );
1696#endif
1697
1698
1699  if (isChroma(chType))
1700  {
1701    if (iLeftIntraDir  == DM_CHROMA_IDX)
1702    {
1703      iLeftIntraDir  = pcCULeft-> getIntraDir( CHANNEL_TYPE_LUMA, LeftPartIdx  );
1704    }
1705    if (iAboveIntraDir == DM_CHROMA_IDX)
1706    {
1707      iAboveIntraDir = pcCUAbove->getIntraDir( CHANNEL_TYPE_LUMA, AbovePartIdx );
1708    }
1709  }
1710
1711  assert (2<NUM_MOST_PROBABLE_MODES);
1712  if(iLeftIntraDir == iAboveIntraDir)
1713  {
1714    if( piMode )
1715    {
1716      *piMode = 1;
1717    }
1718
1719    if (iLeftIntraDir > 1) // angular modes
1720    {
1721      uiIntraDirPred[0] = iLeftIntraDir;
1722      uiIntraDirPred[1] = ((iLeftIntraDir + 29) % 32) + 2;
1723      uiIntraDirPred[2] = ((iLeftIntraDir - 1 ) % 32) + 2;
1724    }
1725    else //non-angular
1726    {
1727      uiIntraDirPred[0] = PLANAR_IDX;
1728      uiIntraDirPred[1] = DC_IDX;
1729      uiIntraDirPred[2] = VER_IDX;
1730    }
1731  }
1732  else
1733  {
1734    if( piMode )
1735    {
1736      *piMode = 2;
1737    }
1738    uiIntraDirPred[0] = iLeftIntraDir;
1739    uiIntraDirPred[1] = iAboveIntraDir;
1740
1741    if (iLeftIntraDir && iAboveIntraDir ) //both modes are non-planar
1742    {
1743      uiIntraDirPred[2] = PLANAR_IDX;
1744    }
1745    else
1746    {
1747      uiIntraDirPred[2] =  (iLeftIntraDir+iAboveIntraDir)<2? VER_IDX : DC_IDX;
1748    }
1749  }
1750  for (UInt i=0; i<NUM_MOST_PROBABLE_MODES; i++)
1751  {
1752    assert(uiIntraDirPred[i] < 35);
1753  }
1754}
1755
1756UInt TComDataCU::getCtxSplitFlag( UInt uiAbsPartIdx, UInt uiDepth ) const
1757{
1758  const TComDataCU* pcTempCU;
1759  UInt        uiTempPartIdx;
1760  UInt        uiCtx;
1761  // Get left split flag
1762  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1763  uiCtx  = ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;
1764
1765  // Get above split flag
1766  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1767  uiCtx += ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;
1768
1769  return uiCtx;
1770}
1771
1772UInt TComDataCU::getCtxQtCbf( TComTU &rTu, const ChannelType chType ) const
1773{
1774  const UInt transformDepth = rTu.GetTransformDepthRel();
1775
1776  if (isChroma(chType))
1777  {
1778    return transformDepth;
1779  }
1780  else
1781  {
1782    const UInt uiCtx = ( transformDepth == 0 ? 1 : 0 );
1783    return uiCtx;
1784  }
1785}
1786
1787UInt TComDataCU::getQuadtreeTULog2MinSizeInCU( UInt absPartIdx ) const
1788{
1789  UInt log2CbSize = g_aucConvertToBit[getWidth( absPartIdx )] + 2;
1790  PartSize  partSize  = getPartitionSize( absPartIdx );
1791  UInt quadtreeTUMaxDepth = isIntra( absPartIdx ) ? m_pcSlice->getSPS()->getQuadtreeTUMaxDepthIntra() : m_pcSlice->getSPS()->getQuadtreeTUMaxDepthInter();
1792  Int intraSplitFlag = ( isIntra( absPartIdx ) && partSize == SIZE_NxN ) ? 1 : 0;
1793  Int interSplitFlag = ((quadtreeTUMaxDepth == 1) && isInter( absPartIdx ) && (partSize != SIZE_2Nx2N) );
1794
1795  UInt log2MinTUSizeInCU = 0;
1796  if (log2CbSize < (m_pcSlice->getSPS()->getQuadtreeTULog2MinSize() + quadtreeTUMaxDepth - 1 + interSplitFlag + intraSplitFlag) )
1797  {
1798    // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is < QuadtreeTULog2MinSize
1799    log2MinTUSizeInCU = m_pcSlice->getSPS()->getQuadtreeTULog2MinSize();
1800  }
1801  else
1802  {
1803    // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is still >= QuadtreeTULog2MinSize
1804    log2MinTUSizeInCU = log2CbSize - ( quadtreeTUMaxDepth - 1 + interSplitFlag + intraSplitFlag); // stop when trafoDepth == hierarchy_depth = splitFlag
1805    if ( log2MinTUSizeInCU > m_pcSlice->getSPS()->getQuadtreeTULog2MaxSize())
1806    {
1807      // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is still > QuadtreeTULog2MaxSize
1808      log2MinTUSizeInCU = m_pcSlice->getSPS()->getQuadtreeTULog2MaxSize();
1809    }
1810  }
1811  return log2MinTUSizeInCU;
1812}
1813
1814UInt TComDataCU::getCtxSkipFlag( UInt uiAbsPartIdx ) const
1815{
1816  const TComDataCU* pcTempCU;
1817  UInt        uiTempPartIdx;
1818  UInt        uiCtx = 0;
1819
1820  // Get BCBP of left PU
1821  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1822  uiCtx    = ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;
1823
1824  // Get BCBP of above PU
1825  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1826  uiCtx   += ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;
1827
1828  return uiCtx;
1829}
1830#if NH_3D
1831UInt TComDataCU::getCTXARPWFlag( UInt uiAbsPartIdx )
1832{
1833  const TComDataCU* pcTempCU;
1834  UInt        uiTempPartIdx;
1835  UInt        uiCtx = 0;
1836
1837  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1838  uiCtx    = ( pcTempCU ) ? ((pcTempCU->getARPW( uiTempPartIdx )==0)?0:1) : 0;
1839  return uiCtx;
1840}
1841
1842Pel* TComDataCU::getVirtualDepthBlock(UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt& uiDepthStride)
1843{
1844  const TComSPS* sps = getSlice()->getSPS();
1845  UInt uiMaxCUWidth = sps->getMaxCUWidth();
1846  UInt uiMaxCUHeight = sps->getMaxCUHeight();
1847 
1848  // get coded and reconstructed depth view
1849  TComPicYuv* depthPicYuv = NULL;
1850  Pel* pDepthPels = NULL;
1851 
1852  // DBBP is a texture coding tool
1853  assert( !getSlice()->getIsDepth() );
1854 
1855  {
1856    DisInfo DvInfo = getDvInfo(uiAbsPartIdx);
1857   
1858    TComPic* baseDepthPic = getSlice()->getIvPic (true, DvInfo.m_aVIdxCan);
1859   
1860    if( baseDepthPic == NULL || baseDepthPic->getPicYuvRec() == NULL )
1861    {
1862      return NULL;
1863    }
1864   
1865    depthPicYuv   = baseDepthPic->getPicYuvRec();
1866    depthPicYuv->extendPicBorder();
1867    uiDepthStride = depthPicYuv->getStride(COMPONENT_Y);
1868   
1869    Int iBlkX = ( getCtuRsAddr() % baseDepthPic->getFrameWidthInCtus() ) * uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ getZorderIdxInCtu()+uiAbsPartIdx ] ];
1870    Int iBlkY = ( getCtuRsAddr() / baseDepthPic->getFrameWidthInCtus() ) * uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ getZorderIdxInCtu()+uiAbsPartIdx ] ];
1871   
1872    Int iPictureWidth  = depthPicYuv->getWidth(COMPONENT_Y);
1873    Int iPictureHeight = depthPicYuv->getHeight(COMPONENT_Y);
1874   
1875   
1876    Bool depthRefineFlag = false;
1877    depthRefineFlag = m_pcSlice->getDepthRefinementFlag();
1878   
1879    TComMv cDv = depthRefineFlag ? DvInfo.m_acDoNBDV : DvInfo.m_acNBDV;
1880    if( depthRefineFlag )
1881    {
1882      cDv.setVer(0);
1883    }
1884   
1885    Int depthPosX = Clip3(0,   iPictureWidth - 1,  iBlkX + ((cDv.getHor()+2)>>2));
1886    Int depthPosY = Clip3(0,   iPictureHeight - 1, iBlkY + ((cDv.getVer()+2)>>2));
1887   
1888    pDepthPels = depthPicYuv->getAddr(COMPONENT_Y) + depthPosX + depthPosY * uiDepthStride;
1889  }
1890 
1891  AOF( depthPicYuv != NULL );
1892  AOF( pDepthPels != NULL );
1893  AOF( uiDepthStride != 0 );
1894 
1895  return pDepthPels;
1896}
1897
1898Void TComDataCU::setDBBPFlagSubParts ( Bool bDBBPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
1899{
1900  setSubPart( bDBBPFlag, m_pbDBBPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
1901}
1902#endif
1903
1904
1905UInt TComDataCU::getCtxInterDir( UInt uiAbsPartIdx ) const
1906{
1907  return getDepth( uiAbsPartIdx );
1908}
1909
1910
1911UChar TComDataCU::getQtRootCbf( UInt uiIdx ) const
1912{
1913  const UInt numberValidComponents = getPic()->getNumberValidComponents();
1914  return getCbf( uiIdx, COMPONENT_Y, 0 )
1915          || ((numberValidComponents > COMPONENT_Cb) && getCbf( uiIdx, COMPONENT_Cb, 0 ))
1916          || ((numberValidComponents > COMPONENT_Cr) && getCbf( uiIdx, COMPONENT_Cr, 0 ));
1917}
1918
1919Void TComDataCU::setCbfSubParts( const UInt uiCbf[MAX_NUM_COMPONENT], UInt uiAbsPartIdx, UInt uiDepth )
1920{
1921  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
1922  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
1923  {
1924    memset( m_puhCbf[comp] + uiAbsPartIdx, uiCbf[comp], sizeof( UChar ) * uiCurrPartNumb );
1925  }
1926}
1927
1928Void TComDataCU::setCbfSubParts( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiDepth )
1929{
1930  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
1931  memset( m_puhCbf[compID] + uiAbsPartIdx, uiCbf, sizeof( UChar ) * uiCurrPartNumb );
1932}
1933
1934/** Sets a coded block flag for all sub-partitions of a partition
1935 * \param uiCbf          The value of the coded block flag to be set
1936 * \param compID
1937 * \param uiAbsPartIdx
1938 * \param uiPartIdx
1939 * \param uiDepth
1940 */
1941Void TComDataCU::setCbfSubParts ( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
1942{
1943  setSubPart<UChar>( uiCbf, m_puhCbf[compID], uiAbsPartIdx, uiDepth, uiPartIdx );
1944}
1945
1946Void TComDataCU::setCbfPartRange ( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
1947{
1948  memset((m_puhCbf[compID] + uiAbsPartIdx), uiCbf, (sizeof(UChar) * uiCoveredPartIdxes));
1949}
1950
1951Void TComDataCU::bitwiseOrCbfPartRange( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
1952{
1953  const UInt stopAbsPartIdx = uiAbsPartIdx + uiCoveredPartIdxes;
1954
1955  for (UInt subPartIdx = uiAbsPartIdx; subPartIdx < stopAbsPartIdx; subPartIdx++)
1956  {
1957    m_puhCbf[compID][subPartIdx] |= uiCbf;
1958  }
1959}
1960
1961Void TComDataCU::setDepthSubParts( UInt uiDepth, UInt uiAbsPartIdx )
1962{
1963  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
1964  memset( m_puhDepth + uiAbsPartIdx, uiDepth, sizeof(UChar)*uiCurrPartNumb );
1965}
1966
1967Bool TComDataCU::isFirstAbsZorderIdxInDepth (UInt uiAbsPartIdx, UInt uiDepth) const
1968{
1969  UInt uiPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
1970  return (((m_absZIdxInCtu + uiAbsPartIdx)% uiPartNumb) == 0);
1971}
1972
1973Void TComDataCU::setPartSizeSubParts( PartSize eMode, UInt uiAbsPartIdx, UInt uiDepth )
1974{
1975  assert( sizeof( *m_pePartSize) == 1 );
1976  memset( m_pePartSize + uiAbsPartIdx, eMode, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
1977}
1978
1979Void TComDataCU::setCUTransquantBypassSubParts( Bool flag, UInt uiAbsPartIdx, UInt uiDepth )
1980{
1981  memset( m_CUTransquantBypass + uiAbsPartIdx, flag, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
1982}
1983
1984Void TComDataCU::setSkipFlagSubParts( Bool skip, UInt absPartIdx, UInt depth )
1985{
1986  assert( sizeof( *m_skipFlag) == 1 );
1987  memset( m_skipFlag + absPartIdx, skip, m_pcPic->getNumPartitionsInCtu() >> ( 2 * depth ) );
1988}
1989
1990#if NH_3D
1991Void TComDataCU::setDISFlagSubParts( Bool bDIS, UInt uiAbsPartIdx, UInt uiDepth )
1992{
1993    assert( sizeof( *m_bDISFlag) == 1 );
1994    memset( m_bDISFlag + uiAbsPartIdx, bDIS, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
1995}
1996
1997Void TComDataCU::setDISTypeSubParts(UChar ucDISType, UInt uiAbsPartIdx, UInt uiDepth )
1998{
1999  assert( sizeof( *m_ucDISType) == 1 );
2000  memset( m_ucDISType + uiAbsPartIdx, ucDISType, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
2001}
2002#endif
2003
2004Void TComDataCU::setPredModeSubParts( PredMode eMode, UInt uiAbsPartIdx, UInt uiDepth )
2005{
2006  assert( sizeof( *m_pePredMode) == 1 );
2007  memset( m_pePredMode + uiAbsPartIdx, eMode, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
2008}
2009
2010Void TComDataCU::setChromaQpAdjSubParts( UChar val, Int absPartIdx, Int depth )
2011{
2012  assert( sizeof(*m_ChromaQpAdj) == 1 );
2013  memset( m_ChromaQpAdj + absPartIdx, val, m_pcPic->getNumPartitionsInCtu() >> ( 2 * depth ) );
2014}
2015
2016Void TComDataCU::setQPSubCUs( Int qp, UInt absPartIdx, UInt depth, Bool &foundNonZeroCbf )
2017{
2018  UInt currPartNumb = m_pcPic->getNumPartitionsInCtu() >> (depth << 1);
2019  UInt currPartNumQ = currPartNumb >> 2;
2020  const UInt numValidComp = m_pcPic->getNumberValidComponents();
2021
2022  if(!foundNonZeroCbf)
2023  {
2024    if(getDepth(absPartIdx) > depth)
2025    {
2026      for ( UInt partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++ )
2027      {
2028        setQPSubCUs( qp, absPartIdx+partUnitIdx*currPartNumQ, depth+1, foundNonZeroCbf );
2029      }
2030    }
2031    else
2032    {
2033      if(getCbf( absPartIdx, COMPONENT_Y ) || (numValidComp>COMPONENT_Cb && getCbf( absPartIdx, COMPONENT_Cb )) || (numValidComp>COMPONENT_Cr && getCbf( absPartIdx, COMPONENT_Cr) ) )
2034      {
2035        foundNonZeroCbf = true;
2036      }
2037      else
2038      {
2039        setQPSubParts(qp, absPartIdx, depth);
2040      }
2041    }
2042  }
2043}
2044
2045Void TComDataCU::setQPSubParts( Int qp, UInt uiAbsPartIdx, UInt uiDepth )
2046{
2047  const UInt numPart = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2048  memset(m_phQP+uiAbsPartIdx, qp, numPart);
2049}
2050
2051Void TComDataCU::setIntraDirSubParts( const ChannelType channelType, const UInt dir, const UInt absPartIdx, const UInt depth )
2052{
2053  UInt numPart = m_pcPic->getNumPartitionsInCtu() >> (depth << 1);
2054  memset( m_puhIntraDir[channelType] + absPartIdx, dir,sizeof(UChar)*numPart );
2055}
2056
2057template<typename T>
2058Void TComDataCU::setSubPart( T uiParameter, T* puhBaseCtu, UInt uiCUAddr, UInt uiCUDepth, UInt uiPUIdx )
2059{
2060  assert( sizeof(T) == 1 ); // Using memset() works only for types of size 1
2061
2062  UInt uiCurrPartNumQ = (m_pcPic->getNumPartitionsInCtu() >> (2 * uiCUDepth)) >> 2;
2063  switch ( m_pePartSize[ uiCUAddr ] )
2064  {
2065    case SIZE_2Nx2N:
2066      memset( puhBaseCtu + uiCUAddr, uiParameter, 4 * uiCurrPartNumQ );
2067      break;
2068    case SIZE_2NxN:
2069      memset( puhBaseCtu + uiCUAddr, uiParameter, 2 * uiCurrPartNumQ );
2070      break;
2071    case SIZE_Nx2N:
2072      memset( puhBaseCtu + uiCUAddr, uiParameter, uiCurrPartNumQ );
2073      memset( puhBaseCtu + uiCUAddr + 2 * uiCurrPartNumQ, uiParameter, uiCurrPartNumQ );
2074      break;
2075    case SIZE_NxN:
2076      memset( puhBaseCtu + uiCUAddr, uiParameter, uiCurrPartNumQ );
2077      break;
2078    case SIZE_2NxnU:
2079      if ( uiPUIdx == 0 )
2080      {
2081        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );
2082        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );
2083      }
2084      else if ( uiPUIdx == 1 )
2085      {
2086        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );
2087        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ, uiParameter, ((uiCurrPartNumQ >> 1) + (uiCurrPartNumQ << 1)) );
2088      }
2089      else
2090      {
2091        assert(0);
2092      }
2093      break;
2094    case SIZE_2NxnD:
2095      if ( uiPUIdx == 0 )
2096      {
2097        memset( puhBaseCtu + uiCUAddr, uiParameter, ((uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1)) );
2098        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );
2099      }
2100      else if ( uiPUIdx == 1 )
2101      {
2102        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );
2103        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );
2104      }
2105      else
2106      {
2107        assert(0);
2108      }
2109      break;
2110    case SIZE_nLx2N:
2111      if ( uiPUIdx == 0 )
2112      {
2113        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
2114        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2115        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) );
2116        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2117      }
2118      else if ( uiPUIdx == 1 )
2119      {
2120        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
2121        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2122        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) );
2123        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2124      }
2125      else
2126      {
2127        assert(0);
2128      }
2129      break;
2130    case SIZE_nRx2N:
2131      if ( uiPUIdx == 0 )
2132      {
2133        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2134        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2135        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2136        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2137      }
2138      else if ( uiPUIdx == 1 )
2139      {
2140        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
2141        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2142        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) );
2143        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2144      }
2145      else
2146      {
2147        assert(0);
2148      }
2149      break;
2150    default:
2151      assert( 0 );
2152      break;
2153  }
2154}
2155
2156#if NH_3D
2157Void TComDataCU::setSDCFlagSubParts ( Bool bSDCFlag, UInt absPartIdx, UInt depth )
2158{
2159  assert( sizeof( *m_pbSDCFlag) == 1 );
2160  memset( m_pbSDCFlag + absPartIdx, bSDCFlag, m_pcPic->getNumPartitionsInCtu() >> ( 2 * depth ) );
2161}
2162
2163Bool TComDataCU::getSDCAvailable( UInt uiAbsPartIdx )
2164{
2165  if( getSlice()->getIsDepth() && isIntra(uiAbsPartIdx) && getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N )
2166  {
2167    UInt lumaPredMode = getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx );
2168    if( lumaPredMode < NUM_INTRA_MODE ) { return true; }
2169    if( isDmmMode( lumaPredMode )     ) { return true; }
2170  }
2171  return false;
2172}
2173#endif
2174
2175Void TComDataCU::setMergeFlagSubParts ( Bool bMergeFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2176{
2177  setSubPart( bMergeFlag, m_pbMergeFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
2178}
2179
2180Void TComDataCU::setMergeIndexSubParts ( UInt uiMergeIndex, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2181{
2182  setSubPart<UChar>( uiMergeIndex, m_puhMergeIndex, uiAbsPartIdx, uiDepth, uiPartIdx );
2183}
2184
2185#if NH_3D
2186Void TComDataCU::setSPIVMPFlagSubParts( Bool bSPIVMPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2187{
2188  setSubPart<Bool>( bSPIVMPFlag, m_pbSPIVMPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
2189}
2190
2191Void TComDataCU::setVSPFlagSubParts( SChar iVSPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2192{
2193  setSubPart<SChar>( iVSPFlag, m_piVSPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
2194}
2195template<typename T>
2196Void TComDataCU::setSubPartT( T uiParameter, T* puhBaseLCU, UInt uiCUAddr, UInt uiCUDepth, UInt uiPUIdx )
2197{
2198  UInt uiCurrPartNumQ = (m_pcPic->getNumPartitionsInCtu() >> (2 * uiCUDepth)) >> 2;
2199  switch ( m_pePartSize[ uiCUAddr ] )
2200  {
2201  case SIZE_2Nx2N:
2202    for (UInt ui = 0; ui < 4 * uiCurrPartNumQ; ui++)
2203      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2204
2205    break;
2206  case SIZE_2NxN:
2207    for (UInt ui = 0; ui < 2 * uiCurrPartNumQ; ui++)
2208      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2209    break;
2210  case SIZE_Nx2N:
2211    for (UInt ui = 0; ui < uiCurrPartNumQ; ui++)
2212      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2213    for (UInt ui = 0; ui < uiCurrPartNumQ; ui++)
2214      puhBaseLCU[uiCUAddr + 2 * uiCurrPartNumQ + ui] = uiParameter;
2215    break;
2216  case SIZE_NxN:
2217    for (UInt ui = 0; ui < uiCurrPartNumQ; ui++)
2218      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2219    break;
2220  case SIZE_2NxnU:
2221    if ( uiPUIdx == 0 )
2222    {
2223      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2224        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2225      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2226        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + ui] = uiParameter;
2227
2228    }
2229    else if ( uiPUIdx == 1 )
2230    {
2231      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2232        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2233      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1) + (uiCurrPartNumQ << 1); ui++)
2234        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + ui] = uiParameter;
2235
2236    }
2237    else
2238    {
2239      assert(0);
2240    }
2241    break;
2242  case SIZE_2NxnD:
2243    if ( uiPUIdx == 0 )
2244    {
2245      for (UInt ui = 0; ui < ((uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1)); ui++)
2246        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2247      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2248        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ + ui] = uiParameter;
2249
2250    }
2251    else if ( uiPUIdx == 1 )
2252    {
2253      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2254        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2255      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2256        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + ui] = uiParameter;
2257
2258    }
2259    else
2260    {
2261      assert(0);
2262    }
2263    break;
2264  case SIZE_nLx2N:
2265    if ( uiPUIdx == 0 )
2266    {
2267      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2268        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2269      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2270        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2271      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2272        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2273      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2274        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2275
2276    }
2277    else if ( uiPUIdx == 1 )
2278    {
2279      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2280        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2281      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2282        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2283      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2284        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2285      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2286        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2287
2288    }
2289    else
2290    {
2291      assert(0);
2292    }
2293    break;
2294  case SIZE_nRx2N:
2295    if ( uiPUIdx == 0 )
2296    {
2297      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2298        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2299      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2300        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2301      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2302        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2303      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2304        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2305
2306    }
2307    else if ( uiPUIdx == 1 )
2308    {
2309      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2310        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2311      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2312        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2313      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2314        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2315      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2316        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2317
2318    }
2319    else
2320    {
2321      assert(0);
2322    }
2323    break;
2324  default:
2325    assert( 0 );
2326  }
2327
2328}
2329#endif
2330
2331Void TComDataCU::setInterDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2332{
2333  setSubPart<UChar>( uiDir, m_puhInterDir, uiAbsPartIdx, uiDepth, uiPartIdx );
2334}
2335
2336Void TComDataCU::setMVPIdxSubParts( Int iMVPIdx, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2337{
2338  setSubPart<SChar>( iMVPIdx, m_apiMVPIdx[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2339}
2340
2341Void TComDataCU::setMVPNumSubParts( Int iMVPNum, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2342{
2343  setSubPart<SChar>( iMVPNum, m_apiMVPNum[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2344}
2345
2346
2347Void TComDataCU::setTrIdxSubParts( UInt uiTrIdx, UInt uiAbsPartIdx, UInt uiDepth )
2348{
2349  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2350
2351  memset( m_puhTrIdx + uiAbsPartIdx, uiTrIdx, sizeof(UChar)*uiCurrPartNumb );
2352}
2353
2354Void TComDataCU::setTransformSkipSubParts( const UInt useTransformSkip[MAX_NUM_COMPONENT], UInt uiAbsPartIdx, UInt uiDepth )
2355{
2356  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2357
2358  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
2359  {
2360    memset( m_puhTransformSkip[i] + uiAbsPartIdx, useTransformSkip[i], sizeof( UChar ) * uiCurrPartNumb );
2361  }
2362}
2363
2364Void TComDataCU::setTransformSkipSubParts( UInt useTransformSkip, ComponentID compID, UInt uiAbsPartIdx, UInt uiDepth)
2365{
2366  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2367
2368  memset( m_puhTransformSkip[compID] + uiAbsPartIdx, useTransformSkip, sizeof( UChar ) * uiCurrPartNumb );
2369}
2370
2371Void TComDataCU::setTransformSkipPartRange ( UInt useTransformSkip, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2372{
2373  memset((m_puhTransformSkip[compID] + uiAbsPartIdx), useTransformSkip, (sizeof(UChar) * uiCoveredPartIdxes));
2374}
2375
2376Void TComDataCU::setCrossComponentPredictionAlphaPartRange( SChar alphaValue, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2377{
2378  memset((m_crossComponentPredictionAlpha[compID] + uiAbsPartIdx), alphaValue, (sizeof(SChar) * uiCoveredPartIdxes));
2379}
2380
2381Void TComDataCU::setExplicitRdpcmModePartRange ( UInt rdpcmMode, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2382{
2383  memset((m_explicitRdpcmMode[compID] + uiAbsPartIdx), rdpcmMode, (sizeof(UChar) * uiCoveredPartIdxes));
2384}
2385
2386Void TComDataCU::setSizeSubParts( UInt uiWidth, UInt uiHeight, UInt uiAbsPartIdx, UInt uiDepth )
2387{
2388  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2389
2390  memset( m_puhWidth  + uiAbsPartIdx, uiWidth,  sizeof(UChar)*uiCurrPartNumb );
2391  memset( m_puhHeight + uiAbsPartIdx, uiHeight, sizeof(UChar)*uiCurrPartNumb );
2392}
2393
2394UChar TComDataCU::getNumPartitions(const UInt uiAbsPartIdx) const
2395{
2396  UChar iNumPart = 0;
2397
2398  switch ( m_pePartSize[uiAbsPartIdx] )
2399  {
2400    case SIZE_2Nx2N:    iNumPart = 1; break;
2401    case SIZE_2NxN:     iNumPart = 2; break;
2402    case SIZE_Nx2N:     iNumPart = 2; break;
2403    case SIZE_NxN:      iNumPart = 4; break;
2404    case SIZE_2NxnU:    iNumPart = 2; break;
2405    case SIZE_2NxnD:    iNumPart = 2; break;
2406    case SIZE_nLx2N:    iNumPart = 2; break;
2407    case SIZE_nRx2N:    iNumPart = 2; break;
2408    default:            assert (0);   break;
2409  }
2410
2411  return  iNumPart;
2412}
2413
2414// This is for use by a leaf/sub CU object only, with no additional AbsPartIdx
2415#if NH_3D
2416Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight, UInt uiAbsPartIdx, Bool bLCU) const
2417{
2418  UInt uiNumPartition  = bLCU ? (getWidth(uiAbsPartIdx)*getHeight(uiAbsPartIdx) >> 4) : m_uiNumPartition;
2419  UInt  uiTmpAbsPartIdx  = bLCU ? uiAbsPartIdx : 0;
2420
2421  switch ( m_pePartSize[uiTmpAbsPartIdx] )
2422  {
2423  case SIZE_2NxN:
2424    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 1;
2425    break;
2426  case SIZE_Nx2N:
2427    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 2;
2428    break;
2429  case SIZE_NxN:
2430    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiNumPartition >> 2 ) * uiPartIdx;
2431    break;
2432  case SIZE_2NxnU:
2433    riWidth     = getWidth( uiTmpAbsPartIdx );
2434    riHeight    = ( uiPartIdx == 0 ) ?  getHeight( uiTmpAbsPartIdx ) >> 2 : ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 );
2435    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 3;
2436    break;
2437  case SIZE_2NxnD:
2438    riWidth     = getWidth( uiTmpAbsPartIdx );
2439    riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 ) : getHeight( uiTmpAbsPartIdx ) >> 2;
2440    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 1) + (uiNumPartition >> 3);
2441    break;
2442  case SIZE_nLx2N:
2443    riWidth     = ( uiPartIdx == 0 ) ? getWidth( uiTmpAbsPartIdx ) >> 2 : ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 );
2444    riHeight    = getHeight( uiTmpAbsPartIdx );
2445    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 4;
2446    break;
2447  case SIZE_nRx2N:
2448    riWidth     = ( uiPartIdx == 0 ) ? ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 ) : getWidth( uiTmpAbsPartIdx ) >> 2;
2449    riHeight    = getHeight( uiTmpAbsPartIdx );
2450    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 2) + (uiNumPartition >> 4);
2451    break;
2452  default:
2453    assert ( m_pePartSize[uiTmpAbsPartIdx] == SIZE_2Nx2N ); 
2454    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = 0;
2455    break;
2456  }
2457}
2458#else
2459
2460Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight )  const
2461{
2462  switch ( m_pePartSize[0] )
2463  {
2464    case SIZE_2NxN:
2465      riWidth = getWidth(0);      riHeight = getHeight(0) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2466      break;
2467    case SIZE_Nx2N:
2468      riWidth = getWidth(0) >> 1; riHeight = getHeight(0);      ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2;
2469      break;
2470    case SIZE_NxN:
2471      riWidth = getWidth(0) >> 1; riHeight = getHeight(0) >> 1; ruiPartAddr = ( m_uiNumPartition >> 2 ) * uiPartIdx;
2472      break;
2473    case SIZE_2NxnU:
2474      riWidth     = getWidth(0);
2475      riHeight    = ( uiPartIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
2476      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 3;
2477      break;
2478    case SIZE_2NxnD:
2479      riWidth     = getWidth(0);
2480      riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
2481      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 3);
2482      break;
2483    case SIZE_nLx2N:
2484      riWidth     = ( uiPartIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
2485      riHeight    = getHeight(0);
2486      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 4;
2487      break;
2488    case SIZE_nRx2N:
2489      riWidth     = ( uiPartIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
2490      riHeight    = getHeight(0);
2491      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2492      break;
2493    default:
2494      assert ( m_pePartSize[0] == SIZE_2Nx2N );
2495      riWidth = getWidth(0);      riHeight = getHeight(0);      ruiPartAddr = 0;
2496      break;
2497  }
2498}
2499#endif
2500
2501// static member function
2502Void TComDataCU::getMvField ( const TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, TComMvField& rcMvField )
2503{
2504  if ( pcCU == NULL )  // OUT OF BOUNDARY
2505  {
2506    TComMv  cZeroMv;
2507    rcMvField.setMvField( cZeroMv, NOT_VALID );
2508    return;
2509  }
2510
2511  const TComCUMvField*  pcCUMvField = pcCU->getCUMvField( eRefPicList );
2512  rcMvField.setMvField( pcCUMvField->getMv( uiAbsPartIdx ), pcCUMvField->getRefIdx( uiAbsPartIdx ) );
2513}
2514
2515Void TComDataCU::deriveLeftRightTopIdxGeneral ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT ) const
2516{
2517  ruiPartIdxLT = m_absZIdxInCtu + uiAbsPartIdx;
2518  UInt uiPUWidth = 0;
2519
2520  switch ( m_pePartSize[uiAbsPartIdx] )
2521  {
2522    case SIZE_2Nx2N: uiPUWidth = m_puhWidth[uiAbsPartIdx];  break;
2523    case SIZE_2NxN:  uiPUWidth = m_puhWidth[uiAbsPartIdx];   break;
2524    case SIZE_Nx2N:  uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1;  break;
2525    case SIZE_NxN:   uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1; break;
2526    case SIZE_2NxnU:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2527    case SIZE_2NxnD:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2528    case SIZE_nLx2N:
2529      if ( uiPartIdx == 0 )
2530      {
2531        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2;
2532      }
2533      else if ( uiPartIdx == 1 )
2534      {
2535        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2);
2536      }
2537      else
2538      {
2539        assert(0);
2540      }
2541      break;
2542    case SIZE_nRx2N:
2543      if ( uiPartIdx == 0 )
2544      {
2545        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2);
2546      }
2547      else if ( uiPartIdx == 1 )
2548      {
2549        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2;
2550      }
2551      else
2552      {
2553        assert(0);
2554      }
2555      break;
2556    default:
2557      assert (0);
2558      break;
2559  }
2560
2561  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + uiPUWidth / m_pcPic->getMinCUWidth() - 1 ];
2562}
2563
2564Void TComDataCU::deriveLeftBottomIdxGeneral( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLB ) const
2565{
2566  UInt uiPUHeight = 0;
2567  switch ( m_pePartSize[uiAbsPartIdx] )
2568  {
2569    case SIZE_2Nx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];    break;
2570    case SIZE_2NxN:  uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2571    case SIZE_Nx2N:  uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2572    case SIZE_NxN:   uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2573    case SIZE_2NxnU:
2574      if ( uiPartIdx == 0 )
2575      {
2576        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;
2577      }
2578      else if ( uiPartIdx == 1 )
2579      {
2580        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);
2581      }
2582      else
2583      {
2584        assert(0);
2585      }
2586      break;
2587    case SIZE_2NxnD:
2588      if ( uiPartIdx == 0 )
2589      {
2590        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);
2591      }
2592      else if ( uiPartIdx == 1 )
2593      {
2594        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;
2595      }
2596      else
2597      {
2598        assert(0);
2599      }
2600      break;
2601    case SIZE_nLx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2602    case SIZE_nRx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2603    default:
2604      assert (0);
2605      break;
2606  }
2607
2608  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_absZIdxInCtu + uiAbsPartIdx ] + ((uiPUHeight / m_pcPic->getMinCUHeight()) - 1)*m_pcPic->getNumPartInCtuWidth()];
2609}
2610
2611Void TComDataCU::deriveLeftRightTopIdx ( UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT ) const
2612{
2613  ruiPartIdxLT = m_absZIdxInCtu;
2614  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + m_puhWidth[0] / m_pcPic->getMinCUWidth() - 1 ];
2615
2616  switch ( m_pePartSize[0] )
2617  {
2618    case SIZE_2Nx2N:                                                                                                                                break;
2619    case SIZE_2NxN:
2620      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1; ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2621      break;
2622    case SIZE_Nx2N:
2623      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2; ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 2;
2624      break;
2625    case SIZE_NxN:
2626      ruiPartIdxLT += ( m_uiNumPartition >> 2 ) * uiPartIdx;         ruiPartIdxRT +=  ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );
2627      break;
2628    case SIZE_2NxnU:
2629      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2630      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2631      break;
2632    case SIZE_2NxnD:
2633      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2634      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2635      break;
2636    case SIZE_nLx2N:
2637      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 4;
2638      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2639      break;
2640    case SIZE_nRx2N:
2641      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2642      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 4;
2643      break;
2644    default:
2645      assert (0);
2646      break;
2647  }
2648
2649}
2650
2651Void TComDataCU::deriveLeftBottomIdx( UInt  uiPartIdx,      UInt&      ruiPartIdxLB ) const
2652{
2653  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_absZIdxInCtu ] + ( ((m_puhHeight[0] / m_pcPic->getMinCUHeight())>>1) - 1)*m_pcPic->getNumPartInCtuWidth()];
2654
2655  switch ( m_pePartSize[0] )
2656  {
2657    case SIZE_2Nx2N:
2658      ruiPartIdxLB += m_uiNumPartition >> 1;
2659      break;
2660    case SIZE_2NxN:
2661      ruiPartIdxLB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2662      break;
2663    case SIZE_Nx2N:
2664      ruiPartIdxLB += ( uiPartIdx == 0 )? m_uiNumPartition >> 1 : (m_uiNumPartition >> 2)*3;
2665      break;
2666    case SIZE_NxN:
2667      ruiPartIdxLB += ( m_uiNumPartition >> 2 ) * uiPartIdx;
2668      break;
2669    case SIZE_2NxnU:
2670      ruiPartIdxLB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2671      break;
2672    case SIZE_2NxnD:
2673      ruiPartIdxLB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2674      break;
2675    case SIZE_nLx2N:
2676      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 4);
2677      break;
2678    case SIZE_nRx2N:
2679      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2680      break;
2681    default:
2682      assert (0);
2683      break;
2684  }
2685}
2686
2687/** Derive the partition index of neighbouring bottom right block
2688 * \param [in]  uiPartIdx     current partition index
2689 * \param [out] ruiPartIdxRB  partition index of neighbouring bottom right block
2690 */
2691Void TComDataCU::deriveRightBottomIdx( UInt uiPartIdx, UInt &ruiPartIdxRB ) const
2692{
2693  ruiPartIdxRB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_absZIdxInCtu ] + ( ((m_puhHeight[0] / m_pcPic->getMinCUHeight())>>1) - 1)*m_pcPic->getNumPartInCtuWidth() +  m_puhWidth[0] / m_pcPic->getMinCUWidth() - 1];
2694
2695  switch ( m_pePartSize[0] )
2696  {
2697    case SIZE_2Nx2N:
2698      ruiPartIdxRB += m_uiNumPartition >> 1;
2699      break;
2700    case SIZE_2NxN:
2701      ruiPartIdxRB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2702      break;
2703    case SIZE_Nx2N:
2704      ruiPartIdxRB += ( uiPartIdx == 0 )? m_uiNumPartition >> 2 : (m_uiNumPartition >> 1);
2705      break;
2706    case SIZE_NxN:
2707      ruiPartIdxRB += ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );
2708      break;
2709    case SIZE_2NxnU:
2710      ruiPartIdxRB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2711      break;
2712    case SIZE_2NxnD:
2713      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2714      break;
2715    case SIZE_nLx2N:
2716      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4): m_uiNumPartition >> 1;
2717      break;
2718    case SIZE_nRx2N:
2719      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4) : m_uiNumPartition >> 1;
2720      break;
2721    default:
2722      assert (0);
2723      break;
2724  }
2725}
2726
2727Bool TComDataCU::hasEqualMotion( UInt uiAbsPartIdx, const TComDataCU* pcCandCU, UInt uiCandAbsPartIdx ) const
2728{
2729  if ( getInterDir( uiAbsPartIdx ) != pcCandCU->getInterDir( uiCandAbsPartIdx ) )
2730  {
2731    return false;
2732  }
2733
2734  for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
2735  {
2736    if ( getInterDir( uiAbsPartIdx ) & ( 1 << uiRefListIdx ) )
2737    {
2738      if ( getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiAbsPartIdx )     != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiCandAbsPartIdx ) ||
2739        getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiAbsPartIdx ) != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiCandAbsPartIdx ) )
2740      {
2741        return false;
2742      }
2743    }
2744  }
2745
2746  return true;
2747}
2748
2749#if NH_3D
2750Bool TComDataCU::hasEqualMotion( Int dirA, const TComMvField* mvFieldA, Int dirB, const TComMvField* mvFieldB )
2751{
2752  return  ( dirA == dirB  &&
2753    ( ( dirA & 1 ) == 0 || mvFieldA[0] == mvFieldB[0]  ) &&
2754    ( ( dirA & 2 ) == 0 || mvFieldA[1] == mvFieldB[1]  ) 
2755    );
2756}
2757
2758/** Add a VSP merging candidate
2759 * \Inputs
2760 * \param uiPUIdx: PU index within a CU
2761 * \param ucVspMergePos: Specify the VSP merge candidate position
2762 * \param mrgCandIdx: Target merge candidate index. At encoder, it is set equal to -1, such that the whole merge candidate list will be constructed.
2763 * \param pDinfo: The "disparity information" derived from neighboring blocks. Type 1 MV.
2764 * \param uiCount: The next position to add VSP merge candidate
2765 *
2766 * \Outputs
2767 * \param uiCount: The next position to add merge candidate. Will be updated if VSP is successfully added
2768 * \param abCandIsInter: abCandIsInter[iCount] tells that VSP candidate is an Inter candidate, if VSP is successfully added
2769 * \param pcMvFieldNeighbours:   Return combined motion information, then stored to a global buffer
2770 *                                    1) the "disparity vector". Type 1 MV. To be used to fetch a depth block.
2771 *                                    2) the ref index /list.    Type 2 reference picture pointer, typically for texture
2772 * \param puhInterDirNeighbours: Indicate the VSP prediction direction.
2773 * \param vspFlag: vspFlag[iCount] will be set (equal to 1), if VSP is successfully added. To be used to indicate the actual position of the VSP candidate
2774 *
2775 * \Return
2776 *   true:  if the VSP candidate is added at the target position
2777 *   false: otherwise
2778 */
2779inline Bool TComDataCU::xAddVspCand( Int mrgCandIdx, DisInfo* pDInfo, Int& iCount)
2780{
2781  if ( m_pcSlice->getViewIndex() == 0 || !m_pcSlice->getViewSynthesisPredFlag( ) || m_pcSlice->getIsDepth() || pDInfo->m_aVIdxCan == -1)
2782  {
2783    return false;
2784  }
2785
2786  Int refViewIdx = pDInfo->m_aVIdxCan;
2787  TComPic* picDepth = getSlice()->getIvPic( true, refViewIdx );
2788
2789  if( picDepth == NULL ) // No depth reference avail
2790  {
2791    // Is this allowed to happen? When not an assertion should be added here!
2792    return false;
2793  }
2794
2795  TComMvField mvVSP[2];
2796  UChar dirVSP;
2797  Bool  refViewAvailFlag = false;
2798  UChar predFlag[2]      = {0, 0};
2799
2800  for( Int iRefListIdX = 0; iRefListIdX < 2 && !refViewAvailFlag; iRefListIdX++ )
2801  {
2802    RefPicList eRefPicListX = RefPicList( iRefListIdX );
2803    for ( Int i = 0; i < m_pcSlice->getNumRefIdx(eRefPicListX) && !refViewAvailFlag; i++ )
2804    {
2805      Int viewIdxRefInListX = m_pcSlice->getRefPic(eRefPicListX, i)->getViewIndex();
2806      if ( viewIdxRefInListX == refViewIdx )
2807      {
2808        refViewAvailFlag      = true;
2809        predFlag[iRefListIdX] = 1;
2810        mvVSP[0+iRefListIdX].setMvField( pDInfo->m_acNBDV, i );
2811        mvVSP[0+iRefListIdX].getMv().setIDVFlag (false);
2812      }
2813    }
2814  }
2815
2816  dirVSP = (predFlag[0] | (predFlag[1] << 1));
2817  m_mergCands[MRG_VSP].setCand( mvVSP, dirVSP, true    , false);
2818  if ( mrgCandIdx == iCount )
2819  {
2820    return true;
2821  }
2822
2823  iCount++;
2824
2825  return false;
2826}
2827
2828inline Bool TComDataCU::xAddIvMRGCand( Int mrgCandIdx, Int& iCount, Int* ivCandDir, TComMv* ivCandMv, Int* ivCandRefIdx )
2829{
2830  for(Int iLoop = 0; iLoop < 2; iLoop ++ ) 
2831  {
2832    /// iLoop = 0 --> IvMCShift
2833    /// iLoop = 1 --> IvDCShift  (Derived from IvDC)
2834    if(ivCandDir[iLoop + 2])
2835    {
2836      TComMvField tmpMV[2];
2837      UChar tmpDir = ivCandDir[iLoop + 2];
2838      if( ( ivCandDir[iLoop + 2] & 1 ) == 1 )
2839      {
2840        tmpMV[0].setMvField( ivCandMv[ (iLoop<<1) + 4 ], ivCandRefIdx[ (iLoop<<1) + 4 ] ); 
2841      }
2842      if( ( ivCandDir[iLoop + 2] & 2 ) == 2 )
2843      {
2844        tmpMV[1].setMvField( ivCandMv[ (iLoop<<1) + 5 ], ivCandRefIdx[ (iLoop<<1) + 5 ] );
2845      }
2846     
2847      // Prune IvMC vs. IvMcShift
2848      Bool bRemove = false;     
2849      if( !iLoop && ivCandDir[0] > 0)
2850      {
2851        if( hasEqualMotion(tmpDir, tmpMV, m_mergCands[MRG_IVMC].m_uDir, m_mergCands[MRG_IVMC].m_cMvField )) 
2852        {
2853            bRemove                         = true;
2854        }
2855      }
2856      if(!bRemove)
2857      {
2858        if(iLoop) // For IvMcShift candidate
2859        {
2860          tmpMV[0].getMv().setIDVFlag (false);
2861          tmpMV[1].getMv().setIDVFlag (false);
2862        }
2863        m_mergCands[MRG_IVSHIFT].setCand(tmpMV, tmpDir, false, false);
2864        if( mrgCandIdx == iCount )
2865        {
2866          return true;
2867        }
2868        iCount++;
2869      }
2870      break;
2871    }
2872  }
2873  return false;
2874} 
2875
2876/** Construct a extended list of merging candidates
2877 * \param pcMvFieldNeighbours
2878 * \param puhInterDirNeighbours
2879 * \param vspFlag
2880 * \param pbSPIVMPFlag
2881 * \param numValidMergeCand
2882 */
2883Void TComDataCU::buildMCL(TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int* vspFlag  , Bool* pbSPIVMPFlag  , Int& numValidMergeCand  )
2884{
2885  if (!( getSlice()->getIsDepth() || getSlice()->getViewIndex()>0))
2886  {
2887    return;
2888  }
2889
2890#if ENC_DEC_TRACE && NH_MV_ENC_DEC_TRAC
2891  if ( g_traceMergeCandListConst ) 
2892  {
2893    for (Int i = 0; i<MRG_IVSHIFT+1; i++)
2894    {
2895      m_mergCands[i].print( i ); 
2896    }
2897  }
2898#endif
2899
2900
2901  Int iCount = 0;
2902  TComMv cZeroMv;
2903
2904  // init temporal list
2905  TComMvField extMergeCandList[MRG_MAX_NUM_CANDS_MEM << 1];
2906  UChar uhInterDirNeighboursExt[MRG_MAX_NUM_CANDS_MEM];
2907  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
2908  {
2909    uhInterDirNeighboursExt[ui] = puhInterDirNeighbours[ui];
2910    extMergeCandList[ui<<1].setMvField(cZeroMv, NOT_VALID);
2911    extMergeCandList[(ui<<1)+1].setMvField(cZeroMv, NOT_VALID);
2912    vspFlag[ui] = 0;
2913  }
2914
2915  // insert MPI ... IvShift candidate to extMergeCandList
2916  for (Int i=0; i<=MRG_IVSHIFT; i++)
2917  {
2918    if (m_mergCands[i].m_bAvailable)
2919    {
2920      m_mergCands[i].getCand(iCount, extMergeCandList, uhInterDirNeighboursExt, vspFlag, pbSPIVMPFlag );
2921      iCount++;
2922      if (iCount >= getSlice()->getMaxNumMergeCand())
2923        break;
2924    }
2925  }
2926
2927  Int iCountBase = m_numSpatialCands;
2928  // insert remaining base candidates to extMergeCandList
2929  while (iCount < getSlice()->getMaxNumMergeCand() && iCountBase < getSlice()->getMaxNumMergeCand())
2930  {
2931    uhInterDirNeighboursExt[iCount] = puhInterDirNeighbours[iCountBase];
2932    extMergeCandList[iCount<<1].setMvField(pcMvFieldNeighbours[iCountBase<<1].getMv(), pcMvFieldNeighbours[iCountBase<<1].getRefIdx());
2933    if ( getSlice()->isInterB() )
2934    {
2935      extMergeCandList[(iCount<<1)+1].setMvField(pcMvFieldNeighbours[(iCountBase<<1)+1].getMv(), pcMvFieldNeighbours[(iCountBase<<1)+1].getRefIdx());
2936    }
2937    iCountBase++;
2938    iCount++;
2939  }
2940
2941  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ui++ )
2942  {
2943    puhInterDirNeighbours[ui] = 0;
2944    pcMvFieldNeighbours[ui<<1].setMvField(cZeroMv, NOT_VALID);
2945    pcMvFieldNeighbours[(ui<<1)+1].setMvField(cZeroMv, NOT_VALID);
2946  }
2947
2948  // copy extMergeCandList to output
2949  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ui++ )
2950  {
2951    puhInterDirNeighbours[ui] = uhInterDirNeighboursExt[ui];
2952    pcMvFieldNeighbours[ui<<1].setMvField(extMergeCandList[ui<<1].getMv(), extMergeCandList[ui<<1].getRefIdx());
2953
2954    if ( getSlice()->isInterB() )
2955    {
2956      pcMvFieldNeighbours[(ui<<1)+1].setMvField(extMergeCandList[(ui<<1)+1].getMv(), extMergeCandList[(ui<<1)+1].getRefIdx());
2957    }
2958  }
2959
2960#if ENC_DEC_TRACE && NH_MV_ENC_DEC_TRAC
2961  if ( g_traceMergeCandListConst )
2962  {
2963    std::cout << std::setfill(' ')                          << std::setw( 15 )
2964      <<  "Num"                                             << std::setw( 15 )
2965      <<  "Dir "                                            << std::setw( 15 )
2966      <<  "L0 RefIdx"                                       << std::setw( 15 )
2967      <<  "L0 Hor"                                          << std::setw( 15 )
2968      <<  "L0 Ver"                                          << std::setw( 15 )
2969      <<  "L1 RefIdx"                                       << std::setw( 15 )
2970      <<  "L1 Hor"                                          << std::setw( 15 )
2971      <<  "L1 Ver"                                          << std::setw( 15 )
2972      << std::endl; 
2973
2974    // copy extMergeCandList to output
2975    for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ui++ )
2976    {
2977      UChar curDir        = puhInterDirNeighbours[ui];
2978      TComMvField& curf   = pcMvFieldNeighbours[ui<<1];
2979      TComMvField& curf2  = pcMvFieldNeighbours[(ui<<1)+1];
2980
2981      std::cout << std::setfill(' ')                         << std::setw( 15 )
2982        << ui                                                << std::setw( 15 )       
2983        << (UInt) curDir                                     << std::setw( 15 )   
2984        << ((curDir & 1) ? curf.getRefIdx()       : MIN_INT) << std::setw( 15 )
2985        << ((curDir & 1) ? curf.getMv().getHor()  : MIN_INT) << std::setw( 15 )
2986        << ((curDir & 1) ? curf.getMv().getVer()  : MIN_INT) << std::setw( 15 );
2987
2988      if ( getSlice()->isInterB() )
2989      {     
2990        std::cout << ((curDir & 2) ? curf2.getRefIdx() : MIN_INT) << std::setw( 15 )
2991          << ((curDir & 1) ? curf2.getMv().getHor()    : MIN_INT) << std::setw( 15 )
2992          << ((curDir & 1) ? curf2.getMv().getVer()    : MIN_INT) << std::setw( 15 );
2993      }
2994      std::cout << std::endl; 
2995    }
2996  }
2997#endif
2998  numValidMergeCand = iCount;
2999  assert(iCount == getSlice()->getMaxNumMergeCand());
3000}
3001
3002
3003
3004/** Derive 3D merge candidates
3005 * \param uiAbsPartIdx
3006 * \param uiPUIdx
3007 * \param pcMvFieldNeighbours
3008 * \param puhInterDirNeighbours
3009 * \param pcMvFieldSP
3010 * \param puhInterDirNeighbours
3011 * \param numValidMergeCand
3012 */
3013
3014Void TComDataCU::xGetInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours, TComMvField* pcMvFieldSP, UChar* puhInterDirSP, Int& numValidMergeCand, Int mrgCandIdx )
3015{
3016  TComMv cZeroMv;
3017  TComMvField tmpMV[2]; 
3018
3019  //////////////////////////////////
3020  //////// GET DISPARITIES  ////////
3021  //////////////////////////////////
3022  DisInfo cDisInfo = getDvInfo(uiAbsPartIdx);
3023  m_cDefaultDisInfo = cDisInfo;
3024
3025  if (!( getSlice()->getIsDepth() || getSlice()->getViewIndex()>0))
3026  {
3027    return;
3028  }
3029  numValidMergeCand = getSlice()->getMaxNumMergeCand();
3030  //////////////////////////////////
3031  //////// DERIVE LOCATIONS ////////
3032  //////////////////////////////////
3033  // compute the location of the current PU
3034  Int xP, yP, nPSW, nPSH;
3035  this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
3036
3037  Int iCount = 0;
3038  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
3039  deriveLeftRightTopIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLT, uiPartIdxRT );
3040  deriveLeftBottomIdxGeneral  ( uiAbsPartIdx, uiPUIdx, uiPartIdxLB );
3041  Bool bMPIFlag   = getSlice()->getMpiFlag(); 
3042  Int  tmpDir;
3043  Bool bIsDepth = getSlice()->getIsDepth();
3044
3045  Bool bICFlag = getICFlag(uiAbsPartIdx);
3046  Bool bARPFlag = getARPW(uiAbsPartIdx) > 0;
3047  Bool bDBBPFlag = getDBBPFlag(uiAbsPartIdx);
3048  assert(bDBBPFlag == getDBBPFlag(0)); 
3049
3050  for(Int i = 0; i < MRG_MAX_NUM_CANDS_MEM; i++) 
3051  {
3052    pcMFieldNeighbours[i<<1    ].getMv().setIDVFlag (false);
3053    pcMFieldNeighbours[(i<<1)+1].getMv().setIDVFlag (false);
3054  }
3055  // init containers
3056  for (Int i = 0; i<MRG_IVSHIFT+1; i++)
3057    m_mergCands[i].init();
3058
3059  m_numSpatialCands = 0;
3060
3061  //////////////////////////////////
3062  ///////// GET VSP FLAGS //////////
3063  //////////////////////////////////
3064  //left
3065  UInt uiLeftPartIdx = 0;
3066  const TComDataCU* pcCULeft = 0;
3067  pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB ); 
3068
3069  if (getAvailableFlagA1())
3070  {
3071    m_mergCands[MRG_A1].setCand( &pcMFieldNeighbours[m_numSpatialCands<<1], puhInterDirNeighbours[m_numSpatialCands], (pcCULeft->getVSPFlag(uiLeftPartIdx) != 0 && !bICFlag && !bARPFlag&& !bDBBPFlag), false ); 
3072    m_numSpatialCands++;
3073  }
3074
3075  // above
3076  if (getAvailableFlagB1())
3077  {
3078    m_mergCands[MRG_B1].setCand( &pcMFieldNeighbours[m_numSpatialCands<<1], puhInterDirNeighbours[m_numSpatialCands], false, false ); 
3079    m_numSpatialCands++;
3080  }
3081
3082  // above right
3083  if (getAvailableFlagB0())
3084  {
3085    m_mergCands[MRG_B0].setCand( &pcMFieldNeighbours[m_numSpatialCands<<1], puhInterDirNeighbours[m_numSpatialCands], false, false ); 
3086    m_numSpatialCands++;
3087  }
3088
3089  // left bottom
3090  if (getAvailableFlagA0())
3091  {
3092    m_mergCands[MRG_A0].setCand( &pcMFieldNeighbours[m_numSpatialCands<<1], puhInterDirNeighbours[m_numSpatialCands], false, false ); 
3093    m_numSpatialCands++;
3094  }
3095
3096  // above left
3097  if (getAvailableFlagB2())
3098  {
3099    m_mergCands[MRG_B2].setCand( &pcMFieldNeighbours[m_numSpatialCands<<1], puhInterDirNeighbours[m_numSpatialCands], false, false ); 
3100    m_numSpatialCands++;
3101  }
3102
3103
3104  /////////////////////////////////////////////
3105  //////// TEXTURE MERGE CANDIDATE (T) ////////
3106  /////////////////////////////////////////////
3107
3108  bMPIFlag &= (nPSW + nPSH > 12);
3109  if( bMPIFlag)
3110  {
3111    tmpMV[0].setMvField( cZeroMv, NOT_VALID );
3112    tmpMV[1].setMvField( cZeroMv, NOT_VALID );
3113    tmpDir        =  0;
3114
3115    Bool bSPIVMPFlag = false;
3116
3117    TComPic * pcTexPic = m_pcSlice->getTexturePic();
3118      TComPicYuv*   pcTexRec = pcTexPic->getPicYuvRec  ();
3119      UInt          uiPartAddr;
3120      Int           iWidth, iHeight;
3121      Int           iCurrPosX, iCurrPosY;
3122
3123      this->getPartIndexAndSize( uiPUIdx, uiPartAddr, iWidth, iHeight );
3124      pcTexRec->getTopLeftSamplePos( this->getCtuRsAddr(), this->getZorderIdxInCtu() + uiPartAddr, iCurrPosX, iCurrPosY );
3125
3126      Int iPUWidth, iPUHeight, iNumPart, iNumPartLine;
3127      this->getSPPara(iWidth, iHeight, iNumPart, iNumPartLine, iPUWidth, iPUHeight);
3128
3129      for (Int i=0; i<iNumPart; i++)
3130      {
3131        puhInterDirSP[i] = 0;
3132        pcMvFieldSP[2*i].getMv().set(0, 0);
3133        pcMvFieldSP[2*i+1].getMv().set(0, 0);
3134        pcMvFieldSP[2*i].setRefIdx(-1);
3135        pcMvFieldSP[2*i+1].setRefIdx(-1);
3136      }
3137
3138      Int         iTexCUAddr;
3139      Int         iTexAbsPartIdx;
3140      TComDataCU* pcTexCU;
3141      Int iPartition = 0;
3142      Int iInterDirSaved = 0;
3143      TComMvField cMvFieldSaved[2];
3144
3145      Int iOffsetX = iPUWidth/2;;
3146      Int iOffsetY = iPUHeight/2;
3147
3148      Int         iTexPosX, iTexPosY;
3149      const TComMv cMvRounding( 1 << ( 2 - 1 ), 1 << ( 2 - 1 ) );
3150
3151      Int         iCenterPosX = iCurrPosX + ( ( iWidth /  iPUWidth ) >> 1 )  * iPUWidth + ( iPUWidth >> 1 );
3152      Int         iCenterPosY = iCurrPosY + ( ( iHeight /  iPUHeight ) >> 1 )  * iPUHeight + (iPUHeight >> 1);
3153      Int         iTexCenterCUAddr, iTexCenterAbsPartIdx;
3154
3155      if(iWidth == iPUWidth && iHeight == iPUHeight)
3156      {
3157        iCenterPosX = iCurrPosX + (iWidth >> 1);
3158        iCenterPosY = iCurrPosY + (iHeight >> 1);
3159      }
3160
3161      // derivation of center motion parameters from the collocated texture CU
3162
3163      pcTexRec->getCUAddrAndPartIdx( iCenterPosX , iCenterPosY , iTexCenterCUAddr, iTexCenterAbsPartIdx );
3164      TComDataCU* pcDefaultCU    = pcTexPic->getCtu( iTexCenterCUAddr );
3165
3166      if( pcDefaultCU->getPredictionMode( iTexCenterAbsPartIdx ) != MODE_INTRA )
3167      {
3168        for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )
3169        {
3170          RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
3171
3172          TComMvField cDefaultMvField;
3173          pcDefaultCU->getMvField( pcDefaultCU, iTexCenterAbsPartIdx, eCurrRefPicList, cDefaultMvField );
3174          Int         iDefaultRefIdx     = cDefaultMvField.getRefIdx();
3175          if (iDefaultRefIdx >= 0)
3176          {
3177            Int iDefaultRefPOC = pcDefaultCU->getSlice()->getRefPOC(eCurrRefPicList, iDefaultRefIdx);
3178            for (Int iRefPicList = 0; iRefPicList < m_pcSlice->getNumRefIdx( eCurrRefPicList ); iRefPicList++)
3179            {
3180              if (iDefaultRefPOC == m_pcSlice->getRefPOC(eCurrRefPicList, iRefPicList))
3181              {
3182                bSPIVMPFlag = true;
3183                TComMv cMv = cDefaultMvField.getMv() + cMvRounding;
3184                cMv >>= 2;
3185                cMvFieldSaved[eCurrRefPicList].setMvField(cMv, iRefPicList) ;
3186                break;
3187              }
3188            }
3189          }
3190        }
3191      }
3192      if ( bSPIVMPFlag == true )
3193      {   
3194        iInterDirSaved = (cMvFieldSaved[0].getRefIdx()!=-1 ? 1: 0) + (cMvFieldSaved[1].getRefIdx()!=-1 ? 2: 0);
3195        tmpDir = iInterDirSaved;
3196        tmpMV[0] = cMvFieldSaved[0];
3197        tmpMV[1] = cMvFieldSaved[1];
3198      }
3199
3200      if ( iInterDirSaved != 0 )
3201      {
3202        for (Int i=iCurrPosY; i < iCurrPosY + iHeight; i += iPUHeight)
3203        {
3204          for (Int j = iCurrPosX; j < iCurrPosX + iWidth; j += iPUWidth)
3205          {
3206            iTexPosX     = j + iOffsetX;
3207            iTexPosY     = i + iOffsetY; 
3208            pcTexRec->getCUAddrAndPartIdx( iTexPosX, iTexPosY, iTexCUAddr, iTexAbsPartIdx );
3209            pcTexCU  = pcTexPic->getCtu( iTexCUAddr );
3210
3211            if( pcTexCU && !pcTexCU->isIntra(iTexAbsPartIdx) )
3212            {
3213              for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )
3214              {
3215                RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
3216                TComMvField cTexMvField;
3217                pcTexCU->getMvField( pcTexCU, iTexAbsPartIdx, eCurrRefPicList, cTexMvField );
3218                Int iValidDepRef = getPic()->isTextRefValid( eCurrRefPicList, cTexMvField.getRefIdx() );
3219                if( (cTexMvField.getRefIdx()>=0) && ( iValidDepRef >= 0 ) )
3220                {
3221                  TComMv cMv = cTexMvField.getMv() + cMvRounding;
3222                  cMv >>=2;         
3223                  pcMvFieldSP[2*iPartition + uiCurrRefListId].setMvField(cMv, iValidDepRef);
3224                }
3225              }
3226            }
3227            puhInterDirSP[iPartition] = (pcMvFieldSP[2*iPartition].getRefIdx()!=-1 ? 1: 0) + (pcMvFieldSP[2*iPartition+1].getRefIdx()!=-1 ? 2: 0);
3228            if (puhInterDirSP[iPartition] == 0)
3229            {
3230              if (iInterDirSaved != 0)
3231              {
3232                puhInterDirSP[iPartition] = iInterDirSaved;
3233                pcMvFieldSP[2*iPartition] = cMvFieldSaved[0];
3234                pcMvFieldSP[2*iPartition + 1] = cMvFieldSaved[1];
3235              }
3236            }
3237
3238            iPartition ++;
3239          }
3240        }
3241      }
3242
3243    if( tmpDir != 0 )
3244    {
3245      Int iCnloop = 0;
3246      for(iCnloop = 0; iCnloop < 2; iCnloop ++)
3247      {
3248        if ( !m_mergCands[MRG_A1+iCnloop].m_bAvailable )  // pruning to A1, B1
3249        {
3250          continue;
3251        }
3252        if (hasEqualMotion( tmpDir, tmpMV, m_mergCands[MRG_A1+iCnloop].m_uDir, m_mergCands[MRG_A1+iCnloop].m_cMvField ) )
3253        {
3254          m_mergCands[MRG_A1+iCnloop].m_bAvailable = false;
3255          break;
3256        }     
3257      }
3258      m_mergCands[MRG_T].setCand( tmpMV, tmpDir, false, bSPIVMPFlag);
3259
3260      if ( mrgCandIdx == iCount )
3261      {
3262        return;
3263      }
3264      iCount ++;
3265    }
3266  }
3267
3268  /////////////////////////////////////////////////////////////////
3269  //////// DERIVE IvMC, IvMCShift,IvDCShift, IvDC  Candidates /////
3270  /////////////////////////////////////////////////////////////////
3271
3272  // { IvMCL0, IvMCL1, IvDCL0, IvDCL1, IvMCL0Shift, IvMCL1Shift, IvDCL0Shift, IvDCL1Shift }; 
3273  // An enumerator would be appropriate here!
3274  TComMv ivCandMv    [8];
3275  Int    ivCandRefIdx[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
3276
3277  // { IvMC, IvDC, IvMCShift, IvDCShift }; 
3278  Int    ivCandDir   [4] = {0, 0, 0, 0};
3279
3280  Bool ivMvPredFlag   = getSlice()->getIvMvPredFlag();
3281
3282  ivMvPredFlag &= (nPSW + nPSH > 12);
3283  if ( ivMvPredFlag && cDisInfo.m_aVIdxCan!=-1)
3284  {
3285    getInterViewMergeCands(uiPUIdx, ivCandRefIdx, ivCandMv, &cDisInfo, ivCandDir , bIsDepth, pcMvFieldSP, puhInterDirSP, bICFlag );
3286  } 
3287
3288  ///////////////////////////////////////////////
3289  //////// INTER VIEW MOTION COMP(IvMC) /////////
3290  ///////////////////////////////////////////////
3291  if( getSlice()->getIsDepth() )
3292  {
3293    ivCandDir[1] = ivCandDir[2] = ivCandDir[3] = 0;
3294  }
3295
3296  if( ivCandDir[0] )
3297  {
3298    tmpMV[0].setMvField( cZeroMv, NOT_VALID );
3299    tmpMV[1].setMvField( cZeroMv, NOT_VALID );
3300
3301    if( ( ivCandDir[0] & 1 ) == 1 )
3302    {
3303      tmpMV[0].setMvField( ivCandMv[ 0 ], ivCandRefIdx[ 0 ] );
3304    }
3305    if( ( ivCandDir[0] & 2 ) == 2 )
3306    {
3307      tmpMV[1].setMvField( ivCandMv[ 1 ], ivCandRefIdx[ 1 ] );
3308    }
3309
3310    Bool bRemoveSpa = false; //pruning
3311
3312    if (!bIsDepth)
3313    {
3314      for(Int i = 0; i < 2; i ++)
3315      {
3316        if ( !m_mergCands[MRG_A1 + i].m_bAvailable ) // pruning to A1, B1
3317        {
3318          continue;
3319        }
3320        if (hasEqualMotion(ivCandDir[0], tmpMV, m_mergCands[MRG_A1+i].m_uDir,  m_mergCands[MRG_A1+i].m_cMvField) )
3321        {
3322          m_mergCands[MRG_A1+i].m_bAvailable = false;
3323          break;
3324        }     
3325      }
3326    }
3327    else
3328    {
3329      if( hasEqualMotion( ivCandDir[0], tmpMV, m_mergCands[MRG_T].m_uDir, m_mergCands[MRG_T].m_cMvField ) )
3330      {
3331        bRemoveSpa                      = true;
3332      }
3333    }
3334    if (!bRemoveSpa)
3335    {
3336      Bool spiMvpFlag = false;
3337      if(!m_pcSlice->getIsDepth())
3338      {
3339        spiMvpFlag = true;
3340      }
3341      spiMvpFlag &= !bDBBPFlag;
3342
3343      m_mergCands[MRG_IVMC].setCand( tmpMV, ivCandDir[0], false, spiMvpFlag);
3344
3345      if ( mrgCandIdx == iCount )
3346      {
3347        return;
3348      }
3349      iCount ++;
3350    }
3351  } 
3352
3353  // early termination
3354  if (iCount == getSlice()->getMaxNumMergeCand()) 
3355  {
3356    return;
3357  }
3358
3359
3360  iCount += m_mergCands[MRG_A1].m_bAvailable + m_mergCands[MRG_B1].m_bAvailable;
3361
3362  /////////////////////////////////////////////////
3363  //////// VIEW SYNTHESIS PREDICTION (VSP) ////////
3364  /////////////////////////////////////////////////
3365  if (iCount<getSlice()->getMaxNumMergeCand())
3366  {
3367    if ( ( !getAvailableFlagA1() || !(pcCULeft->getVSPFlag(uiLeftPartIdx) != 0) ) &&
3368      !bICFlag           &&
3369      !bARPFlag          &&
3370      (nPSW + nPSH > 12) &&
3371      !bDBBPFlag         &&
3372      xAddVspCand( mrgCandIdx, &cDisInfo, iCount ) )
3373    {
3374      return;
3375    }
3376
3377    // early termination
3378    if (iCount == getSlice()->getMaxNumMergeCand())
3379    {
3380      return;
3381    }
3382  }
3383
3384  iCount += m_mergCands[MRG_B0].m_bAvailable;
3385
3386  /////////////////////////////////////////////
3387  //////// INTER VIEW DISP COMP (IvDC) ////////
3388  /////////////////////////////////////////////
3389  if( ivCandDir[1] && iCount < getSlice()->getMaxNumMergeCand() && !getSlice()->getIsDepth() )
3390  {
3391    assert(iCount < getSlice()->getMaxNumMergeCand());
3392
3393    tmpMV[0].setMvField( cZeroMv, NOT_VALID );
3394    tmpMV[1].setMvField( cZeroMv, NOT_VALID );
3395    if( ( ivCandDir[1] & 1 ) == 1 )
3396    {
3397      tmpMV[0].setMvField( ivCandMv[ 2 ], ivCandRefIdx[ 2 ] );
3398    }
3399    if( ( ivCandDir[1] & 2 ) == 2 )
3400    {
3401      tmpMV[1].setMvField( ivCandMv[ 3 ], ivCandRefIdx[ 3 ] );
3402    }
3403
3404    Bool bRemoveSpa = false; //pruning to A1, B1
3405    for(Int i = 0; i < 2; i ++)
3406    {
3407      if ( !m_mergCands[MRG_A1+i].m_bAvailable ) 
3408      {
3409        continue;
3410      }
3411      if ( hasEqualMotion(ivCandDir[1], tmpMV, m_mergCands[MRG_A1+i].m_uDir, m_mergCands[MRG_A1+i].m_cMvField) )
3412      {
3413        bRemoveSpa                      = true;
3414        break;
3415      }     
3416    }
3417    if(!bRemoveSpa)
3418    {
3419      tmpMV[0].getMv().setIDVFlag (false);
3420      tmpMV[1].getMv().setIDVFlag (false);
3421      m_mergCands[MRG_IVDC].setCand( tmpMV, ivCandDir[1], false, false);
3422
3423      if ( mrgCandIdx == iCount )
3424        return;
3425      iCount ++;
3426
3427      // early termination
3428      if (iCount == getSlice()->getMaxNumMergeCand()) 
3429      {
3430        return;
3431      }
3432    }
3433  } 
3434
3435
3436  iCount += m_mergCands[MRG_A0].m_bAvailable + m_mergCands[MRG_B2].m_bAvailable;
3437
3438  ////////////////////////////////////////////////////
3439  //////// SHIFTED IV (IvMCShift + IvDCShift) ////////
3440  ////////////////////////////////////////////////////
3441  if(  ivMvPredFlag && iCount < getSlice()->getMaxNumMergeCand() && !getSlice()->getIsDepth() ) 
3442  {
3443    if(xAddIvMRGCand( mrgCandIdx,  iCount, ivCandDir, ivCandMv, ivCandRefIdx ) )
3444    {
3445      return;
3446    }
3447    //early termination
3448    if (iCount == getSlice()->getMaxNumMergeCand()) 
3449    {
3450      return;
3451    }
3452  }
3453}
3454#endif
3455
3456//! Construct a list of merging candidates
3457
3458
3459#if MCTS_ENC_CHECK
3460Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, UInt &numSpatialMergeCandidates, Int mrgCandIdx ) 
3461#else
3462Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx )
3463#endif
3464#if !NH_3D 
3465  const
3466#endif
3467{
3468  UInt uiAbsPartAddr = m_absZIdxInCtu + uiAbsPartIdx;
3469#if NH_3D
3470  Bool abCandIsInter[ MRG_MAX_NUM_CANDS_MEM ];
3471#else
3472  Bool abCandIsInter[ MRG_MAX_NUM_CANDS ];
3473#endif
3474  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
3475  {
3476    abCandIsInter[ui] = false;
3477    pcMvFieldNeighbours[ ( ui << 1 )     ].setRefIdx(NOT_VALID);
3478    pcMvFieldNeighbours[ ( ui << 1 ) + 1 ].setRefIdx(NOT_VALID);
3479  }
3480  numValidMergeCand = getSlice()->getMaxNumMergeCand();
3481  // compute the location of the current PU
3482  Int xP, yP, nPSW, nPSH;
3483  this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
3484
3485  Int iCount = 0;
3486
3487  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
3488  PartSize cCurPS = getPartitionSize( uiAbsPartIdx );
3489  deriveLeftRightTopIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLT, uiPartIdxRT );
3490  deriveLeftBottomIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLB );
3491
3492  //left
3493  UInt uiLeftPartIdx = 0;
3494  const TComDataCU *pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB );
3495
3496  Bool isAvailableA1 = pcCULeft &&
3497                       pcCULeft->isDiffMER(xP -1, yP+nPSH-1, xP, yP) &&
3498                       !( uiPUIdx == 1 && (cCurPS == SIZE_Nx2N || cCurPS == SIZE_nLx2N || cCurPS == SIZE_nRx2N) ) &&
3499                       pcCULeft->isInter( uiLeftPartIdx ) ;
3500
3501  if ( isAvailableA1 )
3502  {
3503#if NH_3D
3504    m_bAvailableFlagA1 = 1;
3505#endif
3506    abCandIsInter[iCount] = true;
3507    // get Inter Dir
3508    puhInterDirNeighbours[iCount] = pcCULeft->getInterDir( uiLeftPartIdx );
3509    // get Mv from Left
3510    TComDataCU::getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3511    if ( getSlice()->isInterB() )
3512    {
3513      TComDataCU::getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3514    }
3515    if ( mrgCandIdx == iCount )
3516    {
3517#if MCTS_ENC_CHECK
3518      numSpatialMergeCandidates = iCount + 1;
3519#endif
3520      return;
3521    }
3522    iCount ++;
3523  }
3524
3525  // early termination
3526  if (iCount == getSlice()->getMaxNumMergeCand())
3527  {
3528#if MCTS_ENC_CHECK
3529    numSpatialMergeCandidates = iCount;
3530#endif
3531    return;
3532  }
3533  // above
3534  UInt uiAbovePartIdx = 0;
3535  const TComDataCU *pcCUAbove = getPUAbove( uiAbovePartIdx, uiPartIdxRT );
3536
3537  Bool isAvailableB1 = pcCUAbove &&
3538                       pcCUAbove->isDiffMER(xP+nPSW-1, yP-1, xP, yP) &&
3539                       !( uiPUIdx == 1 && (cCurPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD) ) &&
3540                       pcCUAbove->isInter( uiAbovePartIdx );
3541
3542  if ( isAvailableB1 && (!isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
3543  {
3544#if NH_3D
3545    m_bAvailableFlagB1 = 1;
3546#endif
3547    abCandIsInter[iCount] = true;
3548    // get Inter Dir
3549    puhInterDirNeighbours[iCount] = pcCUAbove->getInterDir( uiAbovePartIdx );
3550    // get Mv from Left
3551    TComDataCU::getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3552    if ( getSlice()->isInterB() )
3553    {
3554      TComDataCU::getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3555    }
3556    if ( mrgCandIdx == iCount )
3557    {
3558#if MCTS_ENC_CHECK
3559      numSpatialMergeCandidates = iCount + 1;
3560#endif
3561      return;
3562    }
3563    iCount ++;
3564  }
3565  // early termination
3566  if (iCount == getSlice()->getMaxNumMergeCand())
3567  {
3568#if MCTS_ENC_CHECK
3569    numSpatialMergeCandidates = iCount;
3570#endif
3571    return;
3572  }
3573
3574  // above right
3575  UInt uiAboveRightPartIdx = 0;
3576  const TComDataCU *pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT );
3577
3578  Bool isAvailableB0 = pcCUAboveRight &&
3579                       pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP) &&
3580                       pcCUAboveRight->isInter( uiAboveRightPartIdx );
3581
3582  if ( isAvailableB0 && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
3583  {
3584#if NH_3D
3585    m_bAvailableFlagB0 = 1;
3586#endif
3587    abCandIsInter[iCount] = true;
3588    // get Inter Dir
3589    puhInterDirNeighbours[iCount] = pcCUAboveRight->getInterDir( uiAboveRightPartIdx );
3590    // get Mv from Left
3591    TComDataCU::getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3592    if ( getSlice()->isInterB() )
3593    {
3594      TComDataCU::getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3595    }
3596    if ( mrgCandIdx == iCount )
3597    {
3598#if MCTS_ENC_CHECK
3599      numSpatialMergeCandidates = iCount + 1;
3600#endif
3601      return;
3602    }
3603    iCount ++;
3604  }
3605  // early termination
3606  if (iCount == getSlice()->getMaxNumMergeCand())
3607  {
3608#if MCTS_ENC_CHECK
3609    numSpatialMergeCandidates = iCount;
3610#endif
3611    return;
3612  }
3613
3614  //left bottom
3615  UInt uiLeftBottomPartIdx = 0;
3616  const TComDataCU *pcCULeftBottom = this->getPUBelowLeft( uiLeftBottomPartIdx, uiPartIdxLB );
3617
3618  Bool isAvailableA0 = pcCULeftBottom &&
3619                       pcCULeftBottom->isDiffMER(xP-1, yP+nPSH, xP, yP) &&
3620                       pcCULeftBottom->isInter( uiLeftBottomPartIdx ) ;
3621
3622  if ( isAvailableA0 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCULeftBottom, uiLeftBottomPartIdx ) ) )
3623  {
3624#if NH_3D
3625    m_bAvailableFlagA0 = 1;
3626#endif
3627    abCandIsInter[iCount] = true;
3628    // get Inter Dir
3629    puhInterDirNeighbours[iCount] = pcCULeftBottom->getInterDir( uiLeftBottomPartIdx );
3630    // get Mv from Left
3631    TComDataCU::getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3632    if ( getSlice()->isInterB() )
3633    {
3634      TComDataCU::getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3635    }
3636    if ( mrgCandIdx == iCount )
3637    {
3638#if MCTS_ENC_CHECK
3639      numSpatialMergeCandidates = iCount + 1;
3640#endif
3641      return;
3642    }
3643    iCount ++;
3644  }
3645  // early termination
3646  if (iCount == getSlice()->getMaxNumMergeCand())
3647  {
3648#if MCTS_ENC_CHECK
3649    numSpatialMergeCandidates = iCount;
3650#endif
3651    return;
3652  }
3653
3654  // above left
3655  if( iCount < 4 )
3656  {
3657    UInt uiAboveLeftPartIdx = 0;
3658    const TComDataCU *pcCUAboveLeft = getPUAboveLeft( uiAboveLeftPartIdx, uiAbsPartAddr );
3659
3660    Bool isAvailableB2 = pcCUAboveLeft &&
3661                         pcCUAboveLeft->isDiffMER(xP-1, yP-1, xP, yP) &&
3662                         pcCUAboveLeft->isInter( uiAboveLeftPartIdx );
3663
3664    if ( isAvailableB2 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) )
3665        && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) ) )
3666    {
3667#if NH_3D
3668      m_bAvailableFlagB2 = 1;
3669#endif
3670      abCandIsInter[iCount] = true;
3671      // get Inter Dir
3672      puhInterDirNeighbours[iCount] = pcCUAboveLeft->getInterDir( uiAboveLeftPartIdx );
3673      // get Mv from Left
3674      TComDataCU::getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3675      if ( getSlice()->isInterB() )
3676      {
3677        TComDataCU::getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3678      }
3679      if ( mrgCandIdx == iCount )
3680      {
3681#if MCTS_ENC_CHECK
3682        numSpatialMergeCandidates = iCount + 1;
3683#endif
3684        return;
3685      }
3686      iCount ++;
3687    }
3688  }
3689  // early termination
3690  if (iCount == getSlice()->getMaxNumMergeCand())
3691  {
3692#if MCTS_ENC_CHECK
3693    numSpatialMergeCandidates = iCount;
3694#endif
3695    return;
3696  }
3697
3698#if MCTS_ENC_CHECK
3699  numSpatialMergeCandidates = iCount;
3700#endif
3701  if ( getSlice()->getEnableTMVPFlag() )
3702  {
3703    //>> MTK colocated-RightBottom
3704    UInt uiPartIdxRB;
3705
3706    deriveRightBottomIdx( uiPUIdx, uiPartIdxRB );
3707
3708    UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
3709    const UInt numPartInCtuWidth  = m_pcPic->getNumPartInCtuWidth();
3710    const UInt numPartInCtuHeight = m_pcPic->getNumPartInCtuHeight();
3711
3712    TComMv cColMv;
3713    Int iRefIdx;
3714    Int ctuRsAddr = -1;
3715
3716    if (   ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth () ) < m_pcSlice->getSPS()->getPicWidthInLumaSamples () )  // image boundary check
3717        && ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() ) < m_pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
3718    {
3719      if ( ( uiAbsPartIdxTmp % numPartInCtuWidth < numPartInCtuWidth - 1 ) &&           // is not at the last column of CTU
3720        ( uiAbsPartIdxTmp / numPartInCtuWidth < numPartInCtuHeight - 1 ) )              // is not at the last row    of CTU
3721      {
3722        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + numPartInCtuWidth + 1 ];
3723        ctuRsAddr = getCtuRsAddr();
3724      }
3725      else if ( uiAbsPartIdxTmp % numPartInCtuWidth < numPartInCtuWidth - 1 )           // is not at the last column of CTU But is last row of CTU
3726      {
3727        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdxTmp + numPartInCtuWidth + 1) % m_pcPic->getNumPartitionsInCtu() ];
3728      }
3729      else if ( uiAbsPartIdxTmp / numPartInCtuWidth < numPartInCtuHeight - 1 )          // is not at the last row of CTU But is last column of CTU
3730      {
3731        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
3732        ctuRsAddr = getCtuRsAddr() + 1;
3733      }
3734      else //is the right bottom corner of CTU
3735      {
3736        uiAbsPartAddr = 0;
3737      }
3738    }
3739
3740    iRefIdx = 0;
3741
3742    Bool bExistMV = false;
3743    UInt uiPartIdxCenter;
3744    Int dir = 0;
3745    UInt uiArrayAddr = iCount;
3746    xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );
3747    bExistMV = ctuRsAddr >= 0 && xGetColMVP( REF_PIC_LIST_0, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx );
3748    if( bExistMV == false )
3749    {
3750      bExistMV = xGetColMVP( REF_PIC_LIST_0, getCtuRsAddr(), uiPartIdxCenter,  cColMv, iRefIdx );
3751    }
3752    if( bExistMV )
3753    {
3754      dir |= 1;
3755      pcMvFieldNeighbours[ 2 * uiArrayAddr ].setMvField( cColMv, iRefIdx );
3756    }
3757
3758    if ( getSlice()->isInterB() )
3759    {
3760#if NH_3D
3761      iRefIdx = 0;
3762#endif
3763      bExistMV = ctuRsAddr >= 0 && xGetColMVP( REF_PIC_LIST_1, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx);
3764      if( bExistMV == false )
3765      {
3766        bExistMV = xGetColMVP( REF_PIC_LIST_1, getCtuRsAddr(), uiPartIdxCenter, cColMv, iRefIdx );
3767      }
3768      if( bExistMV )
3769      {
3770        dir |= 2;
3771        pcMvFieldNeighbours[ 2 * uiArrayAddr + 1 ].setMvField( cColMv, iRefIdx );
3772      }
3773    }
3774
3775    if (dir != 0)
3776    {
3777      puhInterDirNeighbours[uiArrayAddr] = dir;
3778      abCandIsInter[uiArrayAddr] = true;
3779#if NH_3D
3780      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
3781      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
3782#endif
3783
3784      if ( mrgCandIdx == iCount )
3785      {
3786        return;
3787      }
3788      iCount++;
3789    }
3790  }
3791  // early termination
3792  if (iCount == getSlice()->getMaxNumMergeCand())
3793  {
3794    return;
3795  }
3796
3797  UInt uiArrayAddr = iCount;
3798  UInt uiCutoff = uiArrayAddr;
3799
3800#if NH_3D
3801  if ( getSlice()->isInterB() && iCount<5)
3802#else
3803  if ( getSlice()->isInterB() )
3804#endif
3805  {
3806    static const UInt NUM_PRIORITY_LIST=12;
3807    static const UInt uiPriorityList0[NUM_PRIORITY_LIST] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3};
3808    static const UInt uiPriorityList1[NUM_PRIORITY_LIST] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2};
3809
3810    for (Int idx=0; idx<uiCutoff*(uiCutoff-1) && uiArrayAddr!= getSlice()->getMaxNumMergeCand(); idx++)
3811    {
3812      assert(idx<NUM_PRIORITY_LIST);
3813      Int i = uiPriorityList0[idx];
3814      Int j = uiPriorityList1[idx];
3815      if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
3816      {
3817        abCandIsInter[uiArrayAddr] = true;
3818        puhInterDirNeighbours[uiArrayAddr] = 3;
3819
3820        // get Mv from cand[i] and cand[j]
3821        pcMvFieldNeighbours[uiArrayAddr << 1].setMvField(pcMvFieldNeighbours[i<<1].getMv(), pcMvFieldNeighbours[i<<1].getRefIdx());
3822        pcMvFieldNeighbours[( uiArrayAddr << 1 ) + 1].setMvField(pcMvFieldNeighbours[(j<<1)+1].getMv(), pcMvFieldNeighbours[(j<<1)+1].getRefIdx());
3823
3824        Int iRefPOCL0 = m_pcSlice->getRefPOC( REF_PIC_LIST_0, pcMvFieldNeighbours[(uiArrayAddr<<1)].getRefIdx() );
3825        Int iRefPOCL1 = m_pcSlice->getRefPOC( REF_PIC_LIST_1, pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getRefIdx() );
3826        if (iRefPOCL0 == iRefPOCL1 && pcMvFieldNeighbours[(uiArrayAddr<<1)].getMv() == pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getMv())
3827        {
3828          abCandIsInter[uiArrayAddr] = false;
3829        }
3830        else
3831        {
3832          uiArrayAddr++;
3833        }
3834      }
3835    }
3836  }
3837  // early termination
3838  if (uiArrayAddr == getSlice()->getMaxNumMergeCand())
3839  {
3840    return;
3841  }
3842
3843  Int iNumRefIdx = (getSlice()->isInterB()) ? min(m_pcSlice->getNumRefIdx(REF_PIC_LIST_0), m_pcSlice->getNumRefIdx(REF_PIC_LIST_1)) : m_pcSlice->getNumRefIdx(REF_PIC_LIST_0);
3844
3845  Int r = 0;
3846  Int refcnt = 0;
3847  while (uiArrayAddr < getSlice()->getMaxNumMergeCand())
3848  {
3849    abCandIsInter[uiArrayAddr] = true;
3850    puhInterDirNeighbours[uiArrayAddr] = 1;
3851    pcMvFieldNeighbours[uiArrayAddr << 1].setMvField( TComMv(0, 0), r);
3852
3853    if ( getSlice()->isInterB() )
3854    {
3855      puhInterDirNeighbours[uiArrayAddr] = 3;
3856      pcMvFieldNeighbours[(uiArrayAddr << 1) + 1].setMvField(TComMv(0, 0), r);
3857    }
3858    uiArrayAddr++;
3859
3860    if ( refcnt == iNumRefIdx - 1 )
3861    {
3862      r = 0;
3863    }
3864    else
3865    {
3866      ++r;
3867      ++refcnt;
3868    }
3869  }
3870  numValidMergeCand = uiArrayAddr;
3871}
3872
3873/** Check whether the current PU and a spatial neighboring PU are in a same ME region.
3874 * \param xN, yN   location of the upper-left corner pixel of a neighboring PU
3875 * \param xP, yP   location of the upper-left corner pixel of the current PU
3876 */
3877Bool TComDataCU::isDiffMER(Int xN, Int yN, Int xP, Int yP) const
3878{
3879
3880  UInt plevel = this->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() + 2;
3881  if ((xN>>plevel)!= (xP>>plevel))
3882  {
3883    return true;
3884  }
3885  if ((yN>>plevel)!= (yP>>plevel))
3886  {
3887    return true;
3888  }
3889  return false;
3890}
3891
3892/** Calculate the location of upper-left corner pixel and size of the current PU.
3893 * \param partIdx       PU index within a CU
3894 * \param xP, yP        location of the upper-left corner pixel of the current PU
3895 * \param nPSW, nPSH    size of the current PU
3896 */
3897Void TComDataCU::getPartPosition( UInt partIdx, Int& xP, Int& yP, Int& nPSW, Int& nPSH) const
3898{
3899  UInt col = m_uiCUPelX;
3900  UInt row = m_uiCUPelY;
3901
3902  switch ( m_pePartSize[0] )
3903  {
3904  case SIZE_2NxN:
3905    nPSW = getWidth(0);
3906    nPSH = getHeight(0) >> 1;
3907    xP   = col;
3908    yP   = (partIdx ==0)? row: row + nPSH;
3909    break;
3910  case SIZE_Nx2N:
3911    nPSW = getWidth(0) >> 1;
3912    nPSH = getHeight(0);
3913    xP   = (partIdx ==0)? col: col + nPSW;
3914    yP   = row;
3915    break;
3916  case SIZE_NxN:
3917    nPSW = getWidth(0) >> 1;
3918    nPSH = getHeight(0) >> 1;
3919    xP   = col + (partIdx&0x1)*nPSW;
3920    yP   = row + (partIdx>>1)*nPSH;
3921    break;
3922  case SIZE_2NxnU:
3923    nPSW = getWidth(0);
3924    nPSH = ( partIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
3925    xP   = col;
3926    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
3927
3928    break;
3929  case SIZE_2NxnD:
3930    nPSW = getWidth(0);
3931    nPSH = ( partIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
3932    xP   = col;
3933    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
3934    break;
3935  case SIZE_nLx2N:
3936    nPSW = ( partIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
3937    nPSH = getHeight(0);
3938    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
3939    yP   = row;
3940    break;
3941  case SIZE_nRx2N:
3942    nPSW = ( partIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
3943    nPSH = getHeight(0);
3944    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
3945    yP   = row;
3946    break;
3947  default:
3948    assert ( m_pePartSize[0] == SIZE_2Nx2N );
3949    nPSW = getWidth(0);
3950    nPSH = getHeight(0);
3951    xP   = col ;
3952    yP   = row ;
3953
3954    break;
3955  }
3956}
3957
3958/** Constructs a list of candidates for AMVP (See specification, section "Derivation process for motion vector predictor candidates")
3959 * \param uiPartIdx
3960 * \param uiPartAddr
3961 * \param eRefPicList
3962 * \param iRefIdx
3963 * \param pInfo
3964 */
3965Void TComDataCU::fillMvpCand ( const UInt partIdx, const UInt partAddr, const RefPicList eRefPicList, const Int refIdx, AMVPInfo* pInfo ) const
3966{
3967  pInfo->iN = 0;
3968  if (refIdx < 0)
3969  {
3970#if MCTS_ENC_CHECK
3971    pInfo->numSpatialMVPCandidates = 0;
3972#endif
3973    return;
3974  }
3975
3976  //-- Get Spatial MV
3977  UInt partIdxLT, partIdxRT, partIdxLB;
3978  deriveLeftRightTopIdx( partIdx, partIdxLT, partIdxRT );
3979  deriveLeftBottomIdx( partIdx, partIdxLB );
3980
3981  Bool isScaledFlagLX = false; /// variable name from specification; true when the PUs below left or left are available (availableA0 || availableA1).
3982  {
3983    UInt idx;
3984    const TComDataCU* tmpCU = getPUBelowLeft(idx, partIdxLB);
3985    isScaledFlagLX = (tmpCU != NULL) && (tmpCU->isInter(idx));
3986    if (!isScaledFlagLX)
3987    {
3988      tmpCU = getPULeft(idx, partIdxLB);
3989      isScaledFlagLX = (tmpCU != NULL) && (tmpCU->isInter(idx));
3990    }
3991  }
3992
3993  // Left predictor search
3994  if (isScaledFlagLX)
3995  {
3996    Bool bAdded = xAddMVPCandUnscaled( *pInfo, eRefPicList, refIdx, partIdxLB, MD_BELOW_LEFT);
3997    if (!bAdded)
3998    {
3999      bAdded = xAddMVPCandUnscaled( *pInfo, eRefPicList, refIdx, partIdxLB, MD_LEFT );
4000      if(!bAdded)
4001      {
4002        bAdded = xAddMVPCandWithScaling( *pInfo, eRefPicList, refIdx, partIdxLB, MD_BELOW_LEFT);
4003        if (!bAdded)
4004        {
4005          xAddMVPCandWithScaling( *pInfo, eRefPicList, refIdx, partIdxLB, MD_LEFT );
4006        }
4007      }
4008    }
4009  }
4010
4011  // Above predictor search
4012  {
4013    Bool bAdded = xAddMVPCandUnscaled( *pInfo, eRefPicList, refIdx, partIdxRT, MD_ABOVE_RIGHT);
4014    if (!bAdded)
4015    {
4016      bAdded = xAddMVPCandUnscaled( *pInfo, eRefPicList, refIdx, partIdxRT, MD_ABOVE);
4017      if(!bAdded)
4018      {
4019        xAddMVPCandUnscaled( *pInfo, eRefPicList, refIdx, partIdxLT, MD_ABOVE_LEFT);
4020      }
4021    }
4022  }
4023
4024  if(!isScaledFlagLX)
4025  {
4026    Bool bAdded = xAddMVPCandWithScaling( *pInfo, eRefPicList, refIdx, partIdxRT, MD_ABOVE_RIGHT);
4027    if (!bAdded)
4028    {
4029      bAdded = xAddMVPCandWithScaling( *pInfo, eRefPicList, refIdx, partIdxRT, MD_ABOVE);
4030      if(!bAdded)
4031      {
4032        xAddMVPCandWithScaling( *pInfo, eRefPicList, refIdx, partIdxLT, MD_ABOVE_LEFT);
4033      }
4034    }
4035  }
4036
4037  if ( pInfo->iN == 2 )
4038  {
4039    if ( pInfo->m_acMvCand[ 0 ] == pInfo->m_acMvCand[ 1 ] )
4040    {
4041      pInfo->iN = 1;
4042    }
4043  }
4044
4045#if MCTS_ENC_CHECK
4046  pInfo->numSpatialMVPCandidates = pInfo->iN;
4047#endif
4048  if (pInfo->iN < AMVP_MAX_NUM_CANDS && getSlice()->getEnableTMVPFlag() )
4049  {
4050    // Get Temporal Motion Predictor
4051    const UInt numPartInCtuWidth  = m_pcPic->getNumPartInCtuWidth();
4052    const UInt numPartInCtuHeight = m_pcPic->getNumPartInCtuHeight();
4053#if NH_3D
4054    Int refIdx_Col = refIdx;
4055#else
4056    const Int refIdx_Col = refIdx;
4057#endif
4058    TComMv cColMv;
4059    UInt partIdxRB;
4060    UInt absPartIdx;
4061
4062    deriveRightBottomIdx( partIdx, partIdxRB );
4063    UInt absPartAddr = m_absZIdxInCtu + partAddr;
4064
4065    //----  co-located RightBottom Temporal Predictor (H) ---//
4066    absPartIdx = g_auiZscanToRaster[partIdxRB];
4067    Int ctuRsAddr = -1;
4068    if (  ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[absPartIdx] + m_pcPic->getMinCUWidth () ) < m_pcSlice->getSPS()->getPicWidthInLumaSamples () )  // image boundary check
4069      && ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[absPartIdx] + m_pcPic->getMinCUHeight() ) < m_pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
4070    {
4071      if ( ( absPartIdx % numPartInCtuWidth < numPartInCtuWidth - 1 ) &&  // is not at the last column of CTU
4072        ( absPartIdx / numPartInCtuWidth < numPartInCtuHeight - 1 ) )  // is not at the last row    of CTU
4073      {
4074        absPartAddr = g_auiRasterToZscan[ absPartIdx + numPartInCtuWidth + 1 ];
4075        ctuRsAddr = getCtuRsAddr();
4076      }
4077      else if ( absPartIdx % numPartInCtuWidth < numPartInCtuWidth - 1 )  // is not at the last column of CTU But is last row of CTU
4078      {
4079        absPartAddr = g_auiRasterToZscan[ (absPartIdx + numPartInCtuWidth + 1) % m_pcPic->getNumPartitionsInCtu() ];
4080      }
4081      else if ( absPartIdx / numPartInCtuWidth < numPartInCtuHeight - 1 ) // is not at the last row of CTU But is last column of CTU
4082      {
4083        absPartAddr = g_auiRasterToZscan[ absPartIdx + 1 ];
4084        ctuRsAddr = getCtuRsAddr() + 1;
4085      }
4086      else //is the right bottom corner of CTU
4087      {
4088        absPartAddr = 0;
4089      }
4090    }
4091#if NH_3D
4092        if ( ctuRsAddr >= 0 && xGetColMVP( eRefPicList, ctuRsAddr, absPartAddr, cColMv, refIdx_Col  , 0 ) )
4093#else
4094    if ( ctuRsAddr >= 0 && xGetColMVP( eRefPicList, ctuRsAddr, absPartAddr, cColMv, refIdx_Col ) )
4095#endif
4096    {
4097      pInfo->m_acMvCand[pInfo->iN++] = cColMv;
4098    }
4099    else
4100    {
4101      UInt uiPartIdxCenter;
4102      xDeriveCenterIdx( partIdx, uiPartIdxCenter );
4103#if NH_3D
4104      if (xGetColMVP( eRefPicList, getCtuRsAddr(), uiPartIdxCenter,  cColMv, refIdx_Col , 0 )) 
4105#else
4106      if (xGetColMVP( eRefPicList, getCtuRsAddr(), uiPartIdxCenter,  cColMv, refIdx_Col ))
4107#endif
4108      {
4109        pInfo->m_acMvCand[pInfo->iN++] = cColMv;
4110      }
4111    }
4112    //----  co-located RightBottom Temporal Predictor  ---//
4113  }
4114
4115  while (pInfo->iN < AMVP_MAX_NUM_CANDS)
4116  {
4117    pInfo->m_acMvCand[pInfo->iN].set(0,0);
4118    pInfo->iN++;
4119  }
4120  return ;
4121}
4122
4123
4124Bool TComDataCU::isBipredRestriction(UInt puIdx) const
4125{
4126  Int width = 0;
4127  Int height = 0;
4128  UInt partAddr;
4129
4130#if NH_3D
4131  if( getDBBPFlag(0) )
4132  {
4133    return true;
4134  }
4135#endif
4136
4137  getPartIndexAndSize( puIdx, partAddr, width, height );
4138  if ( getWidth(0) == 8 && (width < 8 || height < 8) )
4139  {
4140    return true;
4141  }
4142  return false;
4143}
4144
4145
4146Void TComDataCU::clipMv    (TComMv&  rcMv) const
4147{
4148  const TComSPS &sps=*(m_pcSlice->getSPS());
4149  Int  iMvShift = 2;
4150#if NH_3D
4151  if( getSlice()->getIsDepth() )
4152    iMvShift = 0;
4153#endif
4154
4155  Int iOffset = 8;
4156  Int iHorMax = ( sps.getPicWidthInLumaSamples() + iOffset - (Int)m_uiCUPelX - 1 ) << iMvShift;
4157  Int iHorMin = (      -(Int)sps.getMaxCUWidth() - iOffset - (Int)m_uiCUPelX + 1 ) << iMvShift;
4158
4159  Int iVerMax = ( sps.getPicHeightInLumaSamples() + iOffset - (Int)m_uiCUPelY - 1 ) << iMvShift;
4160  Int iVerMin = (      -(Int)sps.getMaxCUHeight() - iOffset - (Int)m_uiCUPelY + 1 ) << iMvShift;
4161
4162  rcMv.setHor( min (iHorMax, max (iHorMin, rcMv.getHor())) );
4163  rcMv.setVer( min (iVerMax, max (iVerMin, rcMv.getVer())) );
4164}
4165
4166#if NH_MV
4167Void TComDataCU::checkMvVertRest (TComMv&  rcMv,  RefPicList eRefPicList, int iRefIdx )
4168{
4169  if ( getSlice()->getSPS()->getInterViewMvVertConstraintFlag() )
4170  {
4171    if ( getSlice()->getRefPic( eRefPicList, iRefIdx )->getPOC() == getSlice()->getPOC() )
4172    {
4173        //When inter_view_mv_vert_constraint_flag is equal to 1,
4174        //the vertical component of the motion vectors used for inter-layer prediction
4175        //shall be equal to or less than 56 in units of luma samples
4176        assert ( rcMv.getVer() <= (56<<2) );
4177    }
4178  }
4179}
4180#endif
4181
4182UInt TComDataCU::getIntraSizeIdx(UInt uiAbsPartIdx) const
4183{
4184  UInt uiShift = ( m_pePartSize[uiAbsPartIdx]==SIZE_NxN ? 1 : 0 );
4185
4186  UChar uiWidth = m_puhWidth[uiAbsPartIdx]>>uiShift;
4187  UInt  uiCnt = 0;
4188  while( uiWidth )
4189  {
4190    uiCnt++;
4191    uiWidth>>=1;
4192  }
4193  uiCnt-=2;
4194  return uiCnt > 6 ? 6 : uiCnt;
4195}
4196
4197Void TComDataCU::clearCbf( UInt uiIdx, ComponentID compID, UInt uiNumParts )
4198{
4199  memset( &m_puhCbf[compID][uiIdx], 0, sizeof(UChar)*uiNumParts);
4200}
4201
4202/** Set a I_PCM flag for all sub-partitions of a partition.
4203 * \param bIpcmFlag I_PCM flag
4204 * \param uiAbsPartIdx patition index
4205 * \param uiDepth CU depth
4206 * \returns Void
4207 */
4208Void TComDataCU::setIPCMFlagSubParts  (Bool bIpcmFlag, UInt uiAbsPartIdx, UInt uiDepth)
4209{
4210  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
4211
4212  memset(m_pbIPCMFlag + uiAbsPartIdx, bIpcmFlag, sizeof(Bool)*uiCurrPartNumb );
4213}
4214
4215/** Test whether the block at uiPartIdx is skipped.
4216 * \param uiPartIdx Partition index
4217 * \returns true if the current the block is skipped
4218 */
4219Bool TComDataCU::isSkipped( UInt uiPartIdx ) const
4220{
4221  return ( getSkipFlag( uiPartIdx ) );
4222}
4223
4224// ====================================================================================================================
4225// Protected member functions
4226// ====================================================================================================================
4227
4228Bool TComDataCU::xAddMVPCandUnscaled( AMVPInfo &info, const RefPicList eRefPicList, const Int iRefIdx, const UInt uiPartUnitIdx, const MVP_DIR eDir ) const
4229{
4230  const TComDataCU* neibCU = NULL;
4231  UInt neibPUPartIdx;
4232  switch( eDir )
4233  {
4234    case MD_LEFT:
4235    {
4236      neibCU = getPULeft(neibPUPartIdx, uiPartUnitIdx);
4237      break;
4238    }
4239    case MD_ABOVE:
4240    {
4241      neibCU = getPUAbove(neibPUPartIdx, uiPartUnitIdx);
4242      break;
4243    }
4244    case MD_ABOVE_RIGHT:
4245    {
4246      neibCU = getPUAboveRight(neibPUPartIdx, uiPartUnitIdx);
4247      break;
4248    }
4249    case MD_BELOW_LEFT:
4250    {
4251      neibCU = getPUBelowLeft(neibPUPartIdx, uiPartUnitIdx);
4252      break;
4253    }
4254    case MD_ABOVE_LEFT:
4255    {
4256      neibCU = getPUAboveLeft(neibPUPartIdx, uiPartUnitIdx);
4257      break;
4258    }
4259    default:
4260    {
4261      break;
4262    }
4263  }
4264
4265  if ( neibCU == NULL )
4266  {
4267    return false;
4268  }
4269
4270  const Int        currRefPOC     = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
4271  const RefPicList eRefPicList2nd = (eRefPicList == REF_PIC_LIST_0) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
4272
4273  for(Int predictorSource=0; predictorSource<2; predictorSource++) // examine the indicated reference picture list, then if not available, examine the other list.
4274  {
4275    const RefPicList eRefPicListIndex = (predictorSource==0) ? eRefPicList : eRefPicList2nd;
4276    const Int        neibRefIdx       = neibCU->getCUMvField(eRefPicListIndex)->getRefIdx(neibPUPartIdx);
4277
4278    if ( neibRefIdx >= 0 && currRefPOC == neibCU->getSlice()->getRefPOC( eRefPicListIndex, neibRefIdx ))
4279    {
4280      info.m_acMvCand[info.iN++] = neibCU->getCUMvField(eRefPicListIndex)->getMv(neibPUPartIdx);
4281      return true;
4282    }
4283  }
4284  return false;
4285}
4286
4287/**
4288 * \param pInfo
4289 * \param eRefPicList
4290 * \param iRefIdx
4291 * \param uiPartUnitIdx
4292 * \param eDir
4293 * \returns Bool
4294 */
4295Bool TComDataCU::xAddMVPCandWithScaling( AMVPInfo &info, const RefPicList eRefPicList, const Int iRefIdx, const UInt uiPartUnitIdx, const MVP_DIR eDir ) const
4296{
4297  const TComDataCU* neibCU = NULL;
4298  UInt neibPUPartIdx;
4299  switch( eDir )
4300  {
4301  case MD_LEFT:
4302    {
4303      neibCU = getPULeft(neibPUPartIdx, uiPartUnitIdx);
4304      break;
4305    }
4306  case MD_ABOVE:
4307    {
4308      neibCU = getPUAbove(neibPUPartIdx, uiPartUnitIdx);
4309      break;
4310    }
4311  case MD_ABOVE_RIGHT:
4312    {
4313      neibCU = getPUAboveRight(neibPUPartIdx, uiPartUnitIdx);
4314      break;
4315    }
4316  case MD_BELOW_LEFT:
4317    {
4318      neibCU = getPUBelowLeft(neibPUPartIdx, uiPartUnitIdx);
4319      break;
4320    }
4321  case MD_ABOVE_LEFT:
4322    {
4323      neibCU = getPUAboveLeft(neibPUPartIdx, uiPartUnitIdx);
4324      break;
4325    }
4326  default:
4327    {
4328      break;
4329    }
4330  }
4331
4332  if ( neibCU == NULL )
4333  {
4334    return false;
4335  }
4336
4337  const RefPicList eRefPicList2nd = (eRefPicList == REF_PIC_LIST_0) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
4338
4339  const Int  currPOC            = m_pcSlice->getPOC();
4340  const Int  currRefPOC         = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
4341  const Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getIsLongTerm();
4342  const Int  neibPOC            = currPOC;
4343
4344  for(Int predictorSource=0; predictorSource<2; predictorSource++) // examine the indicated reference picture list, then if not available, examine the other list.
4345  {
4346    const RefPicList eRefPicListIndex = (predictorSource==0) ? eRefPicList : eRefPicList2nd;
4347    const Int        neibRefIdx       = neibCU->getCUMvField(eRefPicListIndex)->getRefIdx(neibPUPartIdx);
4348    if( neibRefIdx >= 0)
4349    {
4350      const Bool bIsNeibRefLongTerm = neibCU->getSlice()->getRefPic( eRefPicListIndex, neibRefIdx )->getIsLongTerm();
4351
4352      if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm )
4353      {
4354        const TComMv &cMvPred = neibCU->getCUMvField(eRefPicListIndex)->getMv(neibPUPartIdx);
4355        TComMv rcMv;
4356        if ( bIsCurrRefLongTerm /* || bIsNeibRefLongTerm*/ )
4357        {
4358          rcMv = cMvPred;
4359        }
4360        else
4361        {
4362          const Int neibRefPOC = neibCU->getSlice()->getRefPOC( eRefPicListIndex, neibRefIdx );
4363          const Int scale      = xGetDistScaleFactor( currPOC, currRefPOC, neibPOC, neibRefPOC );
4364          if ( scale == 4096 )
4365          {
4366            rcMv = cMvPred;
4367          }
4368          else
4369          {
4370            rcMv = cMvPred.scaleMv( scale );
4371          }
4372        }
4373
4374        info.m_acMvCand[info.iN++] = rcMv;
4375        return true;
4376      }
4377    }
4378  }
4379  return false;
4380}
4381
4382#if NH_3D
4383Bool TComDataCU::xGetColMVP( const RefPicList eRefPicList, const Int ctuRsAddr, const Int partUnitIdx, TComMv& rcMv, Int& refIdx, Bool bMRG  ) const
4384#else
4385Bool TComDataCU::xGetColMVP( const RefPicList eRefPicList, const Int ctuRsAddr, const Int partUnitIdx, TComMv& rcMv, const Int refIdx ) const
4386#endif
4387{
4388  const UInt absPartAddr = partUnitIdx;
4389
4390  // use coldir.
4391  const TComPic    * const pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());
4392#if REDUCED_ENCODER_MEMORY
4393  if (!pColPic->getPicSym()->hasDPBPerCtuData())
4394  {
4395    return false;
4396  }
4397  const TComPicSym::DPBPerCtuData * const pColDpbCtu = &(pColPic->getPicSym()->getDPBPerCtuData(ctuRsAddr));
4398  const TComSlice * const pColSlice = pColDpbCtu->getSlice();
4399  if(pColDpbCtu->getPartitionSize(partUnitIdx)==NUMBER_OF_PART_SIZES)
4400#else
4401  const TComDataCU * const pColCtu = pColPic->getCtu( ctuRsAddr );
4402  if(pColCtu->getPic()==0 || pColCtu->getPartitionSize(partUnitIdx)==NUMBER_OF_PART_SIZES)
4403#endif
4404  {
4405    return false;
4406  }
4407
4408#if REDUCED_ENCODER_MEMORY
4409  if (!pColDpbCtu->isInter(absPartAddr))
4410#else
4411  if (!pColCtu->isInter(absPartAddr))
4412#endif
4413  {
4414    return false;
4415  }
4416
4417  RefPicList eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());
4418#if REDUCED_ENCODER_MEMORY
4419  Int iColRefIdx            = pColDpbCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
4420#else
4421  Int iColRefIdx            = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
4422#endif
4423
4424  if (iColRefIdx < 0 )
4425  {
4426    eColRefPicList = RefPicList(1 - eColRefPicList);
4427#if REDUCED_ENCODER_MEMORY
4428    iColRefIdx = pColDpbCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
4429#else
4430    iColRefIdx = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(absPartAddr);
4431#endif
4432
4433    if (iColRefIdx < 0 )
4434    {
4435      return false;
4436    }
4437  }
4438
4439#if NH_3D
4440  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, refIdx)->getIsLongTerm();
4441#else
4442  const Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, refIdx)->getIsLongTerm();
4443#endif
4444#if REDUCED_ENCODER_MEMORY
4445  const Bool bIsColRefLongTerm  = pColSlice->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
4446#else
4447  const Bool bIsColRefLongTerm  = pColCtu->getSlice()->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
4448#endif
4449  if ( bIsCurrRefLongTerm != bIsColRefLongTerm )
4450  {
4451#if NH_3D
4452    Int iAlterRefIdx  = m_pcSlice->getAlterRefIdx(eRefPicList);
4453    if(bMRG && iAlterRefIdx > 0)
4454    {
4455      refIdx = iAlterRefIdx;
4456      bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, refIdx)->getIsLongTerm();
4457      assert(bIsCurrRefLongTerm == bIsColRefLongTerm);
4458    }
4459    else
4460    {
4461#endif
4462      return false;
4463#if NH_3D
4464    }
4465#endif
4466  }
4467  // Scale the vector.
4468#if REDUCED_ENCODER_MEMORY
4469  const TComMv &cColMv = pColDpbCtu->getCUMvField(eColRefPicList)->getMv(absPartAddr);
4470#else
4471  const TComMv &cColMv = pColCtu->getCUMvField(eColRefPicList)->getMv(absPartAddr);
4472#endif
4473
4474#if NH_3D
4475  if ( bIsCurrRefLongTerm || bIsColRefLongTerm )
4476#else
4477  if ( bIsCurrRefLongTerm /*|| bIsColRefLongTerm*/ )
4478#endif
4479  {
4480#if NH_3D
4481    const Int iCurrViewId    = m_pcSlice->getViewId (); 
4482    const Int iCurrRefViewId = m_pcSlice->getRefPic(eRefPicList, refIdx)->getViewId (); 
4483    const Int iColViewId     = pColCtu->getSlice()->getViewId(); 
4484    const Int iColRefViewId  = pColCtu->getSlice()->getRefPic( eColRefPicList, pColCtu->getCUMvField(eColRefPicList)->getRefIdx(absPartAddr))->getViewId(); 
4485    Int scale = 4096;
4486    if ( iCurrRefViewId != iCurrViewId && iColViewId != iColRefViewId )
4487    {
4488      scale = xGetDistScaleFactor( iCurrViewId, iCurrRefViewId, iColViewId, iColRefViewId );
4489    }
4490    if ( bMRG && scale != 4096 && m_pcSlice->getIvMvScalingFlag( ) ) 
4491    {
4492      rcMv = cColMv.scaleMv( scale );
4493    }
4494    else
4495    {
4496#endif
4497      rcMv = cColMv;
4498#if NH_3D
4499    }
4500#endif
4501  }
4502  else
4503  {
4504    const Int currPOC    = m_pcSlice->getPOC();
4505#if REDUCED_ENCODER_MEMORY
4506    const Int colPOC     = pColSlice->getPOC();
4507    const Int colRefPOC  = pColSlice->getRefPOC(eColRefPicList, iColRefIdx);
4508#else
4509    const Int colPOC     = pColCtu->getSlice()->getPOC();
4510    const Int colRefPOC  = pColCtu->getSlice()->getRefPOC(eColRefPicList, iColRefIdx);
4511#endif
4512    const Int currRefPOC = m_pcSlice->getRefPic(eRefPicList, refIdx)->getPOC();
4513    const Int scale      = xGetDistScaleFactor(currPOC, currRefPOC, colPOC, colRefPOC);
4514    if ( scale == 4096 )
4515    {
4516      rcMv = cColMv;
4517    }
4518    else
4519    {
4520      rcMv = cColMv.scaleMv( scale );
4521    }
4522  }
4523
4524  return true;
4525}
4526
4527// Static member
4528Int TComDataCU::xGetDistScaleFactor(Int iCurrPOC, Int iCurrRefPOC, Int iColPOC, Int iColRefPOC)
4529{
4530  Int iDiffPocD = iColPOC - iColRefPOC;
4531  Int iDiffPocB = iCurrPOC - iCurrRefPOC;
4532
4533  if( iDiffPocD == iDiffPocB )
4534  {
4535    return 4096;
4536  }
4537  else
4538  {
4539    Int iTDB      = Clip3( -128, 127, iDiffPocB );
4540    Int iTDD      = Clip3( -128, 127, iDiffPocD );
4541    Int iX        = (0x4000 + abs(iTDD/2)) / iTDD;
4542    Int iScale    = Clip3( -4096, 4095, (iTDB * iX + 32) >> 6 );
4543    return iScale;
4544  }
4545}
4546
4547Void TComDataCU::xDeriveCenterIdx( UInt uiPartIdx, UInt& ruiPartIdxCenter ) const
4548{
4549  UInt uiPartAddr;
4550  Int  iPartWidth;
4551  Int  iPartHeight;
4552  getPartIndexAndSize( uiPartIdx, uiPartAddr, iPartWidth, iPartHeight);
4553
4554  ruiPartIdxCenter = m_absZIdxInCtu+uiPartAddr; // partition origin.
4555  ruiPartIdxCenter = g_auiRasterToZscan[ g_auiZscanToRaster[ ruiPartIdxCenter ]
4556                                        + ( iPartHeight/m_pcPic->getMinCUHeight()  )/2*m_pcPic->getNumPartInCtuWidth()
4557                                        + ( iPartWidth/m_pcPic->getMinCUWidth()  )/2];
4558}
4559
4560#if NH_3D
4561Void TComDataCU::compressMV(Int scale)
4562{
4563   Int scaleFactor = (4 / scale ) * AMVP_DECIMATION_FACTOR / m_unitSize;
4564  if (scaleFactor > 0)
4565  {
4566    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
4567    {
4568      m_acCUMvField[i].compress(m_pePredMode, scaleFactor);
4569    }
4570  }
4571#else
4572Void TComDataCU::compressMV()
4573{
4574#if REDUCED_ENCODER_MEMORY
4575  const Int scaleFactor = std::max<Int>(1,4 * AMVP_DECIMATION_FACTOR / m_unitSize);
4576  TComPicSym &picSym=*(getPic()->getPicSym());
4577  TComPicSym::DPBPerCtuData &dpbForCtu=picSym.getDPBPerCtuData(getCtuRsAddr());
4578
4579  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
4580  {
4581    dpbForCtu.m_CUMvField[i].compress(dpbForCtu.m_pePredMode, m_pePredMode, scaleFactor,m_acCUMvField[i]);
4582    memcpy(dpbForCtu.m_pePartSize, m_pePartSize, sizeof(*m_pePartSize)*m_uiNumPartition);
4583    dpbForCtu.m_pSlice = getSlice();
4584  }
4585#else
4586  Int scaleFactor = 4 * AMVP_DECIMATION_FACTOR / m_unitSize;
4587  if (scaleFactor > 0)
4588  {
4589    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
4590    {
4591      m_acCUMvField[i].compress(m_pePredMode, scaleFactor);
4592    }
4593  }
4594#endif
4595#endif
4596}
4597#if NH_3D
4598Void TComDataCU::printMV( )
4599{ 
4600
4601  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
4602  {
4603    std::cout << "L" << i; 
4604    m_acCUMvField[i].print(m_pePredMode);
4605  }
4606
4607}
4608#endif
4609
4610UInt TComDataCU::getCoefScanIdx(const UInt uiAbsPartIdx, const UInt uiWidth, const UInt uiHeight, const ComponentID compID) const
4611{
4612  //------------------------------------------------
4613
4614  //this mechanism is available for intra only
4615
4616  if (!isIntra(uiAbsPartIdx))
4617  {
4618    return SCAN_DIAG;
4619  }
4620
4621  //------------------------------------------------
4622
4623  //check that MDCS can be used for this TU
4624
4625  const ChromaFormat format = getPic()->getChromaFormat();
4626
4627  const UInt maximumWidth  = MDCS_MAXIMUM_WIDTH  >> getComponentScaleX(compID, format);
4628  const UInt maximumHeight = MDCS_MAXIMUM_HEIGHT >> getComponentScaleY(compID, format);
4629
4630  if ((uiWidth > maximumWidth) || (uiHeight > maximumHeight))
4631  {
4632    return SCAN_DIAG;
4633  }
4634
4635  //------------------------------------------------
4636
4637  //otherwise, select the appropriate mode
4638
4639  UInt uiDirMode  = getIntraDir(toChannelType(compID), uiAbsPartIdx);
4640#if NH_3D
4641  mapDmmToIntraDir( uiDirMode );
4642#endif
4643
4644  if (uiDirMode==DM_CHROMA_IDX)
4645  {
4646    const TComSPS *sps=getSlice()->getSPS();
4647    const UInt partsPerMinCU = 1<<(2*(sps->getMaxTotalCUDepth() - sps->getLog2DiffMaxMinCodingBlockSize()));
4648    uiDirMode = getIntraDir(CHANNEL_TYPE_LUMA, getChromasCorrespondingPULumaIdx(uiAbsPartIdx, getPic()->getChromaFormat(), partsPerMinCU));
4649#if NH_3D
4650    mapDmmToIntraDir( uiDirMode );
4651#endif
4652  }
4653
4654  if (isChroma(compID) && (format == CHROMA_422))
4655  {
4656    uiDirMode = g_chroma422IntraAngleMappingTable[uiDirMode];
4657  }
4658
4659  //------------------
4660
4661  if      (abs((Int)uiDirMode - VER_IDX) <= MDCS_ANGLE_LIMIT)
4662  {
4663    return SCAN_HOR;
4664  }
4665  else if (abs((Int)uiDirMode - HOR_IDX) <= MDCS_ANGLE_LIMIT)
4666  {
4667    return SCAN_VER;
4668  }
4669  else
4670  {
4671    return SCAN_DIAG;
4672  }
4673}
4674
4675#if MCTS_ENC_CHECK
4676Bool TComDataCU::isLastColumnCTUInTile() const
4677{
4678  UInt      currentTileIdx               = this->getPic()->getPicSym()->getTileIdxMap(this->getCtuRsAddr());
4679  TComTile *pCurrentTile                 = m_pcPic->getPicSym()->getTComTile(currentTileIdx);
4680  UInt      frameWidthInCtus             = m_pcPic->getPicSym()->getFrameWidthInCtus();
4681  UInt      rightEdgeCTUPosInCurrentTile = pCurrentTile->getRightEdgePosInCtus();
4682  UInt      ctuXPosInCtus                = this->getCtuRsAddr() % frameWidthInCtus;
4683 
4684  return (rightEdgeCTUPosInCurrentTile == ctuXPosInCtus);
4685}
4686#endif
4687
4688#if NH_3D_VSO
4689Void TComDataCU::getPosInPic( UInt uiAbsPartIndex, Int& riPosX, Int& riPosY ) const
4690{
4691  riPosX = g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelX();
4692  riPosY = g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelY(); 
4693}
4694#endif
4695
4696#if NH_3D
4697Void TComDataCU::getDispforDepth (UInt uiPartIdx, UInt uiPartAddr, DisInfo* pDisp)
4698{
4699  assert(getPartitionSize( uiPartAddr ) == SIZE_2Nx2N);
4700
4701  TComMv cMv; 
4702  if ( getSlice()->getDefaultRefViewIdxAvailableFlag() )
4703  {
4704    Int iViewIdx = getSlice()->getDefaultRefViewIdx();
4705    pDisp->m_aVIdxCan = iViewIdx;
4706    Int iDisp     = getSlice()->getDepthToDisparityB( iViewIdx )[ (Int64) (1 << ( getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 1 )) ];
4707
4708    cMv.setHor(iDisp);
4709    cMv.setVer(0);
4710    pDisp->m_acNBDV = cMv;
4711    pDisp->m_aVIdxCan = iViewIdx;
4712  }
4713}
4714
4715Bool TComDataCU::getNeighDepth ( UInt uiPartIdx, UInt uiPartAddr, Pel* pNeighDepth, Int index )
4716{
4717  assert(uiPartIdx==0);
4718  const UInt uiPartIdxLT      = getZorderIdxInCtu() + uiPartAddr;
4719  const Int  iPartIdxStride   = getPic()->getNumPartInCtuWidth();
4720 
4721  UInt uiMidPart, uiPartNeighbor; 
4722  const TComDataCU* pcCUNeighbor;
4723  Bool bDepAvail = false;
4724  Pel *pDepth  = this->getPic()->getPicYuvRec()->getAddr(COMPONENT_Y);
4725  Int iDepStride =  this->getPic()->getPicYuvRec()->getStride(COMPONENT_Y);
4726
4727  Int xP, yP, nPSW, nPSH;
4728  this->getPartPosition( uiPartIdx, xP, yP, nPSW, nPSH );
4729
4730  switch( index )
4731  {
4732  case 0: // Mid Left
4733    uiMidPart = g_auiZscanToRaster[uiPartIdxLT] + (nPSH>>1) / this->getPic()->getMinCUHeight() * iPartIdxStride;
4734    pcCUNeighbor = this->getPULeft( uiPartNeighbor, g_auiRasterToZscan[uiMidPart] );
4735    if ( pcCUNeighbor )
4736    {
4737      if( !this->getSlice()->getPPS()->getConstrainedIntraPred() )
4738      {
4739        *pNeighDepth = pDepth[ (yP+(nPSH>>1)) * iDepStride + (xP-1) ];
4740        bDepAvail = true;
4741      }
4742      else if ( pcCUNeighbor->getPredictionMode( uiPartNeighbor ) == MODE_INTRA )
4743      {
4744        *pNeighDepth = pDepth[ (yP+(nPSH>>1)) * iDepStride + (xP-1) ];
4745        bDepAvail = true;
4746      }
4747    }
4748    break;
4749  case 1: // Mid Above
4750    uiMidPart = g_auiZscanToRaster[uiPartIdxLT] + (nPSW>>1) / this->getPic()->getMinCUWidth();
4751    pcCUNeighbor = this->getPUAbove( uiPartNeighbor, g_auiRasterToZscan[uiMidPart] );
4752    if( pcCUNeighbor )
4753    {
4754      if( !this->getSlice()->getPPS()->getConstrainedIntraPred() )
4755      {
4756        *pNeighDepth = pDepth[ (yP-1) * iDepStride + (xP + (nPSW>>1)) ];
4757        bDepAvail = true;
4758      }
4759      else if ( pcCUNeighbor->getPredictionMode( uiPartNeighbor ) == MODE_INTRA )
4760      {
4761        *pNeighDepth = pDepth[ (yP-1) * iDepStride + (xP + (nPSW>>1)) ];
4762        bDepAvail = true;
4763      }
4764    }
4765    break;
4766  default:
4767    break;
4768  }
4769
4770  return bDepAvail;
4771}
4772
4773Void TComDataCU::getDisMvpCandNBDV( DisInfo* pDInfo, Bool bDepthRefine )
4774{
4775  //// ******* Init variables ******* /////
4776  // Init disparity struct for results
4777  pDInfo->m_aVIdxCan = -1;
4778
4779  // Init struct for disparities from MCP neighboring blocks
4780  IDVInfo cIDVInfo;
4781  cIDVInfo.m_bFound = false; 
4782  UInt uiPartIdx = 0;
4783  UInt uiPartAddr = 0;
4784  for (UInt iCurDvMcpCand = 0; iCurDvMcpCand < IDV_CANDS; iCurDvMcpCand++)
4785  {
4786    for (UInt iList = 0; iList < 2; iList++)
4787    {
4788      cIDVInfo.m_acMvCand[iList][iCurDvMcpCand].setZero();
4789      cIDVInfo.m_aVIdxCan[iList][iCurDvMcpCand] = 0; 
4790      cIDVInfo.m_bAvailab[iList][iCurDvMcpCand] = false; 
4791    }
4792  }
4793
4794  if( !m_pcSlice->getDepthRefinementFlag( ) )
4795  {
4796    bDepthRefine = false;
4797  }
4798
4799  // Get Positions 
4800  PartSize eCUMode    = getPartitionSize( uiPartAddr );   
4801  assert(eCUMode == SIZE_2Nx2N);
4802  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB; 
4803
4804  deriveLeftRightTopIdxGeneral(uiPartAddr, uiPartIdx, uiPartIdxLT, uiPartIdxRT );
4805  deriveLeftBottomIdxGeneral  (uiPartAddr, uiPartIdx, uiPartIdxLB );
4806
4807  //// ******* Get disparity from temporal neighboring blocks ******* /////
4808  if ( getSlice()->getEnableTMVPFlag() )
4809  {
4810    TComMv cColMv;
4811    Int iTargetViewIdx = 0;
4812    Int iTStartViewIdx = 0;   
4813
4814    ///*** Derive center position ***
4815    UInt uiPartIdxCenter;
4816    Int  uiLCUIdx = getCtuRsAddr();
4817    xDeriveCenterIdx(uiPartIdx, uiPartIdxCenter );
4818
4819    ///*** Search temporal candidate pictures for disparity vector ***
4820    const Int iNumCandPics = getPic()->getNumDdvCandPics();
4821    for(Int curCandPic = 0; curCandPic < iNumCandPics; curCandPic++)
4822    {
4823      RefPicList eCurRefPicList   = REF_PIC_LIST_0 ;
4824      Int        curCandPicRefIdx = 0;
4825      if( curCandPic == 0 ) 
4826      { 
4827        eCurRefPicList   = RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0);
4828        curCandPicRefIdx = getSlice()->getColRefIdx();
4829      }
4830      else                 
4831      {
4832        eCurRefPicList   = getPic()->getRapRefList();
4833        curCandPicRefIdx = getPic()->getRapRefIdx();
4834      }
4835
4836      Bool bCheck = xGetColDisMV( curCandPic, eCurRefPicList, curCandPicRefIdx, uiLCUIdx,   uiPartIdxCenter,  cColMv, iTargetViewIdx, iTStartViewIdx );
4837
4838      if( bCheck )
4839      {
4840        pDInfo->m_acNBDV = cColMv;
4841        pDInfo->m_aVIdxCan  = iTargetViewIdx;
4842
4843        TComPic* picDepth = NULL;   
4844        picDepth = getSlice()->getIvPic( true, iTargetViewIdx );
4845        if (picDepth && bDepthRefine)
4846        {
4847          estimateDVFromDM(iTargetViewIdx, uiPartIdx, picDepth, uiPartAddr, &cColMv );
4848        }
4849        pDInfo->m_acDoNBDV  = cColMv;
4850        return;
4851      }
4852    }
4853  } 
4854
4855  UInt uiIdx = 0;
4856  Bool        bCheckMcpDv = false;   
4857  const TComDataCU* pcTmpCU     = NULL;
4858
4859  //// ******* Get disparity from left block ******* /////
4860    pcTmpCU = getPULeft(uiIdx, uiPartIdxLB);
4861  bCheckMcpDv = true; 
4862  if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_LEFT, bDepthRefine ) )
4863    return;
4864
4865  //// ******* Get disparity from above block ******* /////
4866  pcTmpCU = getPUAbove(uiIdx, uiPartIdxRT, true, false, true);
4867  if(pcTmpCU != NULL )
4868  {
4869    bCheckMcpDv = ( ( getCtuRsAddr() - pcTmpCU->getCtuRsAddr() ) == 0);
4870    if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_ABOVE , bDepthRefine ) )
4871      return;
4872  }
4873
4874  //// ******* Search MCP blocks ******* /////
4875  if( cIDVInfo.m_bFound ) 
4876  {
4877    for( Int curPos = 0 ; curPos < IDV_CANDS ; curPos++ ) 
4878    {
4879      for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
4880      {
4881        if( cIDVInfo.m_bAvailab[iList][curPos] )
4882        {
4883          TComMv cDispVec = cIDVInfo.m_acMvCand[iList][ curPos ];
4884          pDInfo->m_acNBDV = cDispVec;
4885          pDInfo->m_aVIdxCan = cIDVInfo.m_aVIdxCan[iList][ curPos ];
4886          TComPic* picDepth = getSlice()->getIvPic( true, pDInfo->m_aVIdxCan );
4887
4888          if (picDepth && bDepthRefine)
4889          {
4890            estimateDVFromDM (pDInfo->m_aVIdxCan, uiPartIdx, picDepth, uiPartAddr, &cDispVec);
4891          }
4892          pDInfo->m_acDoNBDV = cDispVec;
4893          return;
4894        }
4895      }
4896    }
4897  }
4898
4899  TComMv defaultDV(0, 0);
4900  pDInfo->m_acNBDV = defaultDV;
4901
4902  if (getSlice()->getDefaultRefViewIdxAvailableFlag())
4903  {
4904    pDInfo->m_aVIdxCan = getSlice()->getDefaultRefViewIdx();
4905
4906    TComPic* picDepth = NULL;
4907    picDepth = getSlice()->getIvPic( true, getSlice()->getDefaultRefViewIdx());
4908    if (picDepth && bDepthRefine)
4909    {
4910      estimateDVFromDM(getSlice()->getDefaultRefViewIdx(), uiPartIdx, picDepth, uiPartAddr, &defaultDV ); // from base view
4911    }
4912    pDInfo->m_acDoNBDV = defaultDV;
4913  }
4914}
4915
4916Pel TComDataCU::getMcpFromDM(TComPicYuv* pcBaseViewDepthPicYuv, TComMv* mv, Int iBlkX, Int iBlkY, Int iBlkWidth, Int iBlkHeight, Int* aiShiftLUT )
4917{
4918  Int iPictureWidth  = pcBaseViewDepthPicYuv->getWidth(COMPONENT_Y);
4919  Int iPictureHeight = pcBaseViewDepthPicYuv->getHeight(COMPONENT_Y);
4920
4921  Int depthStartPosX = Clip3(0,   iPictureWidth - 1,  iBlkX + ((mv->getHor()+2)>>2));
4922  Int depthStartPosY = Clip3(0,   iPictureHeight - 1, iBlkY + ((mv->getVer()+2)>>2));
4923  Int depthEndPosX   = Clip3(0,   iPictureWidth - 1,  iBlkX + iBlkWidth - 1 + ((mv->getHor()+2)>>2));
4924  Int depthEndPosY   = Clip3(0,   iPictureHeight - 1, iBlkY + iBlkHeight - 1 + ((mv->getVer()+2)>>2));
4925
4926  Pel* depthTL  = pcBaseViewDepthPicYuv->getAddr(COMPONENT_Y);
4927  Int depStride =  pcBaseViewDepthPicYuv->getStride(COMPONENT_Y);
4928
4929  Pel  maxDepthVal = 0;
4930  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthStartPosX ]);      // Left Top
4931  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthStartPosX ]);      // Left Bottom
4932  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthEndPosX   ]);      // Right Top
4933  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthEndPosX   ]);      // Right Bottom
4934
4935  return aiShiftLUT[ maxDepthVal ];
4936}
4937
4938Void TComDataCU::estimateDVFromDM(Int refViewIdx, UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred )
4939{
4940  if (picDepth)
4941  {
4942    UInt uiAbsPartAddrCurrCU = m_absZIdxInCtu + uiPartAddr;
4943    Int iWidth, iHeight;
4944    getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight ); // The modified value of uiPartAddr won't be used any more
4945
4946    TComPicYuv* pcBaseViewDepthPicYuv = picDepth->getPicYuvRec();
4947    const TComSPS   &sps =*(getSlice()->getSPS());
4948    Int iBlkX = ( getCtuRsAddr() % picDepth->getFrameWidthInCtus() ) * sps.getMaxCUWidth()  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
4949    Int iBlkY = ( getCtuRsAddr() / picDepth->getFrameWidthInCtus() ) * sps.getMaxCUHeight() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
4950
4951    Int* aiShiftLUT = getSlice()->getDepthToDisparityB(refViewIdx );
4952
4953    Pel iDisp = getMcpFromDM( pcBaseViewDepthPicYuv, cMvPred, iBlkX, iBlkY, iWidth, iHeight, aiShiftLUT );
4954    cMvPred->setHor( iDisp );
4955  }
4956}
4957
4958
4959
4960Bool TComDataCU::xCheckSpatialNBDV( const TComDataCU* pcTmpCU, UInt uiIdx, DisInfo* pNbDvInfo, Bool bSearchForMvpDv, IDVInfo* paIDVInfo, UInt uiMvpDvPos, Bool bDepthRefine )
4961{
4962  if( pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ) )
4963  {
4964    Bool bTmpIsSkipped = pcTmpCU->isSkipped( uiIdx );
4965    for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
4966    {
4967      RefPicList eRefPicList = RefPicList(iList);
4968      Int      refId = pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ;
4969      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
4970
4971      if( refId >= 0)
4972      {
4973        Int refViewIdx  = pcTmpCU->getSlice()->getRefPic(eRefPicList, refId)->getViewIndex();
4974        if (refViewIdx != m_pcSlice->getViewIndex()) 
4975        {
4976          pNbDvInfo->m_acNBDV = cMvPred;
4977          pNbDvInfo->m_aVIdxCan = refViewIdx;
4978
4979          TComPic* picDepth = NULL;
4980          assert(getSlice()->getRefPic(eRefPicList, refId)->getPOC() == getSlice()->getPOC());           
4981          picDepth   = getSlice()->getIvPic (true, refViewIdx );
4982          UInt uiPartIdx = 0;   //Notes from MTK: Please confirm that using 0 as partition index and partition address is correct for CU-level DoNBDV
4983          UInt uiPartAddr = 0;  //QC: confirmed
4984
4985          if (picDepth && bDepthRefine)
4986          {
4987            estimateDVFromDM(refViewIdx, uiPartIdx, picDepth, uiPartAddr, &cMvPred );
4988          }
4989          pNbDvInfo->m_acDoNBDV = cMvPred;
4990          return true;
4991        }
4992        else if ( bSearchForMvpDv && cMvPred.getIDVFlag() && bTmpIsSkipped )
4993        {
4994          assert( uiMvpDvPos < IDV_CANDS );
4995          paIDVInfo->m_acMvCand[iList][ uiMvpDvPos ] = TComMv( cMvPred.getIDVHor(), cMvPred.getIDVVer() );
4996          //Notes from QC: DvMCP is implemented in a way that doesnot carry the reference view identifier as NBDV. It only works for CTC and needs to be fixed to be aligned with other part of the NBDV design.
4997          paIDVInfo->m_aVIdxCan[iList][ uiMvpDvPos ] = cMvPred.getIDVVId();
4998          paIDVInfo->m_bAvailab[iList][ uiMvpDvPos ] = true;
4999          paIDVInfo->m_bFound                        = true; 
5000        }
5001      }
5002    }
5003  }
5004  return false; 
5005}
5006 
5007Void TComDataCU::xDeriveRightBottomNbIdx(Int &riLCUIdxRBNb, Int &riPartIdxRBNb )
5008{
5009  UInt uiPartIdx = 0;
5010  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInCtuWidth(); 
5011  Int uiLCUIdx = getCtuRsAddr();
5012
5013  UInt uiPartIdxRB;
5014  deriveRightBottomIdx(uiPartIdx, uiPartIdxRB ); 
5015  UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
5016
5017  if (( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() )>= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
5018  {
5019    riLCUIdxRBNb  = -1;
5020    riPartIdxRBNb = -1;
5021  }
5022  else if(( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() )>= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
5023  {
5024    riLCUIdxRBNb  = -1;
5025    riPartIdxRBNb = -1;
5026  }
5027  else
5028  {
5029    if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
5030      ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInCtuHeight() - 1 ) ) // is not at the last row    of LCU
5031    {
5032      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
5033      riLCUIdxRBNb  = uiLCUIdx; 
5034    }
5035    else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
5036    {
5037      riPartIdxRBNb = -1;
5038      riLCUIdxRBNb  = -1;
5039    }
5040    else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInCtuHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
5041    {
5042      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
5043      riLCUIdxRBNb = uiLCUIdx + 1;
5044    }
5045    else //is the right bottom corner of LCU                       
5046    {
5047      riPartIdxRBNb = -1;
5048      riLCUIdxRBNb  = -1;
5049    }
5050  }
5051}
5052
5053Void TComDataCU::setDvInfoSubParts( DisInfo cDvInfo, UInt uiAbsPartIdx, UInt uiDepth )
5054{
5055  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
5056  assert(m_pcPic->getNumPartitionsInCtu() ==m_pcPic->getNumPartInCtuWidth()*m_pcPic->getNumPartInCtuHeight());
5057
5058  for (UInt ui = 0; ui < uiCurrPartNumb; ui++ )
5059  {
5060    m_pDvInfo[uiAbsPartIdx + ui] = cDvInfo;
5061  }
5062}
5063
5064Void TComDataCU::setDvInfoSubParts( DisInfo cDvInfo, UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth )
5065{
5066  setSubPartT<DisInfo>( cDvInfo, m_pDvInfo, uiAbsPartIdx, uiDepth, uiPUIdx );
5067}
5068
5069Bool TComDataCU::xGetColDisMV( Int currCandPic, RefPicList eRefPicList, Int refidx, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv , Int & iTargetViewIdx, Int & iStartViewIdx )
5070{
5071
5072  RefPicList  eColRefPicList = REF_PIC_LIST_0;
5073  Int iColViewIdx, iColRefViewIdx;
5074  TComPic *pColPic = getSlice()->getRefPic( eRefPicList, refidx);
5075  TComDataCU *pColCU = pColPic->getCtu( uiCUAddr );
5076  iColViewIdx = pColCU->getSlice()->getViewIndex();
5077  if (pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==NUMBER_OF_PART_SIZES||pColCU->isIntra(uiPartUnitIdx))
5078  {
5079    return false;
5080  }
5081  for (Int ilist = 0; ilist < (pColCU->getSlice()->isInterB()? 2:1); ilist++) 
5082  {
5083    if(pColCU->getSlice()->isInterB())
5084    {
5085      eColRefPicList = RefPicList(ilist);
5086    }
5087
5088    Int iColRefIdx = pColCU->getCUMvField(eColRefPicList)->getRefIdx(uiPartUnitIdx);
5089
5090    if (iColRefIdx < 0)
5091    {
5092      continue;
5093    }
5094
5095    // The picture pColCU->getSlice()->getRefPic(eColRefPicList, iColRefIdx) might not be in DPB anymore
5096    // So don't access it directly.
5097    iColRefViewIdx = pColCU->getSlice()->getVPS()->getViewOrderIdx( pColCU->getSlice()->getRefLayerId( eColRefPicList, iColRefIdx ) );       
5098
5099
5100    if ( iColViewIdx    == iColRefViewIdx ) // temporal vector
5101    {
5102      continue;
5103    }
5104    else 
5105    {
5106      if(getPic()->isTempIVRefValid(currCandPic, ilist,  iColRefIdx))
5107      {
5108        rcMv = pColCU->getCUMvField(eColRefPicList)->getMv(uiPartUnitIdx);
5109        rcMv.setIDVFlag(0);
5110        iTargetViewIdx  = iColRefViewIdx ;
5111        iStartViewIdx   = iColViewIdx   ;
5112        return true;   
5113      }
5114    }
5115  }
5116
5117  return false;
5118}
5119#endif
5120#if  NH_3D_FAST_TEXTURE_ENCODING
5121Void
5122TComDataCU::getIVNStatus       ( UInt uiPartIdx,  DisInfo* pDInfo, Bool& bIVFMerge, Int& iIVFMaxD)
5123{
5124  TComSlice*    pcSlice         = getSlice (); 
5125  Int iViewIndex = pDInfo->m_aVIdxCan;
5126  //--- get base CU/PU and check prediction mode ---
5127  TComPic*    pcBasePic   = pcSlice->getIvPic( false, iViewIndex );
5128  TComPicYuv* pcBaseRec   = pcBasePic->getPicYuvRec   ();
5129
5130  UInt          uiPartAddr;
5131  Int           iWidth;
5132  Int           iHeight;
5133  getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
5134
5135  Int  iCurrPosX, iCurrPosY;
5136  pcBaseRec->getTopLeftSamplePos( this->getCtuRsAddr(), this->getZorderIdxInCtu() + uiPartAddr, iCurrPosX, iCurrPosY );
5137
5138  iCurrPosX  += ( ( iWidth  - 1 ) >> 1 );
5139  iCurrPosY  += ( ( iHeight - 1 ) >> 1 );
5140
5141  Bool depthRefineFlag = m_pcSlice->getDepthRefinementFlag( ); 
5142
5143  TComMv      cDv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
5144  if( depthRefineFlag )
5145  {
5146    cDv.setVer(0);
5147  }
5148
5149  Int         iBasePosX   = Clip3( 0, pcBaseRec->getWidth (COMPONENT_Y) - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
5150  Int         iBasePosY   = Clip3( 0, pcBaseRec->getHeight(COMPONENT_Y) - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
5151  Int         iBaseLPosX   = Clip3( 0, pcBaseRec->getWidth (COMPONENT_Y) - 1, iCurrPosX - (iWidth >> 1) + ( (cDv.getHor() + 2 ) >> 2 ) );
5152  Int         iBaseLPosY   = Clip3( 0, pcBaseRec->getHeight(COMPONENT_Y) - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
5153  Int         iBaseRPosX   = Clip3( 0, pcBaseRec->getWidth (COMPONENT_Y) - 1, iCurrPosX + (iWidth >> 1) + 1 + ( (cDv.getHor() + 2 ) >> 2 ) );
5154  Int         iBaseRPosY   = Clip3( 0, pcBaseRec->getHeight(COMPONENT_Y) - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
5155  Int         iBaseUPosX   = Clip3( 0, pcBaseRec->getWidth (COMPONENT_Y) - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
5156  Int         iBaseUPosY   = Clip3( 0, pcBaseRec->getHeight(COMPONENT_Y) - 1, iCurrPosY - (iHeight >> 1) + ( (cDv.getVer() + 2 ) >> 2 )); 
5157  Int         iBaseDPosX   = Clip3( 0, pcBaseRec->getWidth (COMPONENT_Y) - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
5158  Int         iBaseDPosY   = Clip3( 0, pcBaseRec->getHeight(COMPONENT_Y) - 1, iCurrPosY + (iHeight >> 1) + 1 + ( (cDv.getVer() + 2 ) >> 2 )); 
5159
5160  Int         iBaseCUAddr;
5161  Int         iBaseAbsPartIdx;
5162  Int         iBaseLCUAddr;
5163  Int         iBaseLAbsPartIdx;
5164  Int         iBaseRCUAddr;
5165  Int         iBaseRAbsPartIdx;
5166  Int         iBaseUCUAddr;
5167  Int         iBaseUAbsPartIdx;
5168  Int         iBaseDCUAddr;
5169  Int         iBaseDAbsPartIdx;
5170  pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY , iBaseCUAddr, iBaseAbsPartIdx );
5171  pcBaseRec->getCUAddrAndPartIdx( iBaseLPosX , iBaseLPosY , iBaseLCUAddr, iBaseLAbsPartIdx );
5172  pcBaseRec->getCUAddrAndPartIdx( iBaseRPosX , iBaseRPosY , iBaseRCUAddr, iBaseRAbsPartIdx );
5173  pcBaseRec->getCUAddrAndPartIdx( iBaseUPosX , iBaseUPosY , iBaseUCUAddr, iBaseUAbsPartIdx );
5174  pcBaseRec->getCUAddrAndPartIdx( iBaseDPosX , iBaseDPosY , iBaseDCUAddr, iBaseDAbsPartIdx );
5175  TComDataCU* pcBaseCU     = pcBasePic->getCtu( iBaseCUAddr );
5176  TComDataCU* pcBaseLCU    = pcBasePic->getCtu( iBaseLCUAddr );
5177  TComDataCU* pcBaseRCU    = pcBasePic->getCtu( iBaseRCUAddr );
5178  TComDataCU* pcBaseUCU    = pcBasePic->getCtu( iBaseUCUAddr );
5179  TComDataCU* pcBaseDCU    = pcBasePic->getCtu( iBaseDCUAddr );
5180  bIVFMerge = pcBaseLCU->getMergeFlag( iBaseLAbsPartIdx ) && pcBaseCU->getMergeFlag( iBaseAbsPartIdx ) && pcBaseRCU->getMergeFlag( iBaseRAbsPartIdx ) && pcBaseUCU->getMergeFlag( iBaseUAbsPartIdx ) && pcBaseDCU->getMergeFlag( iBaseDAbsPartIdx );
5181  Int aiDepthL[5]; //depth level