source: 3DVCSoftware/branches/HTM-14.1-update-dev1/source/Lib/TLibCommon/TComDataCU.cpp @ 1305

Last change on this file since 1305 was 1305, checked in by tech, 9 years ago

Further fixes and alignments.

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