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

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

Further fixes to pruning.

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