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

Last change on this file since 1243 was 1243, checked in by rwth, 9 years ago
  • fixed problem when NH_3D_DMM=0
  • cleaned TEMP_SDC_CLEANUP
  • Property svn:eol-style set to native
File size: 227.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 H_3D
58  m_bDISFlag           = NULL;
59  m_uiDISType          = 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 H_3D_NBDV
123  m_pDvInfo              = NULL;
124#endif
125#if H_3D_VSP
126  m_piVSPFlag            = NULL;
127#endif
128#if H_3D_SPIVMP
129  m_pbSPIVMPFlag         = NULL;
130#endif
131#if H_3D_ARP
132  m_puhARPW              = NULL;
133#endif
134#if H_3D_IC
135  m_pbICFlag             = NULL;
136#endif
137#if H_3D_INTER_SDC
138#endif
139#if H_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 H_3D
172    m_bDISFlag           = new Bool[ uiNumPartition ];
173    m_uiDISType          = (UInt*)xMalloc(UInt, 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 H_3D_VSP
183    m_piVSPFlag          = (Char*  )xMalloc(Char,   uiNumPartition);
184#endif
185#if H_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 H_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 H_3D_ARP
247    m_puhARPW            = new UChar[ uiNumPartition];
248#endif
249#if H_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 H_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 H_3D
324    if ( m_bDISFlag           ) { delete[] m_bDISFlag;   m_bDISFlag     = NULL; }
325    if ( m_uiDISType         ) { xFree(m_uiDISType);  m_uiDISType    = 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 H_3D_VSP
365    if ( m_piVSPFlag          ) { xFree(m_piVSPFlag);           m_piVSPFlag         = NULL; }
366#endif
367#if H_3D_SPIVMP
368    if ( m_pbSPIVMPFlag       ) { xFree(m_pbSPIVMPFlag);           m_pbSPIVMPFlag         = NULL; }
369#endif
370
371
372    for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
373    {
374      xFree(m_puhIntraDir[ch]);
375      m_puhIntraDir[ch] = NULL;
376    }
377
378    if ( m_puhTrIdx )
379    {
380      xFree(m_puhTrIdx);
381      m_puhTrIdx = NULL;
382    }
383
384    for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
385    {
386      if ( m_crossComponentPredictionAlpha[comp] )
387      {
388        xFree(m_crossComponentPredictionAlpha[comp]);
389        m_crossComponentPredictionAlpha[comp] = NULL;
390      }
391      if ( m_puhTransformSkip[comp] )
392      {
393        xFree(m_puhTransformSkip[comp]);
394        m_puhTransformSkip[comp] = NULL;
395      }
396      if ( m_puhCbf[comp] )
397      {
398        xFree(m_puhCbf[comp]);
399        m_puhCbf[comp] = NULL;
400      }
401      if ( m_pcTrCoeff[comp] )
402      {
403        xFree(m_pcTrCoeff[comp]);
404        m_pcTrCoeff[comp] = NULL;
405      }
406      if ( m_explicitRdpcmMode[comp] )
407      {
408        xFree(m_explicitRdpcmMode[comp]);
409        m_explicitRdpcmMode[comp] = NULL;
410      }
411
412#if ADAPTIVE_QP_SELECTION
413      if (!m_ArlCoeffIsAliasedAllocation)
414      {
415        if ( m_pcArlCoeff[comp] )
416        {
417          xFree(m_pcArlCoeff[comp]);
418          m_pcArlCoeff[comp] = NULL;
419        }
420      }
421#endif
422
423      if ( m_pcIPCMSample[comp] )
424      {
425        xFree(m_pcIPCMSample[comp]);
426        m_pcIPCMSample[comp] = NULL;
427      }
428    }
429    if ( m_pbIPCMFlag )
430    {
431      xFree(m_pbIPCMFlag );
432      m_pbIPCMFlag = NULL;
433    }
434
435    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
436    {
437      const RefPicList rpl=RefPicList(i);
438      if ( m_apiMVPIdx[rpl] )
439      {
440        delete[] m_apiMVPIdx[rpl];
441        m_apiMVPIdx[rpl] = NULL;
442      }
443      if ( m_apiMVPNum[rpl] )
444      {
445        delete[] m_apiMVPNum[rpl];
446        m_apiMVPNum[rpl] = NULL;
447      }
448    }
449
450    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
451    {
452      const RefPicList rpl=RefPicList(i);
453      m_acCUMvField[rpl].destroy();
454    }
455#if H_3D_NBDV
456    if ( m_pDvInfo            ) { xFree(m_pDvInfo);             m_pDvInfo           = NULL; }
457#endif
458
459
460#if H_3D_ARP
461    if ( m_puhARPW            ) { delete[] m_puhARPW;           m_puhARPW           = NULL; }
462#endif
463#if H_3D_IC
464    if ( m_pbICFlag           ) { xFree(m_pbICFlag);            m_pbICFlag          = NULL; }
465#endif
466
467#if NH_3D_DMM
468    for( Int i = 0; i < NUM_DMM; i++ )
469    {
470      if ( m_dmmDeltaDC[i][0] ) { xFree( m_dmmDeltaDC[i][0] ); m_dmmDeltaDC[i][0] = NULL; }
471      if ( m_dmmDeltaDC[i][1] ) { xFree( m_dmmDeltaDC[i][1] ); m_dmmDeltaDC[i][1] = NULL; }
472    }
473    if ( m_dmm1WedgeTabIdx    ) { xFree( m_dmm1WedgeTabIdx );  m_dmm1WedgeTabIdx = NULL;  }
474#endif
475#if NH_3D_SDC_INTRA
476    if ( m_pbSDCFlag            ) { xFree(m_pbSDCFlag);             m_pbSDCFlag             = NULL; }
477    if ( m_apSegmentDCOffset[0] ) { xFree(m_apSegmentDCOffset[0]);  m_apSegmentDCOffset[0]  = NULL; }
478    if ( m_apSegmentDCOffset[1] ) { xFree(m_apSegmentDCOffset[1]);  m_apSegmentDCOffset[1]  = NULL; }
479#endif   
480#if H_3D_DBBP
481    if ( m_pbDBBPFlag         ) { xFree(m_pbDBBPFlag);          m_pbDBBPFlag        = NULL; }
482#endif
483
484  }
485
486  m_pcPic              = NULL;
487  m_pcSlice            = NULL;
488
489  m_pCtuAboveLeft      = NULL;
490  m_pCtuAboveRight     = NULL;
491  m_pCtuAbove          = NULL;
492  m_pCtuLeft           = NULL;
493
494
495  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
496  {
497    m_apcCUColocated[i]  = NULL;
498  }
499
500}
501
502Bool TComDataCU::CUIsFromSameTile            ( const TComDataCU *pCU /* Can be NULL */) const
503{
504  return pCU!=NULL &&
505         pCU->getSlice() != NULL &&
506         m_pcPic->getPicSym()->getTileIdxMap( pCU->getCtuRsAddr() ) == m_pcPic->getPicSym()->getTileIdxMap(getCtuRsAddr());
507}
508
509Bool TComDataCU::CUIsFromSameSliceAndTile    ( const TComDataCU *pCU /* Can be NULL */) const
510{
511  return pCU!=NULL &&
512         pCU->getSlice() != NULL &&
513         pCU->getSlice()->getSliceCurStartCtuTsAddr() == getSlice()->getSliceCurStartCtuTsAddr() &&
514         m_pcPic->getPicSym()->getTileIdxMap( pCU->getCtuRsAddr() ) == m_pcPic->getPicSym()->getTileIdxMap(getCtuRsAddr())
515         ;
516}
517
518Bool TComDataCU::CUIsFromSameSliceTileAndWavefrontRow( const TComDataCU *pCU /* Can be NULL */) const
519{
520  return CUIsFromSameSliceAndTile(pCU)
521         && (!getSlice()->getPPS()->getEntropyCodingSyncEnabledFlag() || getPic()->getCtu(getCtuRsAddr())->getCUPelY() == getPic()->getCtu(pCU->getCtuRsAddr())->getCUPelY());
522}
523
524Bool TComDataCU::isLastSubCUOfCtu(const UInt absPartIdx)
525{
526  const TComSPS &sps=*(getSlice()->getSPS());
527
528  const UInt picWidth = sps.getPicWidthInLumaSamples();
529  const UInt picHeight = sps.getPicHeightInLumaSamples();
530  const UInt granularityWidth = sps.getMaxCUWidth();
531
532  const UInt cuPosX = getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[absPartIdx] ];
533  const UInt cuPosY = getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[absPartIdx] ];
534
535  return (((cuPosX+getWidth( absPartIdx))%granularityWidth==0||(cuPosX+getWidth( absPartIdx)==picWidth ))
536       && ((cuPosY+getHeight(absPartIdx))%granularityWidth==0||(cuPosY+getHeight(absPartIdx)==picHeight)));
537}
538
539// ====================================================================================================================
540// Public member functions
541// ====================================================================================================================
542
543// --------------------------------------------------------------------------------------------------------------------
544// Initialization
545// --------------------------------------------------------------------------------------------------------------------
546
547/**
548 Initialize top-level CU: create internal buffers and set initial values before encoding the CTU.
549 
550 \param  pcPic       picture (TComPic) class pointer
551 \param  ctuRsAddr   CTU address in raster scan order
552 */
553Void TComDataCU::initCtu( TComPic* pcPic, UInt ctuRsAddr )
554{
555
556  const UInt maxCUWidth = pcPic->getPicSym()->getSPS().getMaxCUWidth();
557  const UInt maxCUHeight= pcPic->getPicSym()->getSPS().getMaxCUHeight();
558  m_pcPic              = pcPic;
559  m_pcSlice            = pcPic->getSlice(pcPic->getCurrSliceIdx());
560  m_ctuRsAddr          = ctuRsAddr;
561  m_uiCUPelX           = ( ctuRsAddr % pcPic->getFrameWidthInCtus() ) * maxCUWidth;
562  m_uiCUPelY           = ( ctuRsAddr / pcPic->getFrameWidthInCtus() ) * maxCUHeight;
563  m_absZIdxInCtu       = 0;
564  m_dTotalCost         = MAX_DOUBLE;
565  m_uiTotalDistortion  = 0;
566  m_uiTotalBits        = 0;
567  m_uiTotalBins        = 0;
568  m_uiNumPartition     = pcPic->getNumPartitionsInCtu();
569
570  memset( m_skipFlag          , false,                      m_uiNumPartition * sizeof( *m_skipFlag ) );
571
572#if H_3D
573    m_bDISFlag[ui]   = pcFrom->getDISFlag(ui);
574    m_uiDISType[ui]  = pcFrom->getDISType(ui);
575#endif
576
577  memset( m_pePartSize        , NUMBER_OF_PART_SIZES,       m_uiNumPartition * sizeof( *m_pePartSize ) );
578  memset( m_pePredMode        , NUMBER_OF_PREDICTION_MODES, m_uiNumPartition * sizeof( *m_pePredMode ) );
579  memset( m_CUTransquantBypass, false,                      m_uiNumPartition * sizeof( *m_CUTransquantBypass) );
580  memset( m_puhDepth          , 0,                          m_uiNumPartition * sizeof( *m_puhDepth ) );
581  memset( m_puhTrIdx          , 0,                          m_uiNumPartition * sizeof( *m_puhTrIdx ) );
582  memset( m_puhWidth          , maxCUWidth,                 m_uiNumPartition * sizeof( *m_puhWidth ) );
583  memset( m_puhHeight         , maxCUHeight,                m_uiNumPartition * sizeof( *m_puhHeight ) );
584
585#if H_3D_ARP
586    m_puhARPW   [ui] = pcFrom->getARPW( ui );
587#endif
588#if H_3D_IC
589    m_pbICFlag[ui]   =  pcFrom->m_pbICFlag[ui];
590#endif
591
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 H_3D_VSP
611    m_piVSPFlag[ui] = pcFrom->m_piVSPFlag[ui];
612#endif
613#if H_3D_SPIVMP
614    m_pbSPIVMPFlag[ui] = pcFrom->m_pbSPIVMPFlag[ui];
615#endif
616#if NH_3D_SDC_INTRA
617  memset( m_pbSDCFlag, false, m_uiNumPartition * sizeof( *m_pbSDCFlag ) );
618#endif
619#if H_3D_DBBP
620    m_pbDBBPFlag[ui] = pcFrom->m_pbDBBPFlag[ui];
621#endif
622#if H_3D
623    memset( m_bDISFlag          + firstElement, false,                    numElements * sizeof( *m_bDISFlag ) );
624    memset( m_uiDISType         + firstElement,     0,                    numElements * sizeof( *m_uiDISType) );
625#endif
626#if H_3D_VSP
627    memset( m_piVSPFlag         + firstElement, 0,                        numElements * sizeof( *m_piVSPFlag ) );
628#endif
629#if H_3D_SPIVMP
630    memset( m_pbSPIVMPFlag      + firstElement, 0,                        numElements * sizeof( *m_pbSPIVMPFlag ) );
631#endif
632
633  for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
634  {
635    memset( m_puhIntraDir[ch] , ((ch==0) ? DC_IDX : 0),   m_uiNumPartition * sizeof( *(m_puhIntraDir[ch]) ) );
636  }
637
638#if H_3D_ARP
639    memset( m_puhARPW           + firstElement, 0,                        numElements * sizeof( UChar )         );
640#endif
641#if H_3D_IC
642    memset( m_pbICFlag          + firstElement, false,                    numElements * sizeof( *m_pbICFlag )   );
643#endif
644
645
646
647#if NH_3D_DMM
648  for( Int i = 0; i < NUM_DMM; i++ )
649  {
650    memset( m_dmmDeltaDC[i][0], 0,                        m_uiNumPartition * sizeof( *m_dmmDeltaDC[i][0] ) );
651    memset( m_dmmDeltaDC[i][1], 0,                        m_uiNumPartition * sizeof( *m_dmmDeltaDC[i][1] ) );
652  }
653  memset( m_dmm1WedgeTabIdx,    0,                        m_uiNumPartition * sizeof( *m_dmm1WedgeTabIdx   ) );
654#endif
655#if NH_3D_SDC_INTRA
656    memset( m_pbSDCFlag,     false,                m_uiNumPartition * sizeof( *m_pbSDCFlag ) );
657    memset( m_apSegmentDCOffset[0],     0,                m_uiNumPartition * sizeof( *m_apSegmentDCOffset[0] ) );
658    memset( m_apSegmentDCOffset[1],     0,                m_uiNumPartition * sizeof( *m_apSegmentDCOffset[1] ) );
659#endif
660#if H_3D_DBBP
661    memset( m_pbDBBPFlag        + firstElement, false,                    numElements * sizeof( *m_pbDBBPFlag ) );
662#endif
663
664  memset( m_puhInterDir       , 0,                        m_uiNumPartition * sizeof( *m_puhInterDir ) );
665  memset( m_pbIPCMFlag        , false,                    m_uiNumPartition * sizeof( *m_pbIPCMFlag ) );
666
667  const UInt numCoeffY    = maxCUWidth*maxCUHeight;
668  for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
669  {
670    const UInt componentShift = m_pcPic->getComponentScaleX(ComponentID(comp)) + m_pcPic->getComponentScaleY(ComponentID(comp));
671    memset( m_pcTrCoeff[comp], 0, sizeof(TCoeff)* numCoeffY>>componentShift );
672#if ADAPTIVE_QP_SELECTION
673    memset( m_pcArlCoeff[comp], 0, sizeof(TCoeff)* numCoeffY>>componentShift );
674#endif
675  }
676
677  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
678  {
679    m_acCUMvField[i].clearMvField();
680  }
681
682  // Setting neighbor CU
683  m_pCtuLeft        = NULL;
684  m_pCtuAbove       = NULL;
685  m_pCtuAboveLeft   = NULL;
686  m_pCtuAboveRight  = NULL;
687
688
689  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
690  {
691    m_apcCUColocated[i]  = NULL;
692  }
693
694  UInt frameWidthInCtus = pcPic->getFrameWidthInCtus();
695  if ( m_ctuRsAddr % frameWidthInCtus )
696  {
697    m_pCtuLeft = pcPic->getCtu( m_ctuRsAddr - 1 );
698  }
699
700  if ( m_ctuRsAddr / frameWidthInCtus )
701  {
702    m_pCtuAbove = pcPic->getCtu( m_ctuRsAddr - frameWidthInCtus );
703  }
704
705  if ( m_pCtuLeft && m_pCtuAbove )
706  {
707    m_pCtuAboveLeft = pcPic->getCtu( m_ctuRsAddr - frameWidthInCtus - 1 );
708  }
709
710  if ( m_pCtuAbove && ( (m_ctuRsAddr%frameWidthInCtus) < (frameWidthInCtus-1) )  )
711  {
712    m_pCtuAboveRight = pcPic->getCtu( m_ctuRsAddr - frameWidthInCtus + 1 );
713  }
714
715  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
716  {
717    const RefPicList rpl=RefPicList(i);
718    if ( getSlice()->getNumRefIdx( rpl ) > 0 )
719    {
720      m_apcCUColocated[rpl] = getSlice()->getRefPic( rpl, 0)->getCtu( m_ctuRsAddr );
721    }
722  }
723}
724
725
726/** Initialize prediction data with enabling sub-CTU-level delta QP.
727*   - set CU width and CU height according to depth
728*   - set qp value according to input qp
729*   - set last-coded qp value according to input last-coded qp
730*
731* \param  uiDepth            depth of the current CU
732* \param  qp                 qp for the current CU
733* \param  bTransquantBypass  true for transquant bypass
734*/
735Void TComDataCU::initEstData( const UInt uiDepth, const Int qp, const Bool bTransquantBypass )
736{
737  m_dTotalCost         = MAX_DOUBLE;
738  m_uiTotalDistortion  = 0;
739  m_uiTotalBits        = 0;
740  m_uiTotalBins        = 0;
741
742  const UChar uhWidth  = getSlice()->getSPS()->getMaxCUWidth()  >> uiDepth;
743  const UChar uhHeight = getSlice()->getSPS()->getMaxCUHeight() >> uiDepth;
744
745  for (UInt ui = 0; ui < m_uiNumPartition; ui++)
746  {
747    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
748    {
749      const RefPicList rpl=RefPicList(i);
750      m_apiMVPIdx[rpl][ui]  = -1;
751      m_apiMVPNum[rpl][ui]  = -1;
752    }
753    m_puhDepth  [ui]    = uiDepth;
754    m_puhWidth  [ui]    = uhWidth;
755    m_puhHeight [ui]    = uhHeight;
756    m_puhTrIdx  [ui]    = 0;
757    for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
758    {
759      m_crossComponentPredictionAlpha[comp][ui] = 0;
760      m_puhTransformSkip             [comp][ui] = 0;
761      m_explicitRdpcmMode            [comp][ui] = NUMBER_OF_RDPCM_MODES;
762    }
763    m_skipFlag[ui]      = false;
764#if H_3D
765      m_bDISFlag[ui]   = false;
766      m_uiDISType[ui]  = 0;
767#endif
768    m_pePartSize[ui]    = NUMBER_OF_PART_SIZES;
769    m_pePredMode[ui]    = NUMBER_OF_PREDICTION_MODES;
770    m_CUTransquantBypass[ui] = bTransquantBypass;
771    m_pbIPCMFlag[ui]    = 0;
772    m_phQP[ui]          = qp;
773    m_ChromaQpAdj[ui]   = 0;
774    m_pbMergeFlag[ui]   = 0;
775    m_puhMergeIndex[ui] = 0;
776#if H_3D_VSP
777      m_piVSPFlag[ui] = 0;
778#endif
779#if H_3D_SPIVMP
780      m_pbSPIVMPFlag[ui] = 0;
781#endif
782
783    for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
784    {
785      m_puhIntraDir[ch][ui] = ((ch==0) ? DC_IDX : 0);
786    }
787
788    m_puhInterDir[ui] = 0;
789    for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
790    {
791      m_puhCbf[comp][ui] = 0;
792    }
793#if H_3D_ARP
794      m_puhARPW[ui] = 0;
795#endif
796#if H_3D_IC
797      m_pbICFlag[ui]  = false;
798#endif
799
800
801#if NH_3D_DMM
802    for( Int i = 0; i < NUM_DMM; i++ )
803    {
804      m_dmmDeltaDC[i][0] [ui] = 0;
805      m_dmmDeltaDC[i][1] [ui] = 0;
806    }
807    m_dmm1WedgeTabIdx    [ui] = 0;
808#endif
809#if NH_3D_SDC_INTRA
810      m_pbSDCFlag           [ui] = false;
811      m_apSegmentDCOffset[0][ui] = 0;
812      m_apSegmentDCOffset[1][ui] = 0;
813#endif
814#if H_3D_DBBP
815      m_pbDBBPFlag[ui] = false;
816#endif
817  }
818
819  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
820  {
821    m_acCUMvField[i].clearMvField();
822  }
823
824  const UInt numCoeffY = uhWidth*uhHeight;
825
826  for (UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
827  {
828    const ComponentID component = ComponentID(comp);
829    const UInt numCoeff = numCoeffY >> (getPic()->getComponentScaleX(component) + getPic()->getComponentScaleY(component));
830    memset( m_pcTrCoeff[comp],    0, numCoeff * sizeof( TCoeff ) );
831#if ADAPTIVE_QP_SELECTION
832    memset( m_pcArlCoeff[comp],   0, numCoeff * sizeof( TCoeff ) );
833#endif
834    memset( m_pcIPCMSample[comp], 0, numCoeff * sizeof( Pel) );
835  }
836}
837
838
839// initialize Sub partition
840Void TComDataCU::initSubCU( TComDataCU* pcCU, UInt uiPartUnitIdx, UInt uiDepth, Int qp )
841{
842  assert( uiPartUnitIdx<4 );
843
844  UInt uiPartOffset = ( pcCU->getTotalNumPart()>>2 )*uiPartUnitIdx;
845
846  m_pcPic              = pcCU->getPic();
847  m_pcSlice            = pcCU->getSlice();
848  m_ctuRsAddr          = pcCU->getCtuRsAddr();
849  m_absZIdxInCtu       = pcCU->getZorderIdxInCtu() + uiPartOffset;
850
851  const UChar uhWidth  = getSlice()->getSPS()->getMaxCUWidth()  >> uiDepth;
852  const UChar uhHeight = getSlice()->getSPS()->getMaxCUHeight() >> uiDepth;
853
854  m_uiCUPelX           = pcCU->getCUPelX() + ( uhWidth )*( uiPartUnitIdx &  1 );
855  m_uiCUPelY           = pcCU->getCUPelY() + ( uhHeight)*( uiPartUnitIdx >> 1 );
856
857  m_dTotalCost         = MAX_DOUBLE;
858  m_uiTotalDistortion  = 0;
859  m_uiTotalBits        = 0;
860  m_uiTotalBins        = 0;
861  m_uiNumPartition     = pcCU->getTotalNumPart() >> 2;
862
863  Int iSizeInUchar = sizeof( UChar  ) * m_uiNumPartition;
864  Int iSizeInBool  = sizeof( Bool   ) * m_uiNumPartition;
865  Int sizeInChar = sizeof( Char  ) * m_uiNumPartition;
866
867  memset( m_phQP,              qp,  sizeInChar );
868  memset( m_pbMergeFlag,        0, iSizeInBool  );
869  memset( m_puhMergeIndex,      0, iSizeInUchar );
870#if H_3D_VSP
871  memset( m_piVSPFlag,          0, sizeof( Char  ) * m_uiNumPartition );
872#endif
873#if H_3D_SPIVMP
874  memset( m_pbSPIVMPFlag,       0, sizeof( Bool  ) * m_uiNumPartition );
875#endif
876
877  for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
878  {
879    memset( m_puhIntraDir[ch],  ((ch==0) ? DC_IDX : 0), iSizeInUchar );
880  }
881
882  memset( m_puhInterDir,        0, iSizeInUchar );
883  memset( m_puhTrIdx,           0, iSizeInUchar );
884
885  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
886  {
887    memset( m_crossComponentPredictionAlpha[comp], 0, iSizeInUchar );
888    memset( m_puhTransformSkip[comp],              0, iSizeInUchar );
889    memset( m_puhCbf[comp],                        0, iSizeInUchar );
890    memset( m_explicitRdpcmMode[comp],             NUMBER_OF_RDPCM_MODES, iSizeInUchar );
891  }
892#if H_3D_ARP
893  memset( m_puhARPW,            0, iSizeInUchar  );
894#endif
895
896  memset( m_puhDepth,     uiDepth, iSizeInUchar );
897  memset( m_puhWidth,          uhWidth,  iSizeInUchar );
898  memset( m_puhHeight,         uhHeight, iSizeInUchar );
899  memset( m_pbIPCMFlag,        0, iSizeInBool  );
900#if H_3D_IC
901  memset( m_pbICFlag,          0, iSizeInBool  );
902#endif
903#if NH_3D_DMM
904  for( Int i = 0; i < NUM_DMM; i++ )
905  {
906    memset( m_dmmDeltaDC[i][0], 0, sizeof(Pel ) * m_uiNumPartition );
907    memset( m_dmmDeltaDC[i][1], 0, sizeof(Pel ) * m_uiNumPartition );
908  }
909  memset( m_dmm1WedgeTabIdx,    0, sizeof(UInt) * m_uiNumPartition );
910#endif
911#if NH_3D_SDC_INTRA
912  memset( m_pbSDCFlag,            0, sizeof(Bool) * m_uiNumPartition  );
913  memset( m_apSegmentDCOffset[0], 0, sizeof(Pel) * m_uiNumPartition   );
914  memset( m_apSegmentDCOffset[1], 0, sizeof(Pel) * m_uiNumPartition   );
915#endif
916#if H_3D_DBBP
917  memset( m_pbDBBPFlag,         0, iSizeInBool  );
918#endif
919
920  for (UInt ui = 0; ui < m_uiNumPartition; ui++)
921  {
922    m_skipFlag[ui]   = false;
923#if H_3D
924    m_bDISFlag[ui]   = false;
925    m_uiDISType[ui]  = 0;
926#endif
927
928    m_pePartSize[ui] = NUMBER_OF_PART_SIZES;
929    m_pePredMode[ui] = NUMBER_OF_PREDICTION_MODES;
930    m_CUTransquantBypass[ui] = false;
931    m_ChromaQpAdj[ui] = 0;
932
933    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
934    {
935      const RefPicList rpl=RefPicList(i);
936      m_apiMVPIdx[rpl][ui] = -1;
937      m_apiMVPNum[rpl][ui] = -1;
938    }
939#if H_3D
940      m_bDISFlag[ui]    = pcCU->getDISFlag(uiPartOffset+ui);
941      m_uiDISType[ui]   = pcCU->getDISType(uiPartOffset+ui);
942#endif
943#if H_3D_VSP
944      m_piVSPFlag[ui]=pcCU->m_piVSPFlag[uiPartOffset+ui];
945      m_pDvInfo[ ui ] = pcCU->m_pDvInfo[uiPartOffset+ui];
946#endif
947#if H_3D_SPIVMP
948      m_pbSPIVMPFlag[ui]=pcCU->m_pbSPIVMPFlag[uiPartOffset+ui];
949#endif
950#if H_3D_ARP
951      m_puhARPW           [ui] = pcCU->getARPW( uiPartOffset+ui );
952#endif
953#if H_3D_IC
954      m_pbICFlag          [ui] = pcCU->m_pbICFlag[uiPartOffset+ui];
955#endif
956#if NH_3D_DMM
957  for( Int i = 0; i < NUM_DMM; i++ )
958  {
959    m_dmmDeltaDC[i][0] [ui] = pcCU->m_dmmDeltaDC[i][0] [uiPartOffset+ui];
960    m_dmmDeltaDC[i][1] [ui] = pcCU->m_dmmDeltaDC[i][1] [uiPartOffset+ui];
961  }
962  m_dmm1WedgeTabIdx    [ui] = pcCU->m_dmm1WedgeTabIdx  [uiPartOffset+ui];
963#endif
964#if NH_3D_SDC_INTRA
965    m_pbSDCFlag           [ui] = pcCU->m_pbSDCFlag            [ uiPartOffset + ui ];
966    m_apSegmentDCOffset[0][ui] = pcCU->m_apSegmentDCOffset[0] [ uiPartOffset + ui ];
967    m_apSegmentDCOffset[1][ui] = pcCU->m_apSegmentDCOffset[1] [ uiPartOffset + ui ];
968#endif
969#if H_3D_DBBP
970      m_pbDBBPFlag[ui]=pcCU->m_pbDBBPFlag[uiPartOffset+ui];
971#endif
972  }
973
974  const UInt numCoeffY    = uhWidth*uhHeight;
975  for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
976  {
977    const UInt componentShift = m_pcPic->getComponentScaleX(ComponentID(ch)) + m_pcPic->getComponentScaleY(ComponentID(ch));
978    memset( m_pcTrCoeff[ch],  0, sizeof(TCoeff)*(numCoeffY>>componentShift) );
979#if ADAPTIVE_QP_SELECTION
980    memset( m_pcArlCoeff[ch], 0, sizeof(TCoeff)*(numCoeffY>>componentShift) );
981#endif
982    memset( m_pcIPCMSample[ch], 0, sizeof(Pel)* (numCoeffY>>componentShift) );
983  }
984
985  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
986  {
987    m_acCUMvField[i].clearMvField();
988  }
989
990  m_pCtuLeft        = pcCU->getCtuLeft();
991  m_pCtuAbove       = pcCU->getCtuAbove();
992  m_pCtuAboveLeft   = pcCU->getCtuAboveLeft();
993  m_pCtuAboveRight  = pcCU->getCtuAboveRight();
994
995  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
996  {
997    m_apcCUColocated[i] = pcCU->getCUColocated(RefPicList(i));
998  }
999}
1000
1001Void TComDataCU::setOutsideCUPart( UInt uiAbsPartIdx, UInt uiDepth )
1002{
1003  const UInt     uiNumPartition = m_uiNumPartition >> (uiDepth << 1);
1004  const UInt     uiSizeInUchar  = sizeof( UChar  ) * uiNumPartition;
1005  const TComSPS &sps            = *(getSlice()->getSPS());
1006  const UChar    uhWidth        = sps.getMaxCUWidth()  >> uiDepth;
1007  const UChar    uhHeight       = sps.getMaxCUHeight() >> uiDepth;
1008  memset( m_puhDepth    + uiAbsPartIdx,     uiDepth,  uiSizeInUchar );
1009  memset( m_puhWidth    + uiAbsPartIdx,     uhWidth,  uiSizeInUchar );
1010  memset( m_puhHeight   + uiAbsPartIdx,     uhHeight, uiSizeInUchar );
1011}
1012
1013// --------------------------------------------------------------------------------------------------------------------
1014// Copy
1015// --------------------------------------------------------------------------------------------------------------------
1016
1017Void TComDataCU::copySubCU( TComDataCU* pcCU, UInt uiAbsPartIdx )
1018{
1019  UInt uiPart = uiAbsPartIdx;
1020
1021  m_pcPic              = pcCU->getPic();
1022  m_pcSlice            = pcCU->getSlice();
1023  m_ctuRsAddr          = pcCU->getCtuRsAddr();
1024  m_absZIdxInCtu       = uiAbsPartIdx;
1025
1026  m_uiCUPelX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1027  m_uiCUPelY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1028
1029  m_skipFlag=pcCU->getSkipFlag()          + uiPart;
1030#if H_3D
1031  m_bDISFlag     = pcCU->getDISFlag()     + uiPart;
1032  m_uiDISType    = pcCU->getDISType()     + uiPart;
1033#endif
1034
1035  m_phQP=pcCU->getQP()                    + uiPart;
1036  m_ChromaQpAdj = pcCU->getChromaQpAdj()  + uiPart;
1037  m_pePartSize = pcCU->getPartitionSize() + uiPart;
1038  m_pePredMode=pcCU->getPredictionMode()  + uiPart;
1039  m_CUTransquantBypass  = pcCU->getCUTransquantBypass()+uiPart;
1040#if H_3D_NBDV
1041  m_pDvInfo             = pcCU->getDvInfo()           + uiPart;
1042#endif
1043
1044  m_pbMergeFlag         = pcCU->getMergeFlag()        + uiPart;
1045  m_puhMergeIndex       = pcCU->getMergeIndex()       + uiPart;
1046#if H_3D_VSP
1047  m_piVSPFlag           = pcCU->getVSPFlag()          + uiPart;
1048#endif
1049#if H_3D_SPIVMP
1050  m_pbSPIVMPFlag        = pcCU->getSPIVMPFlag()          + uiPart;
1051#endif
1052#if H_3D_ARP
1053  m_puhARPW             = pcCU->getARPW()             + uiPart;
1054#endif
1055#if H_3D_IC
1056  m_pbICFlag            = pcCU->getICFlag()           + uiPart;
1057#endif
1058
1059  for (UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
1060  {
1061    m_puhIntraDir[ch]   = pcCU->getIntraDir(ChannelType(ch)) + uiPart;
1062  }
1063
1064  m_puhInterDir         = pcCU->getInterDir()         + uiPart;
1065  m_puhTrIdx            = pcCU->getTransformIdx()     + uiPart;
1066
1067  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
1068  {
1069    m_crossComponentPredictionAlpha[comp] = pcCU->getCrossComponentPredictionAlpha(ComponentID(comp)) + uiPart;
1070    m_puhTransformSkip[comp]              = pcCU->getTransformSkip(ComponentID(comp))                 + uiPart;
1071    m_puhCbf[comp]                        = pcCU->getCbf(ComponentID(comp))                           + uiPart;
1072    m_explicitRdpcmMode[comp]             = pcCU->getExplicitRdpcmMode(ComponentID(comp))             + uiPart;
1073  }
1074#if NH_3D_DMM
1075  for( Int i = 0; i < NUM_DMM; i++ )
1076  {
1077    m_dmmDeltaDC[i][0] = pcCU->getDmmDeltaDC( (DmmID)i, 0 ) + uiPart;
1078    m_dmmDeltaDC[i][1] = pcCU->getDmmDeltaDC( (DmmID)i, 1 ) + uiPart;
1079  }
1080  m_dmm1WedgeTabIdx    = pcCU->getDmm1WedgeTabIdx()  + uiPart;
1081#endif
1082#if NH_3D_SDC_INTRA
1083  m_pbSDCFlag               = pcCU->getSDCFlag()              + uiPart;
1084  m_apSegmentDCOffset[0]    = pcCU->getSDCSegmentDCOffset(0)  + uiPart;
1085  m_apSegmentDCOffset[1]    = pcCU->getSDCSegmentDCOffset(1)  + uiPart;
1086#endif 
1087#if H_3D_DBBP
1088  m_pbDBBPFlag              = pcCU->getDBBPFlag()         + uiPart;
1089#endif
1090
1091  m_puhDepth=pcCU->getDepth()                     + uiPart;
1092  m_puhWidth=pcCU->getWidth()                     + uiPart;
1093  m_puhHeight=pcCU->getHeight()                   + uiPart;
1094
1095  m_pbIPCMFlag         = pcCU->getIPCMFlag()        + uiPart;
1096
1097  m_pCtuAboveLeft      = pcCU->getCtuAboveLeft();
1098  m_pCtuAboveRight     = pcCU->getCtuAboveRight();
1099  m_pCtuAbove          = pcCU->getCtuAbove();
1100  m_pCtuLeft           = pcCU->getCtuLeft();
1101
1102  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1103  {
1104    const RefPicList rpl=RefPicList(i);
1105    m_apcCUColocated[rpl] = pcCU->getCUColocated(rpl);
1106    m_apiMVPIdx[rpl]=pcCU->getMVPIdx(rpl)  + uiPart;
1107    m_apiMVPNum[rpl]=pcCU->getMVPNum(rpl)  + uiPart;
1108  }
1109
1110  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1111  {
1112    const RefPicList rpl=RefPicList(i);
1113    m_acCUMvField[rpl].linkToWithOffset( pcCU->getCUMvField(rpl), uiPart );
1114  }
1115
1116  UInt uiMaxCuWidth=pcCU->getSlice()->getSPS()->getMaxCUWidth();
1117  UInt uiMaxCuHeight=pcCU->getSlice()->getSPS()->getMaxCUHeight();
1118
1119  UInt uiCoffOffset = uiMaxCuWidth*uiMaxCuHeight*uiAbsPartIdx/pcCU->getPic()->getNumPartitionsInCtu();
1120
1121  for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
1122  {
1123    const ComponentID component = ComponentID(ch);
1124    const UInt componentShift   = m_pcPic->getComponentScaleX(component) + m_pcPic->getComponentScaleY(component);
1125    const UInt offset           = uiCoffOffset >> componentShift;
1126    m_pcTrCoeff[ch] = pcCU->getCoeff(component) + offset;
1127#if ADAPTIVE_QP_SELECTION
1128    m_pcArlCoeff[ch] = pcCU->getArlCoeff(component) + offset;
1129#endif
1130    m_pcIPCMSample[ch] = pcCU->getPCMSample(component) + offset;
1131  }
1132}
1133
1134#if H_3D_NBDV
1135Void TComDataCU::copyDVInfoFrom (TComDataCU* pcCU, UInt uiAbsPartIdx)
1136{
1137  m_pDvInfo            = pcCU->getDvInfo()                + uiAbsPartIdx;
1138}
1139#endif
1140
1141// Copy inter prediction info from the biggest CU
1142Void TComDataCU::copyInterPredInfoFrom    ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList
1143#if H_3D_NBDV
1144  , Bool bNBDV
1145#endif
1146)
1147{
1148  m_pcPic              = pcCU->getPic();
1149  m_pcSlice            = pcCU->getSlice();
1150  m_ctuRsAddr          = pcCU->getCtuRsAddr();
1151  m_absZIdxInCtu       = uiAbsPartIdx;
1152
1153  Int iRastPartIdx     = g_auiZscanToRaster[uiAbsPartIdx];
1154  m_uiCUPelX           = pcCU->getCUPelX() + m_pcPic->getMinCUWidth ()*( iRastPartIdx % m_pcPic->getNumPartInCtuWidth() );
1155  m_uiCUPelY           = pcCU->getCUPelY() + m_pcPic->getMinCUHeight()*( iRastPartIdx / m_pcPic->getNumPartInCtuWidth() );
1156
1157  m_pCtuAboveLeft      = pcCU->getCtuAboveLeft();
1158  m_pCtuAboveRight     = pcCU->getCtuAboveRight();
1159  m_pCtuAbove          = pcCU->getCtuAbove();
1160  m_pCtuLeft           = pcCU->getCtuLeft();
1161
1162  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1163  {
1164    m_apcCUColocated[i]  = pcCU->getCUColocated(RefPicList(i));
1165  }
1166
1167  m_skipFlag           = pcCU->getSkipFlag ()             + uiAbsPartIdx;
1168#if H_3D
1169  m_bDISFlag           = pcCU->getDISFlag ()              + uiAbsPartIdx;
1170  m_uiDISType          = pcCU->getDISType()               + uiAbsPartIdx;
1171#endif
1172
1173  m_pePartSize         = pcCU->getPartitionSize ()        + uiAbsPartIdx;
1174#if H_3D_NBDV
1175  if(bNBDV == true)
1176  {
1177    m_puhWidth           = pcCU->getWidth ()                + uiAbsPartIdx;
1178    m_puhHeight          = pcCU->getHeight()                + uiAbsPartIdx;
1179    m_puhDepth           = pcCU->getDepth ()                + uiAbsPartIdx;
1180  }
1181  else
1182  {
1183#endif
1184  m_pePredMode         = pcCU->getPredictionMode()        + uiAbsPartIdx;
1185  m_ChromaQpAdj        = pcCU->getChromaQpAdj()           + uiAbsPartIdx;
1186  m_CUTransquantBypass = pcCU->getCUTransquantBypass()    + uiAbsPartIdx;
1187  m_puhInterDir        = pcCU->getInterDir      ()        + uiAbsPartIdx;
1188
1189  m_puhDepth           = pcCU->getDepth ()                + uiAbsPartIdx;
1190  m_puhWidth           = pcCU->getWidth ()                + uiAbsPartIdx;
1191  m_puhHeight          = pcCU->getHeight()                + uiAbsPartIdx;
1192
1193  m_pbMergeFlag        = pcCU->getMergeFlag()             + uiAbsPartIdx;
1194  m_puhMergeIndex      = pcCU->getMergeIndex()            + uiAbsPartIdx;
1195#if H_3D_VSP
1196  m_piVSPFlag          = pcCU->getVSPFlag()               + uiAbsPartIdx;
1197  m_pDvInfo            = pcCU->getDvInfo()                + uiAbsPartIdx;
1198#endif
1199#if H_3D_SPIVMP
1200  m_pbSPIVMPFlag       = pcCU->getSPIVMPFlag()            + uiAbsPartIdx;
1201#endif
1202
1203  m_apiMVPIdx[eRefPicList] = pcCU->getMVPIdx(eRefPicList) + uiAbsPartIdx;
1204  m_apiMVPNum[eRefPicList] = pcCU->getMVPNum(eRefPicList) + uiAbsPartIdx;
1205#if H_3D_ARP
1206  m_puhARPW            = pcCU->getARPW()                  + uiAbsPartIdx;
1207#endif   
1208#if H_3D_DBBP
1209  m_pbDBBPFlag       = pcCU->getDBBPFlag()              + uiAbsPartIdx;
1210#endif
1211
1212  m_acCUMvField[ eRefPicList ].linkToWithOffset( pcCU->getCUMvField(eRefPicList), uiAbsPartIdx );
1213#if H_3D_NBDV
1214  }
1215#endif
1216#if H_3D_IC
1217  m_pbICFlag           = pcCU->getICFlag()                + uiAbsPartIdx;
1218#endif
1219
1220}
1221
1222// Copy small CU to bigger CU.
1223// One of quarter parts overwritten by predicted sub part.
1224Void TComDataCU::copyPartFrom( TComDataCU* pcCU, UInt uiPartUnitIdx, UInt uiDepth )
1225{
1226  assert( uiPartUnitIdx<4 );
1227
1228  m_dTotalCost         += pcCU->getTotalCost();
1229  m_uiTotalDistortion  += pcCU->getTotalDistortion();
1230  m_uiTotalBits        += pcCU->getTotalBits();
1231
1232  UInt uiOffset         = pcCU->getTotalNumPart()*uiPartUnitIdx;
1233  const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
1234  const UInt numValidChan=pcCU->getPic()->getChromaFormat()==CHROMA_400 ? 1:2;
1235
1236  UInt uiNumPartition = pcCU->getTotalNumPart();
1237  Int iSizeInUchar  = sizeof( UChar ) * uiNumPartition;
1238  Int iSizeInBool   = sizeof( Bool  ) * uiNumPartition;
1239
1240  Int sizeInChar  = sizeof( Char ) * uiNumPartition;
1241  memcpy( m_skipFlag   + uiOffset, pcCU->getSkipFlag(),       sizeof( *m_skipFlag )   * uiNumPartition );
1242#if H_3D
1243  memcpy( m_bDISFlag   + uiOffset, pcCU->getDISFlag(),       sizeof( *m_bDISFlag )   * uiNumPartition );
1244  memcpy( m_uiDISType  + uiOffset, pcCU->getDISType(),       sizeof( *m_uiDISType )  * uiNumPartition);
1245#endif
1246  memcpy( m_phQP       + uiOffset, pcCU->getQP(),             sizeInChar                        );
1247  memcpy( m_pePartSize + uiOffset, pcCU->getPartitionSize(),  sizeof( *m_pePartSize ) * uiNumPartition );
1248  memcpy( m_pePredMode + uiOffset, pcCU->getPredictionMode(), sizeof( *m_pePredMode ) * uiNumPartition );
1249  memcpy( m_ChromaQpAdj + uiOffset, pcCU->getChromaQpAdj(),   sizeof( *m_ChromaQpAdj ) * uiNumPartition );
1250  memcpy( m_CUTransquantBypass + uiOffset, pcCU->getCUTransquantBypass(), sizeof( *m_CUTransquantBypass ) * uiNumPartition );
1251  memcpy( m_pbMergeFlag         + uiOffset, pcCU->getMergeFlag(),         iSizeInBool  );
1252  memcpy( m_puhMergeIndex       + uiOffset, pcCU->getMergeIndex(),        iSizeInUchar );
1253#if H_3D_VSP
1254  memcpy( m_piVSPFlag           + uiOffset, pcCU->getVSPFlag(),           sizeof( Char ) * uiNumPartition );
1255  memcpy( m_pDvInfo             + uiOffset, pcCU->getDvInfo(),            sizeof( *m_pDvInfo ) * uiNumPartition );
1256#endif
1257#if H_3D_SPIVMP
1258  memcpy( m_pbSPIVMPFlag        + uiOffset, pcCU->getSPIVMPFlag(),        sizeof( Bool ) * uiNumPartition );
1259#endif
1260
1261  for (UInt ch=0; ch<numValidChan; ch++)
1262  {
1263    memcpy( m_puhIntraDir[ch]   + uiOffset, pcCU->getIntraDir(ChannelType(ch)), iSizeInUchar );
1264  }
1265
1266  memcpy( m_puhInterDir         + uiOffset, pcCU->getInterDir(),          iSizeInUchar );
1267  memcpy( m_puhTrIdx            + uiOffset, pcCU->getTransformIdx(),      iSizeInUchar );
1268
1269  for(UInt comp=0; comp<numValidComp; comp++)
1270  {
1271    memcpy( m_crossComponentPredictionAlpha[comp] + uiOffset, pcCU->getCrossComponentPredictionAlpha(ComponentID(comp)), iSizeInUchar );
1272    memcpy( m_puhTransformSkip[comp]              + uiOffset, pcCU->getTransformSkip(ComponentID(comp))                , iSizeInUchar );
1273    memcpy( m_puhCbf[comp]                        + uiOffset, pcCU->getCbf(ComponentID(comp))                          , iSizeInUchar );
1274    memcpy( m_explicitRdpcmMode[comp]             + uiOffset, pcCU->getExplicitRdpcmMode(ComponentID(comp))            , iSizeInUchar );
1275  }
1276#if NH_3D_DMM
1277  for( Int i = 0; i < NUM_DMM; i++ )
1278  {
1279    memcpy( m_dmmDeltaDC[i][0] + uiOffset, pcCU->getDmmDeltaDC( (DmmID)i, 0 ), sizeof(Pel ) * uiNumPartition );
1280    memcpy( m_dmmDeltaDC[i][1] + uiOffset, pcCU->getDmmDeltaDC( (DmmID)i, 1 ), sizeof(Pel ) * uiNumPartition );
1281  }
1282  memcpy( m_dmm1WedgeTabIdx    + uiOffset, pcCU->getDmm1WedgeTabIdx(),         sizeof(UInt) * uiNumPartition );
1283#endif
1284#if NH_3D_SDC_INTRA
1285  memcpy( m_pbSDCFlag             + uiOffset, pcCU->getSDCFlag(), sizeof( *m_pbSDCFlag ) * uiNumPartition  );
1286  memcpy( m_apSegmentDCOffset[0]  + uiOffset, pcCU->getSDCSegmentDCOffset(0), sizeof( Pel ) * uiNumPartition);
1287  memcpy( m_apSegmentDCOffset[1]  + uiOffset, pcCU->getSDCSegmentDCOffset(1), sizeof( Pel ) * uiNumPartition);
1288#endif
1289#if H_3D_DBBP
1290  memcpy( m_pbDBBPFlag          + uiOffset, pcCU->getDBBPFlag(),          iSizeInBool  );
1291#endif
1292
1293  memcpy( m_puhDepth  + uiOffset, pcCU->getDepth(),  iSizeInUchar );
1294  memcpy( m_puhWidth  + uiOffset, pcCU->getWidth(),  iSizeInUchar );
1295  memcpy( m_puhHeight + uiOffset, pcCU->getHeight(), iSizeInUchar );
1296
1297  memcpy( m_pbIPCMFlag + uiOffset, pcCU->getIPCMFlag(), iSizeInBool );
1298
1299  m_pCtuAboveLeft      = pcCU->getCtuAboveLeft();
1300  m_pCtuAboveRight     = pcCU->getCtuAboveRight();
1301  m_pCtuAbove          = pcCU->getCtuAbove();
1302  m_pCtuLeft           = pcCU->getCtuLeft();
1303
1304  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1305  {
1306    const RefPicList rpl=RefPicList(i);
1307    memcpy( m_apiMVPIdx[rpl] + uiOffset, pcCU->getMVPIdx(rpl), iSizeInUchar );
1308    memcpy( m_apiMVPNum[rpl] + uiOffset, pcCU->getMVPNum(rpl), iSizeInUchar );
1309    m_apcCUColocated[rpl] = pcCU->getCUColocated(rpl);
1310  }
1311
1312  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1313  {
1314    const RefPicList rpl=RefPicList(i);
1315    m_acCUMvField[rpl].copyFrom( pcCU->getCUMvField( rpl ), pcCU->getTotalNumPart(), uiOffset );
1316  }
1317
1318  const UInt numCoeffY = (pcCU->getSlice()->getSPS()->getMaxCUWidth()*pcCU->getSlice()->getSPS()->getMaxCUHeight()) >> (uiDepth<<1);
1319  const UInt offsetY   = uiPartUnitIdx*numCoeffY;
1320  for (UInt ch=0; ch<numValidComp; ch++)
1321  {
1322    const ComponentID component = ComponentID(ch);
1323    const UInt componentShift   = m_pcPic->getComponentScaleX(component) + m_pcPic->getComponentScaleY(component);
1324    const UInt offset           = offsetY>>componentShift;
1325    memcpy( m_pcTrCoeff [ch] + offset, pcCU->getCoeff(component),    sizeof(TCoeff)*(numCoeffY>>componentShift) );
1326#if ADAPTIVE_QP_SELECTION
1327    memcpy( m_pcArlCoeff[ch] + offset, pcCU->getArlCoeff(component), sizeof(TCoeff)*(numCoeffY>>componentShift) );
1328#endif
1329    memcpy( m_pcIPCMSample[ch] + offset, pcCU->getPCMSample(component), sizeof(Pel)*(numCoeffY>>componentShift) );
1330  }
1331
1332#if H_3D_ARP
1333  memcpy( m_puhARPW             + uiOffset, pcCU->getARPW(),              iSizeInUchar );
1334#endif
1335#if H_3D_IC
1336  memcpy( m_pbICFlag            + uiOffset, pcCU->getICFlag(),            iSizeInBool );
1337#endif
1338
1339  m_uiTotalBins += pcCU->getTotalBins();
1340}
1341
1342// Copy current predicted part to a CU in picture.
1343// It is used to predict for next part
1344Void TComDataCU::copyToPic( UChar uhDepth )
1345{
1346  TComDataCU* pCtu = m_pcPic->getCtu( m_ctuRsAddr );
1347  const UInt numValidComp=pCtu->getPic()->getNumberValidComponents();
1348  const UInt numValidChan=pCtu->getPic()->getChromaFormat()==CHROMA_400 ? 1:2;
1349
1350  pCtu->getTotalCost()       = m_dTotalCost;
1351  pCtu->getTotalDistortion() = m_uiTotalDistortion;
1352  pCtu->getTotalBits()       = m_uiTotalBits;
1353
1354  Int iSizeInUchar  = sizeof( UChar ) * m_uiNumPartition;
1355  Int iSizeInBool   = sizeof( Bool  ) * m_uiNumPartition;
1356  Int sizeInChar  = sizeof( Char ) * m_uiNumPartition;
1357
1358  memcpy( pCtu->getSkipFlag() + m_absZIdxInCtu, m_skipFlag, sizeof( *m_skipFlag ) * m_uiNumPartition );
1359#if H_3D
1360  memcpy( rpcCU->getDISFlag()  + m_uiAbsIdxInLCU, m_bDISFlag,    sizeof( *m_bDISFlag )  * m_uiNumPartition );
1361  memcpy( rpcCU->getDISType()  + m_uiAbsIdxInLCU, m_uiDISType,   sizeof( *m_uiDISType ) * m_uiNumPartition );
1362#endif
1363
1364  memcpy( pCtu->getQP() + m_absZIdxInCtu, m_phQP, sizeInChar  );
1365#if H_3D_NBDV
1366  memcpy( rpcCU->getDvInfo()         + m_uiAbsIdxInLCU, m_pDvInfo,    sizeof(* m_pDvInfo)     * m_uiNumPartition );
1367#endif
1368
1369  memcpy( pCtu->getPartitionSize()  + m_absZIdxInCtu, m_pePartSize, sizeof( *m_pePartSize ) * m_uiNumPartition );
1370  memcpy( pCtu->getPredictionMode() + m_absZIdxInCtu, m_pePredMode, sizeof( *m_pePredMode ) * m_uiNumPartition );
1371  memcpy( pCtu->getChromaQpAdj() + m_absZIdxInCtu, m_ChromaQpAdj, sizeof( *m_ChromaQpAdj ) * m_uiNumPartition );
1372  memcpy( pCtu->getCUTransquantBypass()+ m_absZIdxInCtu, m_CUTransquantBypass, sizeof( *m_CUTransquantBypass ) * m_uiNumPartition );
1373  memcpy( pCtu->getMergeFlag()         + m_absZIdxInCtu, m_pbMergeFlag,         iSizeInBool  );
1374  memcpy( pCtu->getMergeIndex()        + m_absZIdxInCtu, m_puhMergeIndex,       iSizeInUchar );
1375  #if H_3D_VSP
1376  memcpy( rpcCU->getVSPFlag()           + m_uiAbsIdxInLCU, m_piVSPFlag,           sizeof( Char ) * m_uiNumPartition );
1377  memcpy( rpcCU->getDvInfo()            + m_uiAbsIdxInLCU, m_pDvInfo,             sizeof( *m_pDvInfo ) * m_uiNumPartition );
1378#endif
1379#if H_3D_SPIVMP
1380  memcpy( rpcCU->getSPIVMPFlag()        + m_uiAbsIdxInLCU, m_pbSPIVMPFlag,        sizeof( Bool ) * m_uiNumPartition );
1381#endif
1382
1383for (UInt ch=0; ch<numValidChan; ch++)
1384  {
1385    memcpy( pCtu->getIntraDir(ChannelType(ch)) + m_absZIdxInCtu, m_puhIntraDir[ch], iSizeInUchar);
1386  }
1387
1388  memcpy( pCtu->getInterDir()          + m_absZIdxInCtu, m_puhInterDir,         iSizeInUchar );
1389  memcpy( pCtu->getTransformIdx()      + m_absZIdxInCtu, m_puhTrIdx,            iSizeInUchar );
1390
1391  for(UInt comp=0; comp<numValidComp; comp++)
1392  {
1393    memcpy( pCtu->getCrossComponentPredictionAlpha(ComponentID(comp)) + m_absZIdxInCtu, m_crossComponentPredictionAlpha[comp], iSizeInUchar );
1394    memcpy( pCtu->getTransformSkip(ComponentID(comp))                 + m_absZIdxInCtu, m_puhTransformSkip[comp],              iSizeInUchar );
1395    memcpy( pCtu->getCbf(ComponentID(comp))                           + m_absZIdxInCtu, m_puhCbf[comp],                        iSizeInUchar );
1396    memcpy( pCtu->getExplicitRdpcmMode(ComponentID(comp))             + m_absZIdxInCtu, m_explicitRdpcmMode[comp],             iSizeInUchar );
1397  }
1398
1399#if NH_3D_DMM
1400  for( Int i = 0; i < NUM_DMM; i++ )
1401  {
1402    memcpy( pCtu->getDmmDeltaDC( (DmmID)i, 0 ) + m_absZIdxInCtu, m_dmmDeltaDC[i][0], sizeof(Pel ) * m_uiNumPartition );
1403    memcpy( pCtu->getDmmDeltaDC( (DmmID)i, 1 ) + m_absZIdxInCtu, m_dmmDeltaDC[i][1], sizeof(Pel ) * m_uiNumPartition );
1404  }
1405  memcpy( pCtu->getDmm1WedgeTabIdx()           + m_absZIdxInCtu, m_dmm1WedgeTabIdx,  sizeof(UInt) * m_uiNumPartition );
1406#endif
1407#if NH_3D_SDC_INTRA
1408  memcpy( pCtu->getSDCFlag()             + m_absZIdxInCtu, m_pbSDCFlag, sizeof(Bool) * m_uiNumPartition );
1409  memcpy( pCtu->getSDCSegmentDCOffset(0) + m_absZIdxInCtu, m_apSegmentDCOffset[0], sizeof( Pel ) * m_uiNumPartition);
1410  memcpy( pCtu->getSDCSegmentDCOffset(1) + m_absZIdxInCtu, m_apSegmentDCOffset[1], sizeof( Pel ) * m_uiNumPartition);
1411#endif
1412#if H_3D_DBBP
1413  memcpy( rpcCU->getDBBPFlag()          + m_uiAbsIdxInLCU, m_pbDBBPFlag,          iSizeInBool  );
1414#endif
1415
1416  memcpy( pCtu->getDepth()  + m_absZIdxInCtu, m_puhDepth,  iSizeInUchar );
1417  memcpy( pCtu->getWidth()  + m_absZIdxInCtu, m_puhWidth,  iSizeInUchar );
1418  memcpy( pCtu->getHeight() + m_absZIdxInCtu, m_puhHeight, iSizeInUchar );
1419
1420  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1421  {
1422    const RefPicList rpl=RefPicList(i);
1423    memcpy( pCtu->getMVPIdx(rpl) + m_absZIdxInCtu, m_apiMVPIdx[rpl], iSizeInUchar );
1424    memcpy( pCtu->getMVPNum(rpl) + m_absZIdxInCtu, m_apiMVPNum[rpl], iSizeInUchar );
1425  }
1426
1427  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
1428  {
1429    const RefPicList rpl=RefPicList(i);
1430    m_acCUMvField[rpl].copyTo( pCtu->getCUMvField( rpl ), m_absZIdxInCtu );
1431  }
1432
1433  memcpy( pCtu->getIPCMFlag() + m_absZIdxInCtu, m_pbIPCMFlag,         iSizeInBool  );
1434
1435  const UInt numCoeffY    = (pCtu->getSlice()->getSPS()->getMaxCUWidth()*pCtu->getSlice()->getSPS()->getMaxCUHeight())>>(uhDepth<<1);
1436  const UInt offsetY      = m_absZIdxInCtu*m_pcPic->getMinCUWidth()*m_pcPic->getMinCUHeight();
1437  for (UInt comp=0; comp<numValidComp; comp++)
1438  {
1439    const ComponentID component = ComponentID(comp);
1440    const UInt componentShift   = m_pcPic->getComponentScaleX(component) + m_pcPic->getComponentScaleY(component);
1441    memcpy( pCtu->getCoeff(component)   + (offsetY>>componentShift), m_pcTrCoeff[component], sizeof(TCoeff)*(numCoeffY>>componentShift) );
1442#if ADAPTIVE_QP_SELECTION
1443    memcpy( pCtu->getArlCoeff(component) + (offsetY>>componentShift), m_pcArlCoeff[component], sizeof(TCoeff)*(numCoeffY>>componentShift) );
1444#endif
1445    memcpy( pCtu->getPCMSample(component) + (offsetY>>componentShift), m_pcIPCMSample[component], sizeof(Pel)*(numCoeffY>>componentShift) );
1446  }
1447
1448#if H_3D_ARP
1449  memcpy( rpcCU->getARPW()             + m_uiAbsIdxInLCU, m_puhARPW,             iSizeInUchar );
1450#endif
1451#if H_3D_IC
1452  memcpy( rpcCU->getICFlag()           + m_uiAbsIdxInLCU, m_pbICFlag,            iSizeInBool );
1453#endif
1454
1455  pCtu->getTotalBins() = m_uiTotalBins;
1456}
1457
1458#if H_3D
1459  memcpy( rpcCU->getDISFlag()  + uiPartOffset, m_bDISFlag,    sizeof( *m_bDISFlag )   * uiQNumPart );
1460  memcpy( rpcCU->getDISType()  + uiPartOffset, m_uiDISType,   sizeof( *m_uiDISType )  * uiQNumPart );
1461#endif
1462
1463#if H_3D_VSP
1464  memcpy( rpcCU->getVSPFlag()           + uiPartOffset, m_piVSPFlag,           sizeof(Char) * uiQNumPart );
1465#endif
1466#if H_3D_SPIVMP
1467  memcpy( rpcCU->getSPIVMPFlag()        + uiPartOffset, m_pbSPIVMPFlag,        sizeof(Bool) * uiQNumPart );
1468#endif
1469#if H_3D_DBBP
1470  memcpy( rpcCU->getDBBPFlag()          + uiPartOffset, m_pbDBBPFlag,          iSizeInBool  );
1471#endif
1472#if H_3D_ARP
1473  memcpy( rpcCU->getARPW()             + uiPartOffset, m_puhARPW,             iSizeInUchar );
1474#endif
1475#if H_3D_IC
1476  memcpy( rpcCU->getICFlag()           + uiPartOffset, m_pbICFlag,            iSizeInBool );
1477#endif
1478
1479
1480
1481// --------------------------------------------------------------------------------------------------------------------
1482// Other public functions
1483// --------------------------------------------------------------------------------------------------------------------
1484
1485TComDataCU* TComDataCU::getPULeft( UInt& uiLPartUnitIdx,
1486                                   UInt uiCurrPartUnitIdx,
1487                                   Bool bEnforceSliceRestriction,
1488                                   Bool bEnforceTileRestriction )
1489{
1490  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1491  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_absZIdxInCtu];
1492  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1493
1494  if ( !RasterAddress::isZeroCol( uiAbsPartIdx, numPartInCtuWidth ) )
1495  {
1496    uiLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - 1 ];
1497    if ( RasterAddress::isEqualCol( uiAbsPartIdx, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1498    {
1499      return m_pcPic->getCtu( getCtuRsAddr() );
1500    }
1501    else
1502    {
1503      uiLPartUnitIdx -= m_absZIdxInCtu;
1504      return this;
1505    }
1506  }
1507
1508  uiLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + numPartInCtuWidth - 1 ];
1509  if ( (bEnforceSliceRestriction && !CUIsFromSameSlice(m_pCtuLeft)) || (bEnforceTileRestriction && !CUIsFromSameTile(m_pCtuLeft)) )
1510  {
1511    return NULL;
1512  }
1513  return m_pCtuLeft;
1514}
1515
1516
1517TComDataCU* TComDataCU::getPUAbove( UInt& uiAPartUnitIdx,
1518                                    UInt uiCurrPartUnitIdx,
1519                                    Bool bEnforceSliceRestriction,
1520                                    Bool planarAtCtuBoundary,
1521                                    Bool bEnforceTileRestriction )
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::isZeroRow( uiAbsPartIdx, numPartInCtuWidth ) )
1528  {
1529    uiAPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - numPartInCtuWidth ];
1530    if ( RasterAddress::isEqualRow( uiAbsPartIdx, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1531    {
1532      return m_pcPic->getCtu( getCtuRsAddr() );
1533    }
1534    else
1535    {
1536      uiAPartUnitIdx -= m_absZIdxInCtu;
1537      return this;
1538    }
1539  }
1540
1541  if(planarAtCtuBoundary)
1542  {
1543    return NULL;
1544  }
1545
1546  uiAPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + m_pcPic->getNumPartitionsInCtu() - numPartInCtuWidth ];
1547
1548  if ( (bEnforceSliceRestriction && !CUIsFromSameSlice(m_pCtuAbove)) || (bEnforceTileRestriction && !CUIsFromSameTile(m_pCtuAbove)) )
1549  {
1550    return NULL;
1551  }
1552  return m_pCtuAbove;
1553}
1554
1555TComDataCU* TComDataCU::getPUAboveLeft( UInt& uiALPartUnitIdx, UInt uiCurrPartUnitIdx, Bool bEnforceSliceRestriction )
1556{
1557  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1558  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_absZIdxInCtu];
1559  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1560
1561  if ( !RasterAddress::isZeroCol( uiAbsPartIdx, numPartInCtuWidth ) )
1562  {
1563    if ( !RasterAddress::isZeroRow( uiAbsPartIdx, numPartInCtuWidth ) )
1564    {
1565      uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - numPartInCtuWidth - 1 ];
1566      if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdx, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1567      {
1568        return m_pcPic->getCtu( getCtuRsAddr() );
1569      }
1570      else
1571      {
1572        uiALPartUnitIdx -= m_absZIdxInCtu;
1573        return this;
1574      }
1575    }
1576    uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + getPic()->getNumPartitionsInCtu() - numPartInCtuWidth - 1 ];
1577    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAbove) )
1578    {
1579      return NULL;
1580    }
1581    return m_pCtuAbove;
1582  }
1583
1584  if ( !RasterAddress::isZeroRow( uiAbsPartIdx, numPartInCtuWidth ) )
1585  {
1586    uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - 1 ];
1587    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuLeft) )
1588    {
1589      return NULL;
1590    }
1591    return m_pCtuLeft;
1592  }
1593
1594  uiALPartUnitIdx = g_auiRasterToZscan[ m_pcPic->getNumPartitionsInCtu() - 1 ];
1595  if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAboveLeft) )
1596  {
1597    return NULL;
1598  }
1599  return m_pCtuAboveLeft;
1600}
1601
1602TComDataCU* TComDataCU::getPUBelowLeft(UInt& uiBLPartUnitIdx,  UInt uiCurrPartUnitIdx, UInt uiPartUnitOffset, Bool bEnforceSliceRestriction)
1603{
1604  UInt uiAbsPartIdxLB     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1605  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1606  UInt uiAbsZorderCUIdxLB = g_auiZscanToRaster[ m_absZIdxInCtu ] + ((m_puhHeight[0] / m_pcPic->getMinCUHeight()) - 1)*numPartInCtuWidth;
1607
1608  if( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxLB] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples())
1609  {
1610    uiBLPartUnitIdx = MAX_UINT;
1611    return NULL;
1612  }
1613
1614  if ( RasterAddress::lessThanRow( uiAbsPartIdxLB, m_pcPic->getNumPartInCtuHeight() - uiPartUnitOffset, numPartInCtuWidth ) )
1615  {
1616    if ( !RasterAddress::isZeroCol( uiAbsPartIdxLB, numPartInCtuWidth ) )
1617    {
1618      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxLB + uiPartUnitOffset * numPartInCtuWidth - 1 ] )
1619      {
1620        uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + uiPartUnitOffset * numPartInCtuWidth - 1 ];
1621        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxLB, uiAbsZorderCUIdxLB, numPartInCtuWidth ) )
1622        {
1623          return m_pcPic->getCtu( getCtuRsAddr() );
1624        }
1625        else
1626        {
1627          uiBLPartUnitIdx -= m_absZIdxInCtu;
1628          return this;
1629        }
1630      }
1631      uiBLPartUnitIdx = MAX_UINT;
1632      return NULL;
1633    }
1634    uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + (1+uiPartUnitOffset) * numPartInCtuWidth - 1 ];
1635    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuLeft) )
1636    {
1637      return NULL;
1638    }
1639    return m_pCtuLeft;
1640  }
1641
1642  uiBLPartUnitIdx = MAX_UINT;
1643  return NULL;
1644}
1645
1646TComDataCU* TComDataCU::getPUAboveRight(UInt&  uiARPartUnitIdx, UInt uiCurrPartUnitIdx, UInt uiPartUnitOffset, Bool bEnforceSliceRestriction)
1647{
1648  UInt uiAbsPartIdxRT     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1649  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[ m_absZIdxInCtu ] + (m_puhWidth[0] / m_pcPic->getMinCUWidth()) - 1;
1650  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1651
1652  if( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxRT] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
1653  {
1654    uiARPartUnitIdx = MAX_UINT;
1655    return NULL;
1656  }
1657
1658  if ( RasterAddress::lessThanCol( uiAbsPartIdxRT, numPartInCtuWidth - uiPartUnitOffset, numPartInCtuWidth ) )
1659  {
1660    if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, numPartInCtuWidth ) )
1661    {
1662      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxRT - numPartInCtuWidth + uiPartUnitOffset ] )
1663      {
1664        uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT - numPartInCtuWidth + uiPartUnitOffset ];
1665        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxRT, uiAbsZorderCUIdx, numPartInCtuWidth ) )
1666        {
1667          return m_pcPic->getCtu( getCtuRsAddr() );
1668        }
1669        else
1670        {
1671          uiARPartUnitIdx -= m_absZIdxInCtu;
1672          return this;
1673        }
1674      }
1675      uiARPartUnitIdx = MAX_UINT;
1676      return NULL;
1677    }
1678
1679    uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT + m_pcPic->getNumPartitionsInCtu() - numPartInCtuWidth + uiPartUnitOffset ];
1680    if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAbove) )
1681    {
1682      return NULL;
1683    }
1684    return m_pCtuAbove;
1685  }
1686
1687  if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, numPartInCtuWidth ) )
1688  {
1689    uiARPartUnitIdx = MAX_UINT;
1690    return NULL;
1691  }
1692
1693  uiARPartUnitIdx = g_auiRasterToZscan[ m_pcPic->getNumPartitionsInCtu() - numPartInCtuWidth + uiPartUnitOffset-1 ];
1694  if ( bEnforceSliceRestriction && !CUIsFromSameSliceAndTile(m_pCtuAboveRight) )
1695  {
1696    return NULL;
1697  }
1698  return m_pCtuAboveRight;
1699}
1700
1701/** Get left QpMinCu
1702*\param   uiLPartUnitIdx
1703*\param   uiCurrAbsIdxInCtu
1704*\returns TComDataCU*   point of TComDataCU of left QpMinCu
1705*/
1706TComDataCU* TComDataCU::getQpMinCuLeft( UInt& uiLPartUnitIdx, UInt uiCurrAbsIdxInCtu )
1707{
1708  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1709  const UInt maxCUDepth        = getSlice()->getSPS()->getMaxTotalCUDepth();
1710  const UInt maxCuDQPDepth     = getSlice()->getPPS()->getMaxCuDQPDepth();
1711  const UInt doubleDepthDifference = ((maxCUDepth - maxCuDQPDepth)<<1);
1712  UInt absZorderQpMinCUIdx = (uiCurrAbsIdxInCtu>>doubleDepthDifference)<<doubleDepthDifference;
1713  UInt absRorderQpMinCUIdx = g_auiZscanToRaster[absZorderQpMinCUIdx];
1714
1715  // check for left CTU boundary
1716  if ( RasterAddress::isZeroCol(absRorderQpMinCUIdx, numPartInCtuWidth) )
1717  {
1718    return NULL;
1719  }
1720
1721  // get index of left-CU relative to top-left corner of current quantization group
1722  uiLPartUnitIdx = g_auiRasterToZscan[absRorderQpMinCUIdx - 1];
1723
1724  // return pointer to current CTU
1725  return m_pcPic->getCtu( getCtuRsAddr() );
1726}
1727
1728/** Get Above QpMinCu
1729*\param   uiAPartUnitIdx
1730*\param   uiCurrAbsIdxInCtu
1731*\returns TComDataCU*   point of TComDataCU of above QpMinCu
1732*/
1733TComDataCU* TComDataCU::getQpMinCuAbove( UInt& uiAPartUnitIdx, UInt uiCurrAbsIdxInCtu )
1734{
1735  const UInt numPartInCtuWidth = m_pcPic->getNumPartInCtuWidth();
1736  const UInt maxCUDepth        = getSlice()->getSPS()->getMaxTotalCUDepth();
1737  const UInt maxCuDQPDepth     = getSlice()->getPPS()->getMaxCuDQPDepth();
1738  const UInt doubleDepthDifference = ((maxCUDepth - maxCuDQPDepth)<<1);
1739  UInt absZorderQpMinCUIdx = (uiCurrAbsIdxInCtu>>doubleDepthDifference)<<doubleDepthDifference;
1740  UInt absRorderQpMinCUIdx = g_auiZscanToRaster[absZorderQpMinCUIdx];
1741
1742  // check for top CTU boundary
1743  if ( RasterAddress::isZeroRow( absRorderQpMinCUIdx, numPartInCtuWidth) )
1744  {
1745    return NULL;
1746  }
1747
1748  // get index of top-CU relative to top-left corner of current quantization group
1749  uiAPartUnitIdx = g_auiRasterToZscan[absRorderQpMinCUIdx - numPartInCtuWidth];
1750
1751  // return pointer to current CTU
1752  return m_pcPic->getCtu( getCtuRsAddr() );
1753}
1754
1755
1756
1757/** Get reference QP from left QpMinCu or latest coded QP
1758*\param   uiCurrAbsIdxInCtu
1759*\returns Char   reference QP value
1760*/
1761Char TComDataCU::getRefQP( UInt uiCurrAbsIdxInCtu )
1762{
1763  UInt lPartIdx = MAX_UINT;
1764  UInt aPartIdx = MAX_UINT;
1765  TComDataCU* cULeft  = getQpMinCuLeft ( lPartIdx, m_absZIdxInCtu + uiCurrAbsIdxInCtu );
1766  TComDataCU* cUAbove = getQpMinCuAbove( aPartIdx, m_absZIdxInCtu + uiCurrAbsIdxInCtu );
1767  return (((cULeft? cULeft->getQP( lPartIdx ): getLastCodedQP( uiCurrAbsIdxInCtu )) + (cUAbove? cUAbove->getQP( aPartIdx ): getLastCodedQP( uiCurrAbsIdxInCtu )) + 1) >> 1);
1768}
1769
1770Int TComDataCU::getLastValidPartIdx( Int iAbsPartIdx )
1771{
1772  Int iLastValidPartIdx = iAbsPartIdx-1;
1773  while ( iLastValidPartIdx >= 0
1774       && getPredictionMode( iLastValidPartIdx ) == NUMBER_OF_PREDICTION_MODES )
1775  {
1776    UInt uiDepth = getDepth( iLastValidPartIdx );
1777    iLastValidPartIdx -= m_uiNumPartition>>(uiDepth<<1);
1778  }
1779  return iLastValidPartIdx;
1780}
1781
1782Char TComDataCU::getLastCodedQP( UInt uiAbsPartIdx )
1783{
1784  UInt uiQUPartIdxMask = ~((1<<((getSlice()->getSPS()->getMaxTotalCUDepth() - getSlice()->getPPS()->getMaxCuDQPDepth())<<1))-1);
1785  Int iLastValidPartIdx = getLastValidPartIdx( uiAbsPartIdx&uiQUPartIdxMask ); // A idx will be invalid if it is off the right or bottom edge of the picture.
1786  // If this CU is in the first CTU of the slice and there is no valid part before this one, use slice QP
1787  if ( getPic()->getPicSym()->getCtuTsToRsAddrMap(getSlice()->getSliceCurStartCtuTsAddr()) == getCtuRsAddr() && Int(getZorderIdxInCtu())+iLastValidPartIdx<0)
1788  {
1789    return getSlice()->getSliceQp();
1790  }
1791  else if ( iLastValidPartIdx >= 0 )
1792  {
1793    // If there is a valid part within the current Sub-CU, use it
1794    return getQP( iLastValidPartIdx );
1795  }
1796  else
1797  {
1798    if ( getZorderIdxInCtu() > 0 )
1799    {
1800      // If this wasn't the first sub-cu within the Ctu, explore the CTU itself.
1801      return getPic()->getCtu( getCtuRsAddr() )->getLastCodedQP( getZorderIdxInCtu() ); // TODO - remove this recursion
1802    }
1803    else if ( getPic()->getPicSym()->getCtuRsToTsAddrMap(getCtuRsAddr()) > 0
1804      && CUIsFromSameSliceTileAndWavefrontRow(getPic()->getCtu(getPic()->getPicSym()->getCtuTsToRsAddrMap(getPic()->getPicSym()->getCtuRsToTsAddrMap(getCtuRsAddr())-1))) )
1805    {
1806      // 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.
1807      return getPic()->getCtu( getPic()->getPicSym()->getCtuTsToRsAddrMap(getPic()->getPicSym()->getCtuRsToTsAddrMap(getCtuRsAddr())-1) )->getLastCodedQP( getPic()->getNumPartitionsInCtu() );  // TODO - remove this recursion
1808    }
1809    else
1810    {
1811      // No other options available - use the slice-level QP.
1812      return getSlice()->getSliceQp();
1813    }
1814  }
1815}
1816
1817
1818/** Check whether the CU is coded in lossless coding mode.
1819 * \param   absPartIdx
1820 * \returns true if the CU is coded in lossless coding mode; false if otherwise
1821 */
1822Bool TComDataCU::isLosslessCoded(UInt absPartIdx)
1823{
1824  return (getSlice()->getPPS()->getTransquantBypassEnableFlag() && getCUTransquantBypass (absPartIdx));
1825}
1826
1827
1828/** Get allowed chroma intra modes
1829*   - fills uiModeList with chroma intra modes
1830*
1831*\param   [in]  uiAbsPartIdx
1832*\param   [out] uiModeList pointer to chroma intra modes array
1833*/
1834Void TComDataCU::getAllowedChromaDir( UInt uiAbsPartIdx, UInt uiModeList[NUM_CHROMA_MODE] )
1835{
1836  uiModeList[0] = PLANAR_IDX;
1837  uiModeList[1] = VER_IDX;
1838  uiModeList[2] = HOR_IDX;
1839  uiModeList[3] = DC_IDX;
1840  uiModeList[4] = DM_CHROMA_IDX;
1841  assert(4<NUM_CHROMA_MODE);
1842
1843  UInt uiLumaMode = getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx );
1844
1845  for( Int i = 0; i < NUM_CHROMA_MODE - 1; i++ )
1846  {
1847    if( uiLumaMode == uiModeList[i] )
1848    {
1849      uiModeList[i] = 34; // VER+8 mode
1850      break;
1851    }
1852  }
1853}
1854
1855/** Get most probable intra modes
1856*\param   uiAbsPartIdx    partition index
1857*\param   uiIntraDirPred  pointer to the array for MPM storage
1858*\param   compID          colour component ID
1859*\param   piMode          it is set with MPM mode in case both MPM are equal. It is used to restrict RD search at encode side.
1860*\returns Number of MPM
1861*/
1862Void TComDataCU::getIntraDirPredictor( UInt uiAbsPartIdx, Int uiIntraDirPred[NUM_MOST_PROBABLE_MODES], const ComponentID compID, Int* piMode  )
1863{
1864  TComDataCU* pcCULeft, *pcCUAbove;
1865  UInt        LeftPartIdx  = MAX_UINT;
1866  UInt        AbovePartIdx = MAX_UINT;
1867  Int         iLeftIntraDir, iAboveIntraDir;
1868  const TComSPS *sps=getSlice()->getSPS();
1869  const UInt partsPerMinCU = 1<<(2*(sps->getMaxTotalCUDepth() - sps->getLog2DiffMaxMinCodingBlockSize()));
1870
1871  const ChannelType chType = toChannelType(compID);
1872  const ChromaFormat chForm = getPic()->getChromaFormat();
1873  // Get intra direction of left PU
1874  pcCULeft = getPULeft( LeftPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1875
1876  if (isChroma(compID))
1877  {
1878    LeftPartIdx = getChromasCorrespondingPULumaIdx(LeftPartIdx, chForm, partsPerMinCU);
1879  }
1880  iLeftIntraDir  = pcCULeft ? ( pcCULeft->isIntra( LeftPartIdx ) ? pcCULeft->getIntraDir( chType, LeftPartIdx ) : DC_IDX ) : DC_IDX;
1881#if NH_3D_DMM
1882  mapDmmToIntraDir( iLeftIntraDir );
1883#endif
1884
1885  // Get intra direction of above PU
1886  pcCUAbove = getPUAbove( AbovePartIdx, m_absZIdxInCtu + uiAbsPartIdx, true, true );
1887
1888  if (isChroma(compID))
1889  {
1890    AbovePartIdx = getChromasCorrespondingPULumaIdx(AbovePartIdx, chForm, partsPerMinCU);
1891  }
1892  iAboveIntraDir = pcCUAbove ? ( pcCUAbove->isIntra( AbovePartIdx ) ? pcCUAbove->getIntraDir( chType, AbovePartIdx ) : DC_IDX ) : DC_IDX;
1893#if NH_3D_DMM
1894  mapDmmToIntraDir( iAboveIntraDir );
1895#endif
1896
1897
1898  if (isChroma(chType))
1899  {
1900    if (iLeftIntraDir  == DM_CHROMA_IDX)
1901    {
1902      iLeftIntraDir  = pcCULeft-> getIntraDir( CHANNEL_TYPE_LUMA, LeftPartIdx  );
1903    }
1904    if (iAboveIntraDir == DM_CHROMA_IDX)
1905    {
1906      iAboveIntraDir = pcCUAbove->getIntraDir( CHANNEL_TYPE_LUMA, AbovePartIdx );
1907    }
1908  }
1909
1910  assert (2<NUM_MOST_PROBABLE_MODES);
1911  if(iLeftIntraDir == iAboveIntraDir)
1912  {
1913    if( piMode )
1914    {
1915      *piMode = 1;
1916    }
1917
1918    if (iLeftIntraDir > 1) // angular modes
1919    {
1920      uiIntraDirPred[0] = iLeftIntraDir;
1921      uiIntraDirPred[1] = ((iLeftIntraDir + 29) % 32) + 2;
1922      uiIntraDirPred[2] = ((iLeftIntraDir - 1 ) % 32) + 2;
1923    }
1924    else //non-angular
1925    {
1926      uiIntraDirPred[0] = PLANAR_IDX;
1927      uiIntraDirPred[1] = DC_IDX;
1928      uiIntraDirPred[2] = VER_IDX;
1929    }
1930  }
1931  else
1932  {
1933    if( piMode )
1934    {
1935      *piMode = 2;
1936    }
1937    uiIntraDirPred[0] = iLeftIntraDir;
1938    uiIntraDirPred[1] = iAboveIntraDir;
1939
1940    if (iLeftIntraDir && iAboveIntraDir ) //both modes are non-planar
1941    {
1942      uiIntraDirPred[2] = PLANAR_IDX;
1943    }
1944    else
1945    {
1946      uiIntraDirPred[2] =  (iLeftIntraDir+iAboveIntraDir)<2? VER_IDX : DC_IDX;
1947    }
1948  }
1949  for (UInt i=0; i<NUM_MOST_PROBABLE_MODES; i++)
1950  {
1951    assert(uiIntraDirPred[i] < 35);
1952  }
1953}
1954
1955UInt TComDataCU::getCtxSplitFlag( UInt uiAbsPartIdx, UInt uiDepth )
1956{
1957  TComDataCU* pcTempCU;
1958  UInt        uiTempPartIdx;
1959  UInt        uiCtx;
1960  // Get left split flag
1961  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1962  uiCtx  = ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;
1963
1964  // Get above split flag
1965  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
1966  uiCtx += ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;
1967
1968  return uiCtx;
1969}
1970
1971UInt TComDataCU::getCtxQtCbf( TComTU &rTu, const ChannelType chType )
1972{
1973  const UInt transformDepth = rTu.GetTransformDepthRel();
1974
1975  if (isChroma(chType))
1976  {
1977    return transformDepth;
1978  }
1979  else
1980  {
1981    const UInt uiCtx = ( transformDepth == 0 ? 1 : 0 );
1982    return uiCtx;
1983  }
1984}
1985
1986UInt TComDataCU::getQuadtreeTULog2MinSizeInCU( UInt absPartIdx )
1987{
1988  UInt log2CbSize = g_aucConvertToBit[getWidth( absPartIdx )] + 2;
1989  PartSize  partSize  = getPartitionSize( absPartIdx );
1990  UInt quadtreeTUMaxDepth = isIntra( absPartIdx ) ? m_pcSlice->getSPS()->getQuadtreeTUMaxDepthIntra() : m_pcSlice->getSPS()->getQuadtreeTUMaxDepthInter();
1991  Int intraSplitFlag = ( isIntra( absPartIdx ) && partSize == SIZE_NxN ) ? 1 : 0;
1992  Int interSplitFlag = ((quadtreeTUMaxDepth == 1) && isInter( absPartIdx ) && (partSize != SIZE_2Nx2N) );
1993
1994  UInt log2MinTUSizeInCU = 0;
1995  if (log2CbSize < (m_pcSlice->getSPS()->getQuadtreeTULog2MinSize() + quadtreeTUMaxDepth - 1 + interSplitFlag + intraSplitFlag) )
1996  {
1997    // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is < QuadtreeTULog2MinSize
1998    log2MinTUSizeInCU = m_pcSlice->getSPS()->getQuadtreeTULog2MinSize();
1999  }
2000  else
2001  {
2002    // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is still >= QuadtreeTULog2MinSize
2003    log2MinTUSizeInCU = log2CbSize - ( quadtreeTUMaxDepth - 1 + interSplitFlag + intraSplitFlag); // stop when trafoDepth == hierarchy_depth = splitFlag
2004    if ( log2MinTUSizeInCU > m_pcSlice->getSPS()->getQuadtreeTULog2MaxSize())
2005    {
2006      // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is still > QuadtreeTULog2MaxSize
2007      log2MinTUSizeInCU = m_pcSlice->getSPS()->getQuadtreeTULog2MaxSize();
2008    }
2009  }
2010  return log2MinTUSizeInCU;
2011}
2012
2013UInt TComDataCU::getCtxSkipFlag( UInt uiAbsPartIdx )
2014{
2015  TComDataCU* pcTempCU;
2016  UInt        uiTempPartIdx;
2017  UInt        uiCtx = 0;
2018
2019  // Get BCBP of left PU
2020  pcTempCU = getPULeft( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
2021  uiCtx    = ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;
2022
2023  // Get BCBP of above PU
2024  pcTempCU = getPUAbove( uiTempPartIdx, m_absZIdxInCtu + uiAbsPartIdx );
2025  uiCtx   += ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;
2026
2027  return uiCtx;
2028}
2029#if H_3D_ARP
2030UInt TComDataCU::getCTXARPWFlag( UInt uiAbsPartIdx )
2031{
2032  TComDataCU* pcTempCU;
2033  UInt        uiTempPartIdx;
2034  UInt        uiCtx = 0;
2035 
2036  pcTempCU = getPULeft( uiTempPartIdx, m_uiAbsIdxInLCU + uiAbsPartIdx );
2037  uiCtx    = ( pcTempCU ) ? ((pcTempCU->getARPW( uiTempPartIdx )==0)?0:1) : 0;
2038    return uiCtx;
2039}
2040#endif
2041#if H_3D_DBBP
2042Pel* TComDataCU::getVirtualDepthBlock(UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt& uiDepthStride)
2043{
2044  // get coded and reconstructed depth view
2045  TComPicYuv* depthPicYuv = NULL;
2046  Pel* pDepthPels = NULL;
2047 
2048  // DBBP is a texture coding tool
2049  if( getSlice()->getIsDepth() )
2050  {
2051    return NULL;
2052  } 
2053#if H_3D_FCO
2054  TComPic* depthPic = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
2055 
2056  if( depthPic && depthPic->getPicYuvRec() != NULL && depthPic->getIsDepth() )  // depth first
2057  {
2058    depthPicYuv = depthPic->getPicYuvRec();
2059    depthPicYuv->extendPicBorder();
2060   
2061    // get collocated depth block for current CU
2062    uiDepthStride = depthPicYuv->getStride();
2063    pDepthPels    = depthPicYuv->getLumaAddr( getAddr(), uiAbsPartIdx );
2064  }
2065  else  // texture first
2066#else
2067  {
2068    DisInfo DvInfo = getDvInfo(uiAbsPartIdx);
2069   
2070    TComPic* baseDepthPic = getSlice()->getIvPic (true, DvInfo.m_aVIdxCan);
2071   
2072    if( baseDepthPic == NULL || baseDepthPic->getPicYuvRec() == NULL )
2073    {
2074      return NULL;
2075    }
2076   
2077    depthPicYuv   = baseDepthPic->getPicYuvRec();
2078    depthPicYuv->extendPicBorder();
2079    uiDepthStride = depthPicYuv->getStride();
2080   
2081    Int iBlkX = ( getAddr() % baseDepthPic->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ getZorderIdxInCU()+uiAbsPartIdx ] ];
2082    Int iBlkY = ( getAddr() / baseDepthPic->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ getZorderIdxInCU()+uiAbsPartIdx ] ];
2083   
2084    Int iPictureWidth  = depthPicYuv->getWidth();
2085    Int iPictureHeight = depthPicYuv->getHeight();
2086   
2087   
2088    Bool depthRefineFlag = false;
2089#if H_3D_NBDV_REF
2090    depthRefineFlag = m_pcSlice->getDepthRefinementFlag(  );
2091#endif // H_3D_NBDV_REF
2092   
2093    TComMv cDv = depthRefineFlag ? DvInfo.m_acDoNBDV : DvInfo.m_acNBDV;
2094    if( depthRefineFlag )
2095    {
2096      cDv.setVer(0);
2097    }
2098   
2099    Int depthPosX = Clip3(0,   iPictureWidth - 1,  iBlkX + ((cDv.getHor()+2)>>2));
2100    Int depthPosY = Clip3(0,   iPictureHeight - 1, iBlkY + ((cDv.getVer()+2)>>2));
2101   
2102    pDepthPels = depthPicYuv->getLumaAddr() + depthPosX + depthPosY * uiDepthStride;
2103  }
2104#endif
2105 
2106  AOF( depthPicYuv != NULL );
2107  AOF( pDepthPels != NULL );
2108  AOF( uiDepthStride != 0 );
2109 
2110  return pDepthPels;
2111}
2112#endif
2113
2114#if H_3D_DBBP
2115Void TComDataCU::setDBBPFlagSubParts ( Bool bDBBPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2116{
2117  setSubPart( bDBBPFlag, m_pbDBBPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
2118}
2119#endif
2120
2121
2122UInt TComDataCU::getCtxInterDir( UInt uiAbsPartIdx )
2123{
2124  return getDepth( uiAbsPartIdx );
2125}
2126
2127
2128UChar TComDataCU::getQtRootCbf( UInt uiIdx )
2129{
2130  const UInt numberValidComponents = getPic()->getNumberValidComponents();
2131  return getCbf( uiIdx, COMPONENT_Y, 0 )
2132          || ((numberValidComponents > COMPONENT_Cb) && getCbf( uiIdx, COMPONENT_Cb, 0 ))
2133          || ((numberValidComponents > COMPONENT_Cr) && getCbf( uiIdx, COMPONENT_Cr, 0 ));
2134}
2135
2136Void TComDataCU::setCbfSubParts( const UInt uiCbf[MAX_NUM_COMPONENT], UInt uiAbsPartIdx, UInt uiDepth )
2137{
2138  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2139  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
2140  {
2141    memset( m_puhCbf[comp] + uiAbsPartIdx, uiCbf[comp], sizeof( UChar ) * uiCurrPartNumb );
2142  }
2143}
2144
2145Void TComDataCU::setCbfSubParts( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiDepth )
2146{
2147  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2148  memset( m_puhCbf[compID] + uiAbsPartIdx, uiCbf, sizeof( UChar ) * uiCurrPartNumb );
2149}
2150
2151/** Sets a coded block flag for all sub-partitions of a partition
2152 * \param uiCbf          The value of the coded block flag to be set
2153 * \param compID
2154 * \param uiAbsPartIdx
2155 * \param uiPartIdx
2156 * \param uiDepth
2157 */
2158Void TComDataCU::setCbfSubParts ( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2159{
2160  setSubPart<UChar>( uiCbf, m_puhCbf[compID], uiAbsPartIdx, uiDepth, uiPartIdx );
2161}
2162
2163Void TComDataCU::setCbfPartRange ( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2164{
2165  memset((m_puhCbf[compID] + uiAbsPartIdx), uiCbf, (sizeof(UChar) * uiCoveredPartIdxes));
2166}
2167
2168Void TComDataCU::bitwiseOrCbfPartRange( UInt uiCbf, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2169{
2170  const UInt stopAbsPartIdx = uiAbsPartIdx + uiCoveredPartIdxes;
2171
2172  for (UInt subPartIdx = uiAbsPartIdx; subPartIdx < stopAbsPartIdx; subPartIdx++)
2173  {
2174    m_puhCbf[compID][subPartIdx] |= uiCbf;
2175  }
2176}
2177
2178Void TComDataCU::setDepthSubParts( UInt uiDepth, UInt uiAbsPartIdx )
2179{
2180  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2181  memset( m_puhDepth + uiAbsPartIdx, uiDepth, sizeof(UChar)*uiCurrPartNumb );
2182}
2183
2184Bool TComDataCU::isFirstAbsZorderIdxInDepth (UInt uiAbsPartIdx, UInt uiDepth)
2185{
2186  UInt uiPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2187  return (((m_absZIdxInCtu + uiAbsPartIdx)% uiPartNumb) == 0);
2188}
2189
2190Void TComDataCU::setPartSizeSubParts( PartSize eMode, UInt uiAbsPartIdx, UInt uiDepth )
2191{
2192  assert( sizeof( *m_pePartSize) == 1 );
2193  memset( m_pePartSize + uiAbsPartIdx, eMode, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
2194}
2195
2196Void TComDataCU::setCUTransquantBypassSubParts( Bool flag, UInt uiAbsPartIdx, UInt uiDepth )
2197{
2198  memset( m_CUTransquantBypass + uiAbsPartIdx, flag, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
2199}
2200
2201Void TComDataCU::setSkipFlagSubParts( Bool skip, UInt absPartIdx, UInt depth )
2202{
2203  assert( sizeof( *m_skipFlag) == 1 );
2204  memset( m_skipFlag + absPartIdx, skip, m_pcPic->getNumPartitionsInCtu() >> ( 2 * depth ) );
2205}
2206
2207#if H_3D
2208Void TComDataCU::setDISFlagSubParts( Bool bDIS, UInt absPartIdx, UInt depth )
2209{
2210    assert( sizeof( *m_bDISFlag) == 1 );
2211    memset( m_bDISFlag + absPartIdx, bDIS, m_pcPic->getNumPartInCU() >> ( 2 * depth ) );
2212}
2213
2214Void TComDataCU::setDISTypeSubParts(UInt uiDISType, UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth )
2215{
2216    setSubPartT( uiDISType, m_uiDISType, uiAbsPartIdx, uiDepth, uiPUIdx );
2217}
2218#endif
2219
2220Void TComDataCU::setPredModeSubParts( PredMode eMode, UInt uiAbsPartIdx, UInt uiDepth )
2221{
2222  assert( sizeof( *m_pePredMode) == 1 );
2223  memset( m_pePredMode + uiAbsPartIdx, eMode, m_pcPic->getNumPartitionsInCtu() >> ( 2 * uiDepth ) );
2224}
2225
2226Void TComDataCU::setChromaQpAdjSubParts( UChar val, Int absPartIdx, Int depth )
2227{
2228  assert( sizeof(*m_ChromaQpAdj) == 1 );
2229  memset( m_ChromaQpAdj + absPartIdx, val, m_pcPic->getNumPartitionsInCtu() >> ( 2 * depth ) );
2230}
2231
2232Void TComDataCU::setQPSubCUs( Int qp, UInt absPartIdx, UInt depth, Bool &foundNonZeroCbf )
2233{
2234  UInt currPartNumb = m_pcPic->getNumPartitionsInCtu() >> (depth << 1);
2235  UInt currPartNumQ = currPartNumb >> 2;
2236  const UInt numValidComp = m_pcPic->getNumberValidComponents();
2237
2238  if(!foundNonZeroCbf)
2239  {
2240    if(getDepth(absPartIdx) > depth)
2241    {
2242      for ( UInt partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++ )
2243      {
2244        setQPSubCUs( qp, absPartIdx+partUnitIdx*currPartNumQ, depth+1, foundNonZeroCbf );
2245      }
2246    }
2247    else
2248    {
2249      if(getCbf( absPartIdx, COMPONENT_Y ) || (numValidComp>COMPONENT_Cb && getCbf( absPartIdx, COMPONENT_Cb )) || (numValidComp>COMPONENT_Cr && getCbf( absPartIdx, COMPONENT_Cr) ) )
2250      {
2251        foundNonZeroCbf = true;
2252      }
2253      else
2254      {
2255        setQPSubParts(qp, absPartIdx, depth);
2256      }
2257    }
2258  }
2259}
2260
2261Void TComDataCU::setQPSubParts( Int qp, UInt uiAbsPartIdx, UInt uiDepth )
2262{
2263  const UInt numPart = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2264  memset(m_phQP+uiAbsPartIdx, qp, numPart);
2265}
2266
2267Void TComDataCU::setIntraDirSubParts( const ChannelType channelType, const UInt dir, const UInt absPartIdx, const UInt depth )
2268{
2269  UInt numPart = m_pcPic->getNumPartitionsInCtu() >> (depth << 1);
2270  memset( m_puhIntraDir[channelType] + absPartIdx, dir,sizeof(UChar)*numPart );
2271}
2272
2273template<typename T>
2274Void TComDataCU::setSubPart( T uiParameter, T* puhBaseCtu, UInt uiCUAddr, UInt uiCUDepth, UInt uiPUIdx )
2275{
2276  assert( sizeof(T) == 1 ); // Using memset() works only for types of size 1
2277
2278  UInt uiCurrPartNumQ = (m_pcPic->getNumPartitionsInCtu() >> (2 * uiCUDepth)) >> 2;
2279  switch ( m_pePartSize[ uiCUAddr ] )
2280  {
2281    case SIZE_2Nx2N:
2282      memset( puhBaseCtu + uiCUAddr, uiParameter, 4 * uiCurrPartNumQ );
2283      break;
2284    case SIZE_2NxN:
2285      memset( puhBaseCtu + uiCUAddr, uiParameter, 2 * uiCurrPartNumQ );
2286      break;
2287    case SIZE_Nx2N:
2288      memset( puhBaseCtu + uiCUAddr, uiParameter, uiCurrPartNumQ );
2289      memset( puhBaseCtu + uiCUAddr + 2 * uiCurrPartNumQ, uiParameter, uiCurrPartNumQ );
2290      break;
2291    case SIZE_NxN:
2292      memset( puhBaseCtu + uiCUAddr, uiParameter, uiCurrPartNumQ );
2293      break;
2294    case SIZE_2NxnU:
2295      if ( uiPUIdx == 0 )
2296      {
2297        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );
2298        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );
2299      }
2300      else if ( uiPUIdx == 1 )
2301      {
2302        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );
2303        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ, uiParameter, ((uiCurrPartNumQ >> 1) + (uiCurrPartNumQ << 1)) );
2304      }
2305      else
2306      {
2307        assert(0);
2308      }
2309      break;
2310    case SIZE_2NxnD:
2311      if ( uiPUIdx == 0 )
2312      {
2313        memset( puhBaseCtu + uiCUAddr, uiParameter, ((uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1)) );
2314        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );
2315      }
2316      else if ( uiPUIdx == 1 )
2317      {
2318        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );
2319        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );
2320      }
2321      else
2322      {
2323        assert(0);
2324      }
2325      break;
2326    case SIZE_nLx2N:
2327      if ( uiPUIdx == 0 )
2328      {
2329        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
2330        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2331        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) );
2332        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2333      }
2334      else if ( uiPUIdx == 1 )
2335      {
2336        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
2337        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2338        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) );
2339        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2340      }
2341      else
2342      {
2343        assert(0);
2344      }
2345      break;
2346    case SIZE_nRx2N:
2347      if ( uiPUIdx == 0 )
2348      {
2349        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2350        memset( puhBaseCtu + uiCUAddr + uiCurrPartNumQ + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2351        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );
2352        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2353      }
2354      else if ( uiPUIdx == 1 )
2355      {
2356        memset( puhBaseCtu + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
2357        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2358        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) );
2359        memset( puhBaseCtu + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );
2360      }
2361      else
2362      {
2363        assert(0);
2364      }
2365      break;
2366    default:
2367      assert( 0 );
2368      break;
2369  }
2370}
2371
2372#if NH_3D_SDC_INTRA
2373Void TComDataCU::setSDCFlagSubParts ( Bool bSDCFlag, UInt absPartIdx, UInt depth )
2374{
2375  assert( sizeof( *m_pbSDCFlag) == 1 );
2376  memset( m_pbSDCFlag + absPartIdx, bSDCFlag, m_pcPic->getNumPartitionsInCtu() >> ( 2 * depth ) );
2377}
2378
2379Bool TComDataCU::getSDCAvailable( UInt uiAbsPartIdx )
2380{
2381  if( getSlice()->getIsDepth() && isIntra(uiAbsPartIdx) && getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N )
2382  {
2383    UInt lumaPredMode = getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx );
2384    if( lumaPredMode < NUM_INTRA_MODE ) { return true; }
2385#if NH_3D_DMM
2386    if( isDmmMode( lumaPredMode )     ) { return true; }
2387#endif
2388  }
2389  return false;
2390}
2391#endif
2392
2393Void TComDataCU::setMergeFlagSubParts ( Bool bMergeFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2394{
2395  setSubPart( bMergeFlag, m_pbMergeFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
2396}
2397
2398Void TComDataCU::setMergeIndexSubParts ( UInt uiMergeIndex, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2399{
2400  setSubPart<UChar>( uiMergeIndex, m_puhMergeIndex, uiAbsPartIdx, uiDepth, uiPartIdx );
2401}
2402
2403#if H_3D_SPIVMP
2404Void TComDataCU::setSPIVMPFlagSubParts( Bool bSPIVMPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2405{
2406  setSubPart<Bool>( bSPIVMPFlag, m_pbSPIVMPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
2407}
2408#endif
2409
2410#if H_3D_VSP
2411Void TComDataCU::setVSPFlagSubParts( Char iVSPFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2412{
2413  setSubPart<Char>( iVSPFlag, m_piVSPFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
2414}
2415#if H_3D_VSP
2416template<typename T>
2417Void TComDataCU::setSubPartT( T uiParameter, T* puhBaseLCU, UInt uiCUAddr, UInt uiCUDepth, UInt uiPUIdx )
2418{
2419  UInt uiCurrPartNumQ = (m_pcPic->getNumPartInCU() >> (2 * uiCUDepth)) >> 2;
2420  switch ( m_pePartSize[ uiCUAddr ] )
2421  {
2422  case SIZE_2Nx2N:
2423    for (UInt ui = 0; ui < 4 * uiCurrPartNumQ; ui++)
2424      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2425
2426    break;
2427  case SIZE_2NxN:
2428    for (UInt ui = 0; ui < 2 * uiCurrPartNumQ; ui++)
2429      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2430    break;
2431  case SIZE_Nx2N:
2432    for (UInt ui = 0; ui < uiCurrPartNumQ; ui++)
2433      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2434    for (UInt ui = 0; ui < uiCurrPartNumQ; ui++)
2435      puhBaseLCU[uiCUAddr + 2 * uiCurrPartNumQ + ui] = uiParameter;
2436    break;
2437  case SIZE_NxN:
2438    for (UInt ui = 0; ui < uiCurrPartNumQ; ui++)
2439      puhBaseLCU[uiCUAddr + ui] = uiParameter;
2440    break;
2441  case SIZE_2NxnU:
2442    if ( uiPUIdx == 0 )
2443    {
2444      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2445        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2446      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2447        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + ui] = uiParameter;
2448
2449    }
2450    else if ( uiPUIdx == 1 )
2451    {
2452      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2453        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2454      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1) + (uiCurrPartNumQ << 1); ui++)
2455        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + ui] = uiParameter;
2456
2457    }
2458    else
2459    {
2460      assert(0);
2461    }
2462    break;
2463  case SIZE_2NxnD:
2464    if ( uiPUIdx == 0 )
2465    {
2466      for (UInt ui = 0; ui < ((uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1)); ui++)
2467        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2468      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2469        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ + ui] = uiParameter;
2470
2471    }
2472    else if ( uiPUIdx == 1 )
2473    {
2474      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2475        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2476      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 1); ui++)
2477        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + ui] = uiParameter;
2478
2479    }
2480    else
2481    {
2482      assert(0);
2483    }
2484    break;
2485  case SIZE_nLx2N:
2486    if ( uiPUIdx == 0 )
2487    {
2488      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2489        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2490      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2491        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2492      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2493        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2494      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2495        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2496
2497    }
2498    else if ( uiPUIdx == 1 )
2499    {
2500      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2501        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2502      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2503        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2504      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2505        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2506      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2507        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2508
2509    }
2510    else
2511    {
2512      assert(0);
2513    }
2514    break;
2515  case SIZE_nRx2N:
2516    if ( uiPUIdx == 0 )
2517    {
2518      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2519        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2520      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2521        puhBaseLCU[uiCUAddr + uiCurrPartNumQ + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2522      for (UInt ui = 0; ui < (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)); ui++)
2523        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2524      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2525        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2526
2527    }
2528    else if ( uiPUIdx == 1 )
2529    {
2530      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2531        puhBaseLCU[uiCUAddr + ui] = uiParameter;
2532      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2533        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2534      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2535        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + ui] = uiParameter;
2536      for (UInt ui = 0; ui < (uiCurrPartNumQ >> 2); ui++)
2537        puhBaseLCU[uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1) + ui] = uiParameter;
2538
2539    }
2540    else
2541    {
2542      assert(0);
2543    }
2544    break;
2545  default:
2546    assert( 0 );
2547  }
2548
2549}
2550#endif
2551#endif
2552
2553Void TComDataCU::setInterDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2554{
2555  setSubPart<UChar>( uiDir, m_puhInterDir, uiAbsPartIdx, uiDepth, uiPartIdx );
2556}
2557
2558Void TComDataCU::setMVPIdxSubParts( Int iMVPIdx, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2559{
2560  setSubPart<Char>( iMVPIdx, m_apiMVPIdx[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2561}
2562
2563Void TComDataCU::setMVPNumSubParts( Int iMVPNum, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2564{
2565  setSubPart<Char>( iMVPNum, m_apiMVPNum[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2566}
2567
2568
2569Void TComDataCU::setTrIdxSubParts( UInt uiTrIdx, UInt uiAbsPartIdx, UInt uiDepth )
2570{
2571  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2572
2573  memset( m_puhTrIdx + uiAbsPartIdx, uiTrIdx, sizeof(UChar)*uiCurrPartNumb );
2574}
2575
2576Void TComDataCU::setTransformSkipSubParts( const UInt useTransformSkip[MAX_NUM_COMPONENT], UInt uiAbsPartIdx, UInt uiDepth )
2577{
2578  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2579
2580  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
2581  {
2582    memset( m_puhTransformSkip[i] + uiAbsPartIdx, useTransformSkip[i], sizeof( UChar ) * uiCurrPartNumb );
2583  }
2584}
2585
2586Void TComDataCU::setTransformSkipSubParts( UInt useTransformSkip, ComponentID compID, UInt uiAbsPartIdx, UInt uiDepth)
2587{
2588  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2589
2590  memset( m_puhTransformSkip[compID] + uiAbsPartIdx, useTransformSkip, sizeof( UChar ) * uiCurrPartNumb );
2591}
2592
2593Void TComDataCU::setTransformSkipPartRange ( UInt useTransformSkip, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2594{
2595  memset((m_puhTransformSkip[compID] + uiAbsPartIdx), useTransformSkip, (sizeof(UChar) * uiCoveredPartIdxes));
2596}
2597
2598Void TComDataCU::setCrossComponentPredictionAlphaPartRange( Char alphaValue, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2599{
2600  memset((m_crossComponentPredictionAlpha[compID] + uiAbsPartIdx), alphaValue, (sizeof(Char) * uiCoveredPartIdxes));
2601}
2602
2603Void TComDataCU::setExplicitRdpcmModePartRange ( UInt rdpcmMode, ComponentID compID, UInt uiAbsPartIdx, UInt uiCoveredPartIdxes )
2604{
2605  memset((m_explicitRdpcmMode[compID] + uiAbsPartIdx), rdpcmMode, (sizeof(UChar) * uiCoveredPartIdxes));
2606}
2607
2608Void TComDataCU::setSizeSubParts( UInt uiWidth, UInt uiHeight, UInt uiAbsPartIdx, UInt uiDepth )
2609{
2610  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
2611
2612  memset( m_puhWidth  + uiAbsPartIdx, uiWidth,  sizeof(UChar)*uiCurrPartNumb );
2613  memset( m_puhHeight + uiAbsPartIdx, uiHeight, sizeof(UChar)*uiCurrPartNumb );
2614}
2615
2616UChar TComDataCU::getNumPartitions(const UInt uiAbsPartIdx)
2617{
2618  UChar iNumPart = 0;
2619
2620  switch ( m_pePartSize[uiAbsPartIdx] )
2621  {
2622    case SIZE_2Nx2N:    iNumPart = 1; break;
2623    case SIZE_2NxN:     iNumPart = 2; break;
2624    case SIZE_Nx2N:     iNumPart = 2; break;
2625    case SIZE_NxN:      iNumPart = 4; break;
2626    case SIZE_2NxnU:    iNumPart = 2; break;
2627    case SIZE_2NxnD:    iNumPart = 2; break;
2628    case SIZE_nLx2N:    iNumPart = 2; break;
2629    case SIZE_nRx2N:    iNumPart = 2; break;
2630    default:            assert (0);   break;
2631  }
2632
2633  return  iNumPart;
2634}
2635
2636// This is for use by a leaf/sub CU object only, with no additional AbsPartIdx
2637#if H_3D_IC
2638Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight, UInt uiAbsPartIdx, Bool bLCU)
2639{
2640  UInt uiNumPartition  = bLCU ? (getWidth(uiAbsPartIdx)*getHeight(uiAbsPartIdx) >> 4) : m_uiNumPartition;
2641  UInt  uiTmpAbsPartIdx  = bLCU ? uiAbsPartIdx : 0;
2642
2643  switch ( m_pePartSize[uiTmpAbsPartIdx] )
2644  {
2645  case SIZE_2NxN:
2646    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 1;
2647    break;
2648  case SIZE_Nx2N:
2649    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 2;
2650    break;
2651  case SIZE_NxN:
2652    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiNumPartition >> 2 ) * uiPartIdx;
2653    break;
2654  case SIZE_2NxnU:
2655    riWidth     = getWidth( uiTmpAbsPartIdx );
2656    riHeight    = ( uiPartIdx == 0 ) ?  getHeight( uiTmpAbsPartIdx ) >> 2 : ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 );
2657    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 3;
2658    break;
2659  case SIZE_2NxnD:
2660    riWidth     = getWidth( uiTmpAbsPartIdx );
2661    riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 ) : getHeight( uiTmpAbsPartIdx ) >> 2;
2662    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 1) + (uiNumPartition >> 3);
2663    break;
2664  case SIZE_nLx2N:
2665    riWidth     = ( uiPartIdx == 0 ) ? getWidth( uiTmpAbsPartIdx ) >> 2 : ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 );
2666    riHeight    = getHeight( uiTmpAbsPartIdx );
2667    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 4;
2668    break;
2669  case SIZE_nRx2N:
2670    riWidth     = ( uiPartIdx == 0 ) ? ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 ) : getWidth( uiTmpAbsPartIdx ) >> 2;
2671    riHeight    = getHeight( uiTmpAbsPartIdx );
2672    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 2) + (uiNumPartition >> 4);
2673    break;
2674  default:
2675    assert ( m_pePartSize[uiTmpAbsPartIdx] == SIZE_2Nx2N ); 
2676    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = 0;
2677    break;
2678  }
2679}
2680#else
2681
2682Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight )
2683{
2684  switch ( m_pePartSize[0] )
2685  {
2686    case SIZE_2NxN:
2687      riWidth = getWidth(0);      riHeight = getHeight(0) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2688      break;
2689    case SIZE_Nx2N:
2690      riWidth = getWidth(0) >> 1; riHeight = getHeight(0);      ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2;
2691      break;
2692    case SIZE_NxN:
2693      riWidth = getWidth(0) >> 1; riHeight = getHeight(0) >> 1; ruiPartAddr = ( m_uiNumPartition >> 2 ) * uiPartIdx;
2694      break;
2695    case SIZE_2NxnU:
2696      riWidth     = getWidth(0);
2697      riHeight    = ( uiPartIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
2698      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 3;
2699      break;
2700    case SIZE_2NxnD:
2701      riWidth     = getWidth(0);
2702      riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
2703      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 3);
2704      break;
2705    case SIZE_nLx2N:
2706      riWidth     = ( uiPartIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
2707      riHeight    = getHeight(0);
2708      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 4;
2709      break;
2710    case SIZE_nRx2N:
2711      riWidth     = ( uiPartIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
2712      riHeight    = getHeight(0);
2713      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2714      break;
2715    default:
2716      assert ( m_pePartSize[0] == SIZE_2Nx2N );
2717      riWidth = getWidth(0);      riHeight = getHeight(0);      ruiPartAddr = 0;
2718      break;
2719  }
2720}
2721#endif
2722
2723
2724Void TComDataCU::getMvField ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, TComMvField& rcMvField )
2725{
2726  if ( pcCU == NULL )  // OUT OF BOUNDARY
2727  {
2728    TComMv  cZeroMv;
2729    rcMvField.setMvField( cZeroMv, NOT_VALID );
2730    return;
2731  }
2732
2733  TComCUMvField*  pcCUMvField = pcCU->getCUMvField( eRefPicList );
2734  rcMvField.setMvField( pcCUMvField->getMv( uiAbsPartIdx ), pcCUMvField->getRefIdx( uiAbsPartIdx ) );
2735}
2736
2737Void TComDataCU::deriveLeftRightTopIdxGeneral ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT )
2738{
2739  ruiPartIdxLT = m_absZIdxInCtu + uiAbsPartIdx;
2740  UInt uiPUWidth = 0;
2741
2742  switch ( m_pePartSize[uiAbsPartIdx] )
2743  {
2744    case SIZE_2Nx2N: uiPUWidth = m_puhWidth[uiAbsPartIdx];  break;
2745    case SIZE_2NxN:  uiPUWidth = m_puhWidth[uiAbsPartIdx];   break;
2746    case SIZE_Nx2N:  uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1;  break;
2747    case SIZE_NxN:   uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1; break;
2748    case SIZE_2NxnU:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2749    case SIZE_2NxnD:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2750    case SIZE_nLx2N:
2751      if ( uiPartIdx == 0 )
2752      {
2753        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2;
2754      }
2755      else if ( uiPartIdx == 1 )
2756      {
2757        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2);
2758      }
2759      else
2760      {
2761        assert(0);
2762      }
2763      break;
2764    case SIZE_nRx2N:
2765      if ( uiPartIdx == 0 )
2766      {
2767        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2);
2768      }
2769      else if ( uiPartIdx == 1 )
2770      {
2771        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2;
2772      }
2773      else
2774      {
2775        assert(0);
2776      }
2777      break;
2778    default:
2779      assert (0);
2780      break;
2781  }
2782
2783  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + uiPUWidth / m_pcPic->getMinCUWidth() - 1 ];
2784}
2785
2786Void TComDataCU::deriveLeftBottomIdxGeneral( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLB )
2787{
2788  UInt uiPUHeight = 0;
2789  switch ( m_pePartSize[uiAbsPartIdx] )
2790  {
2791    case SIZE_2Nx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];    break;
2792    case SIZE_2NxN:  uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2793    case SIZE_Nx2N:  uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2794    case SIZE_NxN:   uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2795    case SIZE_2NxnU:
2796      if ( uiPartIdx == 0 )
2797      {
2798        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;
2799      }
2800      else if ( uiPartIdx == 1 )
2801      {
2802        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);
2803      }
2804      else
2805      {
2806        assert(0);
2807      }
2808      break;
2809    case SIZE_2NxnD:
2810      if ( uiPartIdx == 0 )
2811      {
2812        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);
2813      }
2814      else if ( uiPartIdx == 1 )
2815      {
2816        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;
2817      }
2818      else
2819      {
2820        assert(0);
2821      }
2822      break;
2823    case SIZE_nLx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2824    case SIZE_nRx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2825    default:
2826      assert (0);
2827      break;
2828  }
2829
2830  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_absZIdxInCtu + uiAbsPartIdx ] + ((uiPUHeight / m_pcPic->getMinCUHeight()) - 1)*m_pcPic->getNumPartInCtuWidth()];
2831}
2832
2833Void TComDataCU::deriveLeftRightTopIdx ( UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT )
2834{
2835  ruiPartIdxLT = m_absZIdxInCtu;
2836  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + m_puhWidth[0] / m_pcPic->getMinCUWidth() - 1 ];
2837
2838  switch ( m_pePartSize[0] )
2839  {
2840    case SIZE_2Nx2N:                                                                                                                                break;
2841    case SIZE_2NxN:
2842      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1; ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2843      break;
2844    case SIZE_Nx2N:
2845      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2; ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 2;
2846      break;
2847    case SIZE_NxN:
2848      ruiPartIdxLT += ( m_uiNumPartition >> 2 ) * uiPartIdx;         ruiPartIdxRT +=  ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );
2849      break;
2850    case SIZE_2NxnU:
2851      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2852      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2853      break;
2854    case SIZE_2NxnD:
2855      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2856      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2857      break;
2858    case SIZE_nLx2N:
2859      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 4;
2860      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2861      break;
2862    case SIZE_nRx2N:
2863      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2864      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 4;
2865      break;
2866    default:
2867      assert (0);
2868      break;
2869  }
2870
2871}
2872
2873Void TComDataCU::deriveLeftBottomIdx( UInt  uiPartIdx,      UInt&      ruiPartIdxLB )
2874{
2875  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_absZIdxInCtu ] + ( ((m_puhHeight[0] / m_pcPic->getMinCUHeight())>>1) - 1)*m_pcPic->getNumPartInCtuWidth()];
2876
2877  switch ( m_pePartSize[0] )
2878  {
2879    case SIZE_2Nx2N:
2880      ruiPartIdxLB += m_uiNumPartition >> 1;
2881      break;
2882    case SIZE_2NxN:
2883      ruiPartIdxLB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2884      break;
2885    case SIZE_Nx2N:
2886      ruiPartIdxLB += ( uiPartIdx == 0 )? m_uiNumPartition >> 1 : (m_uiNumPartition >> 2)*3;
2887      break;
2888    case SIZE_NxN:
2889      ruiPartIdxLB += ( m_uiNumPartition >> 2 ) * uiPartIdx;
2890      break;
2891    case SIZE_2NxnU:
2892      ruiPartIdxLB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2893      break;
2894    case SIZE_2NxnD:
2895      ruiPartIdxLB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2896      break;
2897    case SIZE_nLx2N:
2898      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 4);
2899      break;
2900    case SIZE_nRx2N:
2901      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2902      break;
2903    default:
2904      assert (0);
2905      break;
2906  }
2907}
2908
2909/** Derive the partition index of neighbouring bottom right block
2910 * \param [in]  uiPartIdx     current partition index
2911 * \param [out] ruiPartIdxRB  partition index of neighbouring bottom right block
2912 */
2913Void TComDataCU::deriveRightBottomIdx( UInt uiPartIdx, UInt &ruiPartIdxRB )
2914{
2915  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];
2916
2917  switch ( m_pePartSize[0] )
2918  {
2919    case SIZE_2Nx2N:
2920      ruiPartIdxRB += m_uiNumPartition >> 1;
2921      break;
2922    case SIZE_2NxN:
2923      ruiPartIdxRB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2924      break;
2925    case SIZE_Nx2N:
2926      ruiPartIdxRB += ( uiPartIdx == 0 )? m_uiNumPartition >> 2 : (m_uiNumPartition >> 1);
2927      break;
2928    case SIZE_NxN:
2929      ruiPartIdxRB += ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );
2930      break;
2931    case SIZE_2NxnU:
2932      ruiPartIdxRB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2933      break;
2934    case SIZE_2NxnD:
2935      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2936      break;
2937    case SIZE_nLx2N:
2938      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4): m_uiNumPartition >> 1;
2939      break;
2940    case SIZE_nRx2N:
2941      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4) : m_uiNumPartition >> 1;
2942      break;
2943    default:
2944      assert (0);
2945      break;
2946  }
2947}
2948
2949Bool TComDataCU::hasEqualMotion( UInt uiAbsPartIdx, TComDataCU* pcCandCU, UInt uiCandAbsPartIdx )
2950{
2951  if ( getInterDir( uiAbsPartIdx ) != pcCandCU->getInterDir( uiCandAbsPartIdx ) )
2952  {
2953    return false;
2954  }
2955
2956  for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
2957  {
2958    if ( getInterDir( uiAbsPartIdx ) & ( 1 << uiRefListIdx ) )
2959    {
2960      if ( getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiAbsPartIdx )     != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiCandAbsPartIdx ) ||
2961        getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiAbsPartIdx ) != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiCandAbsPartIdx ) )
2962      {
2963        return false;
2964      }
2965    }
2966  }
2967
2968  return true;
2969}
2970
2971#if H_3D_VSP
2972
2973/** Add a VSP merging candidate
2974 * \Inputs
2975 * \param uiPUIdx: PU index within a CU
2976 * \param ucVspMergePos: Specify the VSP merge candidate position
2977 * \param mrgCandIdx: Target merge candidate index. At encoder, it is set equal to -1, such that the whole merge candidate list will be constructed.
2978 * \param pDinfo: The "disparity information" derived from neighboring blocks. Type 1 MV.
2979 * \param uiCount: The next position to add VSP merge candidate
2980 *
2981 * \Outputs
2982 * \param uiCount: The next position to add merge candidate. Will be updated if VSP is successfully added
2983 * \param abCandIsInter: abCandIsInter[iCount] tells that VSP candidate is an Inter candidate, if VSP is successfully added
2984 * \param pcMvFieldNeighbours:   Return combined motion information, then stored to a global buffer
2985 *                                    1) the "disparity vector". Type 1 MV. To be used to fetch a depth block.
2986 *                                    2) the ref index /list.    Type 2 reference picture pointer, typically for texture
2987 * \param puhInterDirNeighbours: Indicate the VSP prediction direction.
2988 * \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
2989 *
2990 * \Return
2991 *   true:  if the VSP candidate is added at the target position
2992 *   false: otherwise
2993 */
2994inline Bool TComDataCU::xAddVspCand( Int mrgCandIdx, DisInfo* pDInfo, Int& iCount)
2995{
2996  if ( m_pcSlice->getViewIndex() == 0 || !m_pcSlice->getViewSynthesisPredFlag( ) || m_pcSlice->getIsDepth() || pDInfo->m_aVIdxCan == -1)
2997  {
2998    return false;
2999  }
3000
3001  Int refViewIdx = pDInfo->m_aVIdxCan;
3002  TComPic* picDepth = getSlice()->getIvPic( true, refViewIdx );
3003
3004  if( picDepth == NULL ) // No depth reference avail
3005  {
3006    // Is this allowed to happen? When not an assertion should be added here!
3007    return false;
3008  }
3009
3010  TComMvField mvVSP[2];
3011  UChar dirVSP;
3012  Bool  refViewAvailFlag = false;
3013  UChar predFlag[2]      = {0, 0};
3014
3015  for( Int iRefListIdX = 0; iRefListIdX < 2 && !refViewAvailFlag; iRefListIdX++ )
3016  {
3017    RefPicList eRefPicListX = RefPicList( iRefListIdX );
3018    for ( Int i = 0; i < m_pcSlice->getNumRefIdx(eRefPicListX) && !refViewAvailFlag; i++ )
3019    {
3020      Int viewIdxRefInListX = m_pcSlice->getRefPic(eRefPicListX, i)->getViewIndex();
3021      if ( viewIdxRefInListX == refViewIdx )
3022      {
3023        refViewAvailFlag      = true;
3024        predFlag[iRefListIdX] = 1;
3025        mvVSP[0+iRefListIdX].setMvField( pDInfo->m_acNBDV, i );
3026#if H_3D_NBDV
3027        mvVSP[0+iRefListIdX].getMv().setIDVFlag (false);
3028#endif
3029      }
3030    }
3031  }
3032
3033  dirVSP = (predFlag[0] | (predFlag[1] << 1));
3034  m_mergCands[MRG_VSP].setCand( mvVSP, dirVSP, true, false);
3035  if ( mrgCandIdx == iCount )
3036  {
3037    return true;
3038  }
3039
3040  iCount++;
3041
3042  return false;
3043}
3044
3045#endif
3046
3047#if H_3D_IV_MERGE
3048inline Bool TComDataCU::xAddIvMRGCand( Int mrgCandIdx, Int& iCount, Int* ivCandDir, TComMv* ivCandMv, Int* ivCandRefIdx )
3049{
3050  for(Int iLoop = 0; iLoop < 2; iLoop ++ ) 
3051  {
3052    /// iLoop = 0 --> IvMCShift
3053    /// iLoop = 1 --> IvDCShift  (Derived from IvDC)
3054    if(ivCandDir[iLoop + 2])
3055    {
3056      TComMvField tmpMV[2];
3057      UChar tmpDir = ivCandDir[iLoop + 2];
3058      if( ( ivCandDir[iLoop + 2] & 1 ) == 1 )
3059      {
3060        tmpMV[0].setMvField( ivCandMv[ (iLoop<<1) + 4 ], ivCandRefIdx[ (iLoop<<1) + 4 ] ); 
3061      }
3062      if( ( ivCandDir[iLoop + 2] & 2 ) == 2 )
3063      {
3064        tmpMV[1].setMvField( ivCandMv[ (iLoop<<1) + 5 ], ivCandRefIdx[ (iLoop<<1) + 5 ] );
3065      }
3066     
3067      // Prune IvMC vs. IvMcShift
3068      Bool bRemove = false;     
3069      if( !iLoop && ivCandDir[0] > 0)
3070      {
3071        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])
3072        {
3073            bRemove                         = true;
3074        }
3075      }
3076      if(!bRemove)
3077      {
3078#if H_3D_NBDV
3079        if(iLoop) // For IvMcShift candidate
3080        {
3081          tmpMV[0].getMv().setIDVFlag (false);
3082          tmpMV[1].getMv().setIDVFlag (false);
3083        }
3084#endif
3085        m_mergCands[MRG_IVSHIFT].setCand(tmpMV, tmpDir, false, false);
3086        if( mrgCandIdx == iCount )
3087        {
3088          return true;
3089        }
3090        iCount++;
3091      }
3092      break;
3093    }
3094  }
3095  return false;
3096} 
3097
3098#endif
3099#if H_3D
3100Void TComDataCU::buildMCL(TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours
3101#if H_3D_VSP
3102  , Int* vspFlag
3103#endif
3104#if H_3D_SPIVMP
3105  , Bool* pbSPIVMPFlag
3106#endif
3107  , Int& numValidMergeCand
3108  )
3109{
3110  if (!( getSlice()->getIsDepth() || getSlice()->getViewIndex()>0))  // for only dependent texture
3111  {
3112    return;
3113  }
3114
3115  Int iCount = 0;
3116  TComMv cZeroMv;
3117
3118  // init temporal list
3119  TComMvField extMergeCandList[MRG_MAX_NUM_CANDS_MEM << 1];
3120  UChar uhInterDirNeighboursExt[MRG_MAX_NUM_CANDS_MEM];
3121  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
3122  {
3123    uhInterDirNeighboursExt[ui] = puhInterDirNeighbours[ui];
3124    extMergeCandList[ui<<1].setMvField(cZeroMv, NOT_VALID);
3125    extMergeCandList[(ui<<1)+1].setMvField(cZeroMv, NOT_VALID);
3126    vspFlag[ui] = 0;
3127  }
3128
3129  // add candidates to temporal list
3130  // insert MPI ... IvShift candidate
3131  for (Int i=0; i<=MRG_IVSHIFT; i++)
3132  {
3133    if (m_mergCands[i].m_bAvailable)
3134    {
3135      m_mergCands[i].getCand(iCount, extMergeCandList, uhInterDirNeighboursExt, vspFlag, pbSPIVMPFlag);
3136      iCount++;
3137      if (iCount >= getSlice()->getMaxNumMergeCand())
3138        break;
3139    }
3140  }
3141
3142  // insert remaining base candidates
3143  while (iCount < getSlice()->getMaxNumMergeCand() && m_baseListidc < getSlice()->getMaxNumMergeCand())
3144  {
3145    uhInterDirNeighboursExt[iCount] = puhInterDirNeighbours[m_baseListidc];
3146    extMergeCandList[iCount<<1].setMvField(pcMvFieldNeighbours[m_baseListidc<<1].getMv(), pcMvFieldNeighbours[m_baseListidc<<1].getRefIdx());
3147    if ( getSlice()->isInterB() )
3148    {
3149      extMergeCandList[(iCount<<1)+1].setMvField(pcMvFieldNeighbours[(m_baseListidc<<1)+1].getMv(), pcMvFieldNeighbours[(m_baseListidc<<1)+1].getRefIdx());
3150    }
3151    m_baseListidc++;
3152    iCount++;
3153  }
3154
3155  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ui++ )
3156  {
3157    puhInterDirNeighbours[ui] = 0;
3158    pcMvFieldNeighbours[ui<<1].setMvField(cZeroMv, NOT_VALID);
3159    pcMvFieldNeighbours[(ui<<1)+1].setMvField(cZeroMv, NOT_VALID);
3160  }
3161  // copy extMergeCandList to output
3162  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ui++ )
3163  {
3164    puhInterDirNeighbours[ui] = uhInterDirNeighboursExt[ui];
3165    pcMvFieldNeighbours[ui<<1].setMvField(extMergeCandList[ui<<1].getMv(), extMergeCandList[ui<<1].getRefIdx());
3166    if ( getSlice()->isInterB() )
3167      pcMvFieldNeighbours[(ui<<1)+1].setMvField(extMergeCandList[(ui<<1)+1].getMv(), extMergeCandList[(ui<<1)+1].getRefIdx());
3168  }
3169  numValidMergeCand = iCount;
3170  assert(iCount == getSlice()->getMaxNumMergeCand());
3171}
3172
3173/** Constructs a list of merging candidates
3174 * \param uiAbsPartIdx
3175 * \param uiPUIdx
3176 * \param uiDepth
3177 * \param pcMvFieldNeighbours
3178 * \param puhInterDirNeighbours
3179 * \param numValidMergeCand
3180 */
3181// HM 12.0 based merge candidate list construction
3182
3183Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx )
3184{
3185
3186  UInt uiAbsPartAddr = m_uiAbsIdxInLCU + uiAbsPartIdx;
3187  Bool abCandIsInter[ MRG_MAX_NUM_CANDS_MEM ];
3188  TComMv cZeroMv;
3189  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
3190  {
3191    abCandIsInter[ui] = false;
3192    pcMvFieldNeighbours[ ( ui << 1 )     ].setMvField(cZeroMv, NOT_VALID);
3193    pcMvFieldNeighbours[ ( ui << 1 ) + 1 ].setMvField(cZeroMv, NOT_VALID);
3194  }
3195  numValidMergeCand = getSlice()->getMaxNumMergeCand();
3196  // compute the location of the current PU
3197  Int xP, yP, nPSW, nPSH;
3198  this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
3199
3200  Int iCount = 0;
3201
3202  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
3203  PartSize cCurPS = getPartitionSize( uiAbsPartIdx );
3204  deriveLeftRightTopIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLT, uiPartIdxRT );
3205  deriveLeftBottomIdxGeneral  ( uiAbsPartIdx, uiPUIdx, uiPartIdxLB );
3206
3207  //left
3208  UInt uiLeftPartIdx = 0;
3209  TComDataCU* pcCULeft = 0;
3210  pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB );
3211  Bool isAvailableA1 = pcCULeft &&
3212    pcCULeft->isDiffMER(xP -1, yP+nPSH-1, xP, yP) &&
3213    !( uiPUIdx == 1 && (cCurPS == SIZE_Nx2N || cCurPS == SIZE_nLx2N || cCurPS == SIZE_nRx2N) ) &&
3214    !pcCULeft->isIntra( uiLeftPartIdx ) ;
3215  if ( isAvailableA1 )
3216  {
3217    m_bAvailableFlagA1 = 1;
3218    abCandIsInter[iCount] = true;
3219    // get Inter Dir
3220    puhInterDirNeighbours[iCount] = pcCULeft->getInterDir( uiLeftPartIdx );
3221    // get Mv from Left
3222    pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3223    if ( getSlice()->isInterB() )
3224    {
3225      pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3226    }
3227
3228    iCount ++;
3229  }
3230 
3231  // early termination
3232  if (iCount == getSlice()->getMaxNumMergeCand()) 
3233  {
3234    return;
3235  }
3236  // above
3237  UInt uiAbovePartIdx = 0;
3238  TComDataCU* pcCUAbove = 0;
3239  pcCUAbove = getPUAbove( uiAbovePartIdx, uiPartIdxRT );
3240  Bool isAvailableB1 = pcCUAbove &&
3241  pcCUAbove->isDiffMER(xP+nPSW-1, yP-1, xP, yP) &&
3242  !( uiPUIdx == 1 && (cCurPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD) ) &&
3243  !pcCUAbove->isIntra( uiAbovePartIdx );
3244  if ( isAvailableB1 && (!isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
3245  {
3246    m_bAvailableFlagB1 = 1;
3247    abCandIsInter[iCount] = true;
3248    // get Inter Dir
3249    puhInterDirNeighbours[iCount] = pcCUAbove->getInterDir( uiAbovePartIdx );
3250    // get Mv from Left
3251    pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3252    if ( getSlice()->isInterB() )
3253    {
3254      pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3255    }
3256    if ( mrgCandIdx == iCount )
3257    {
3258      return;
3259    }
3260    iCount ++;
3261  }
3262  // early termination
3263  if (iCount == getSlice()->getMaxNumMergeCand()) 
3264  {
3265    return;
3266  }
3267
3268  // above right
3269  UInt uiAboveRightPartIdx = 0;
3270  TComDataCU* pcCUAboveRight = 0;
3271  pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT );
3272  Bool isAvailableB0 = pcCUAboveRight &&
3273  pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP) &&
3274  !pcCUAboveRight->isIntra( uiAboveRightPartIdx );
3275  if ( isAvailableB0 && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
3276  {
3277    m_bAvailableFlagB0 = 1;
3278    abCandIsInter[iCount] = true;
3279    // get Inter Dir
3280    puhInterDirNeighbours[iCount] = pcCUAboveRight->getInterDir( uiAboveRightPartIdx );
3281    // get Mv from Left
3282    pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3283    if ( getSlice()->isInterB() )
3284    {
3285      pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3286    }
3287    if ( mrgCandIdx == iCount )
3288    {
3289      return;
3290    }
3291    iCount ++;
3292  }
3293  // early termination
3294  if (iCount == getSlice()->getMaxNumMergeCand()) 
3295  {
3296    return;
3297  }
3298
3299  //left bottom
3300  UInt uiLeftBottomPartIdx = 0;
3301  TComDataCU* pcCULeftBottom = 0;
3302  pcCULeftBottom = this->getPUBelowLeft( uiLeftBottomPartIdx, uiPartIdxLB );
3303  Bool isAvailableA0 = pcCULeftBottom &&
3304  pcCULeftBottom->isDiffMER(xP-1, yP+nPSH, xP, yP) &&
3305  !pcCULeftBottom->isIntra( uiLeftBottomPartIdx ) ;
3306  if ( isAvailableA0 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCULeftBottom, uiLeftBottomPartIdx ) ) )
3307  {
3308    m_bAvailableFlagA0 = 1;
3309    abCandIsInter[iCount] = true;
3310    // get Inter Dir
3311    puhInterDirNeighbours[iCount] = pcCULeftBottom->getInterDir( uiLeftBottomPartIdx );
3312    // get Mv from Left
3313    pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3314    if ( getSlice()->isInterB() )
3315    {
3316      pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3317    }
3318    if ( mrgCandIdx == iCount )
3319    {
3320      return;
3321    }
3322    iCount ++;
3323  }
3324  // early termination
3325  if (iCount == getSlice()->getMaxNumMergeCand()) 
3326  {
3327    return;
3328  }
3329  // above left
3330  if( iCount < 4 )
3331  {
3332    UInt uiAboveLeftPartIdx = 0;
3333    TComDataCU* pcCUAboveLeft = 0;
3334    pcCUAboveLeft = getPUAboveLeft( uiAboveLeftPartIdx, uiAbsPartAddr );
3335    Bool isAvailableB2 = pcCUAboveLeft &&
3336    pcCUAboveLeft->isDiffMER(xP-1, yP-1, xP, yP) &&
3337    !pcCUAboveLeft->isIntra( uiAboveLeftPartIdx );
3338    if ( isAvailableB2 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) )
3339        && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) ) )
3340    {
3341      m_bAvailableFlagB2 = 1;
3342      abCandIsInter[iCount] = true;
3343      // get Inter Dir
3344      puhInterDirNeighbours[iCount] = pcCUAboveLeft->getInterDir( uiAboveLeftPartIdx );
3345      // get Mv from Left
3346      pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3347      if ( getSlice()->isInterB() )
3348      {
3349        pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3350      }
3351      if ( mrgCandIdx == iCount )
3352      {
3353        return;
3354      }
3355      iCount ++;
3356    }
3357  }
3358  // early termination
3359  if (iCount == getSlice()->getMaxNumMergeCand()) 
3360  {
3361    return;
3362  }
3363  if ( getSlice()->getEnableTMVPFlag())
3364  {
3365    //>> MTK colocated-RightBottom
3366    UInt uiPartIdxRB;
3367
3368    deriveRightBottomIdx( uiPUIdx, uiPartIdxRB ); 
3369
3370    UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
3371    UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
3372
3373    TComMv cColMv;
3374    Int iRefIdx;
3375    Int uiLCUIdx = -1;
3376
3377    if      ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )  // image boundary check
3378    {
3379    }
3380    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
3381    {
3382    }
3383    else
3384    {
3385      if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
3386        ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
3387      {
3388        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
3389        uiLCUIdx = getAddr();
3390      }
3391      else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
3392      {
3393        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdxTmp + uiNumPartInCUWidth + 1) % m_pcPic->getNumPartInCU() ];
3394      }
3395      else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
3396      {
3397        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
3398        uiLCUIdx = getAddr() + 1;
3399      }
3400      else //is the right bottom corner of LCU                       
3401      {
3402        uiAbsPartAddr = 0;
3403      }
3404    }
3405
3406    iRefIdx = 0;
3407    Bool bExistMV = false;
3408    UInt uiPartIdxCenter;
3409    UInt uiCurLCUIdx = getAddr();
3410    Int dir = 0;
3411    UInt uiArrayAddr = iCount;
3412    xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );
3413    bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_0, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx );
3414    if( bExistMV == false )
3415    {
3416      bExistMV = xGetColMVP( REF_PIC_LIST_0, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
3417    }
3418    if( bExistMV )
3419    {
3420      dir |= 1;
3421      pcMvFieldNeighbours[ 2 * uiArrayAddr ].setMvField( cColMv, iRefIdx );
3422    }
3423
3424    if ( getSlice()->isInterB() )
3425    {
3426#if H_3D_TMVP
3427      iRefIdx = 0;
3428#endif
3429      bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_1, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx);
3430      if( bExistMV == false )
3431      {
3432        bExistMV = xGetColMVP( REF_PIC_LIST_1, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
3433      }
3434      if( bExistMV )
3435      {
3436        dir |= 2;
3437        pcMvFieldNeighbours[ 2 * uiArrayAddr + 1 ].setMvField( cColMv, iRefIdx );
3438      }
3439    }
3440
3441    if (dir != 0)
3442    {
3443      puhInterDirNeighbours[uiArrayAddr] = dir;
3444      abCandIsInter[uiArrayAddr] = true;
3445#if H_3D_NBDV
3446      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
3447      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
3448#endif
3449      if ( mrgCandIdx == iCount )
3450      {
3451        return;
3452      }
3453      iCount++;
3454    }
3455  }
3456  // early termination
3457  if (iCount == getSlice()->getMaxNumMergeCand()) 
3458  {
3459    return;
3460  }
3461  UInt uiArrayAddr = iCount;
3462  UInt uiCutoff = uiArrayAddr;
3463 
3464  if ( getSlice()->isInterB() && iCount<5)  // JCT3V-F0129 by Qualcomm
3465  {
3466    UInt uiPriorityList0[12] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3};
3467    UInt uiPriorityList1[12] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2};
3468
3469    for (Int idx=0; idx<uiCutoff*(uiCutoff-1) && uiArrayAddr!= getSlice()->getMaxNumMergeCand(); idx++)
3470    {
3471      Int i = uiPriorityList0[idx]; Int j = uiPriorityList1[idx];
3472      if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
3473      {
3474        abCandIsInter[uiArrayAddr] = true;
3475        puhInterDirNeighbours[uiArrayAddr] = 3;
3476
3477        // get Mv from cand[i] and cand[j]
3478        pcMvFieldNeighbours[uiArrayAddr << 1].setMvField(pcMvFieldNeighbours[i<<1].getMv(), pcMvFieldNeighbours[i<<1].getRefIdx());
3479        pcMvFieldNeighbours[( uiArrayAddr << 1 ) + 1].setMvField(pcMvFieldNeighbours[(j<<1)+1].getMv(), pcMvFieldNeighbours[(j<<1)+1].getRefIdx());
3480
3481        Int iRefPOCL0 = m_pcSlice->getRefPOC( REF_PIC_LIST_0, pcMvFieldNeighbours[(uiArrayAddr<<1)].getRefIdx() );
3482        Int iRefPOCL1 = m_pcSlice->getRefPOC( REF_PIC_LIST_1, pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getRefIdx() );
3483        if (iRefPOCL0 == iRefPOCL1 && pcMvFieldNeighbours[(uiArrayAddr<<1)].getMv() == pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getMv())
3484        {
3485          abCandIsInter[uiArrayAddr] = false;
3486        }
3487        else
3488        {
3489          uiArrayAddr++;
3490        }
3491      }
3492    }
3493  }
3494  // early termination
3495  if (uiArrayAddr == getSlice()->getMaxNumMergeCand()) 
3496  {
3497    return;
3498  }
3499 
3500  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);
3501  Int r = 0;
3502  Int refcnt = 0;
3503  while (uiArrayAddr < getSlice()->getMaxNumMergeCand())
3504  {
3505    abCandIsInter[uiArrayAddr] = true;
3506    puhInterDirNeighbours[uiArrayAddr] = 1;
3507    pcMvFieldNeighbours[uiArrayAddr << 1].setMvField( TComMv(0, 0), r);
3508
3509    if ( getSlice()->isInterB() )
3510    {
3511      puhInterDirNeighbours[uiArrayAddr] = 3;
3512      pcMvFieldNeighbours[(uiArrayAddr << 1) + 1].setMvField(TComMv(0, 0), r);
3513    }
3514    uiArrayAddr++;
3515    if ( refcnt == iNumRefIdx - 1 )
3516    {
3517      r = 0;
3518    }
3519    else
3520    {
3521      ++r;
3522      ++refcnt;
3523    }
3524  }
3525 
3526  numValidMergeCand = uiArrayAddr;
3527}
3528
3529
3530
3531/** Constructs a list of merging candidates
3532 * \param uiAbsPartIdx
3533 * \param uiPUIdx
3534 * \param uiDepth
3535 * \param pcMvFieldNeighbours
3536 * \param puhInterDirNeighbours
3537 * \param numValidMergeCand
3538 */
3539#if H_3D
3540Void TComDataCU::xGetInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours
3541#else
3542Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours
3543#endif
3544#if H_3D_SPIVMP
3545      , TComMvField* pcMvFieldSP, UChar* puhInterDirSP
3546#endif
3547      , Int& numValidMergeCand, Int mrgCandIdx
3548)
3549{
3550#if H_3D_IV_MERGE
3551  ////////////////////////////
3552  //////// INIT LISTS ////////
3553  ////////////////////////////
3554  TComMv cZeroMv;
3555#else
3556  Bool abCandIsInter[ MRG_MAX_NUM_CANDS ];
3557#endif
3558#if H_3D
3559  TComMvField tmpMV[2];
3560  UChar tmpDir;
3561
3562
3563  //////////////////////////////////
3564  //////// GET DISPARITIES  ////////
3565  //////////////////////////////////
3566  DisInfo cDisInfo = getDvInfo(uiAbsPartIdx);
3567  m_cDefaultDisInfo = cDisInfo;
3568
3569  if (!( getSlice()->getIsDepth() || getSlice()->getViewIndex()>0))  // current slice is not both dependent view or depth
3570  {
3571    return;
3572  }
3573#else
3574  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
3575  {
3576    abCandIsInter[ui] = false;
3577    pcMvFieldNeighbours[ ( ui << 1 )     ].setRefIdx(NOT_VALID);
3578    pcMvFieldNeighbours[ ( ui << 1 ) + 1 ].setRefIdx(NOT_VALID);
3579  }
3580#endif
3581
3582  numValidMergeCand = getSlice()->getMaxNumMergeCand();
3583#if H_3D
3584  //////////////////////////////////
3585  //////// DERIVE LOCATIONS ////////
3586  //////////////////////////////////
3587#endif
3588  // compute the location of the current PU
3589  Int xP, yP, nPSW, nPSH;
3590  this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
3591
3592  Int iCount = 0;
3593
3594  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
3595#if !H_3D
3596  PartSize cCurPS = getPartitionSize( uiAbsPartIdx );
3597#endif
3598  deriveLeftRightTopIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLT, uiPartIdxRT );
3599  deriveLeftBottomIdxGeneral  ( uiAbsPartIdx, uiPUIdx, uiPartIdxLB );
3600#if H_3D
3601  Bool bMPIFlag   = getSlice()->getMpiFlag(); 
3602  Bool bIsDepth = getSlice()->getIsDepth();
3603#endif
3604
3605#if H_3D_IC
3606  Bool bICFlag = getICFlag(uiAbsPartIdx);
3607#endif
3608#if H_3D_ARP
3609  Bool bARPFlag = getARPW(uiAbsPartIdx) > 0;
3610#endif
3611#if H_3D_DBBP
3612  Bool bDBBPFlag = getDBBPFlag(uiAbsPartIdx);
3613  assert(bDBBPFlag == getDBBPFlag(0)); 
3614#endif
3615
3616#if H_3D
3617#if H_3D_NBDV
3618  for(Int i = 0; i < MRG_MAX_NUM_CANDS_MEM; i++) 
3619  {
3620    pcMvFieldNeighbours[i<<1    ].getMv().setIDVFlag (false);
3621    pcMvFieldNeighbours[(i<<1)+1].getMv().setIDVFlag (false);
3622  }
3623#endif
3624  // Clean version for MCL construction align with WD
3625  // init mergCands list
3626  for (Int i = 0; i<MRG_IVSHIFT+1; i++)
3627  {
3628    m_mergCands[i].init();
3629  }
3630
3631  m_baseListidc = 0;
3632
3633  //left
3634  UInt uiLeftPartIdx = 0;
3635  TComDataCU* pcCULeft = 0;
3636  pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB ); 
3637
3638  if (getAvailableFlagA1())
3639  {
3640    m_mergCands[MRG_A1].setCand( &pcMvFieldNeighbours[m_baseListidc<<1], puhInterDirNeighbours[m_baseListidc]
3641#if H_3D_VSP
3642    , (pcCULeft->getVSPFlag(uiLeftPartIdx) != 0
3643#if H_3D_IC
3644      && !bICFlag
3645#endif
3646#if H_3D_ARP
3647      && !bARPFlag
3648#endif
3649#if H_3D_DBBP
3650      && !bDBBPFlag
3651#endif
3652      )
3653#endif
3654      , false
3655      ); 
3656    m_baseListidc++;
3657  }
3658
3659  // above
3660
3661  if (getAvailableFlagB1())
3662  {
3663    m_mergCands[MRG_B1].setCand( &pcMvFieldNeighbours[m_baseListidc<<1], puhInterDirNeighbours[m_baseListidc]
3664#if H_3D_VSP
3665    , false
3666#endif
3667      , false
3668      ); 
3669    m_baseListidc++;
3670  }
3671
3672  // above right
3673
3674  if (getAvailableFlagB0())
3675  {
3676    m_mergCands[MRG_B0].setCand( &pcMvFieldNeighbours[m_baseListidc<<1], puhInterDirNeighbours[m_baseListidc]
3677#if H_3D_VSP
3678    ,
3679      false
3680#endif
3681      , false
3682      ); 
3683    m_baseListidc++;
3684  }
3685
3686  // left bottom
3687
3688  if (getAvailableFlagA0())
3689  {
3690    m_mergCands[MRG_A0].setCand( &pcMvFieldNeighbours[m_baseListidc<<1], puhInterDirNeighbours[m_baseListidc]
3691#if H_3D_VSP
3692    , false
3693#endif
3694      , false
3695      ); 
3696    m_baseListidc++;
3697  }
3698
3699  // above left
3700
3701  if (getAvailableFlagB2())
3702  {
3703    m_mergCands[MRG_B2].setCand( &pcMvFieldNeighbours[m_baseListidc<<1], puhInterDirNeighbours[m_baseListidc]
3704#if H_3D_VSP
3705    , false
3706#endif
3707      , false
3708      ); 
3709    m_baseListidc++;
3710  }
3711
3712#endif
3713
3714
3715#if H_3D_IV_MERGE
3716
3717  /////////////////////////////////////////////
3718  //////// TEXTURE MERGE CANDIDATE (T) ////////
3719  /////////////////////////////////////////////
3720
3721  bMPIFlag &= (nPSW + nPSH > 12);
3722  if( bMPIFlag)
3723  {
3724    tmpMV[0].setMvField( cZeroMv, NOT_VALID );
3725    tmpMV[1].setMvField( cZeroMv, NOT_VALID );
3726    tmpDir        =  0;
3727
3728    Bool bSPIVMPFlag = false;
3729
3730    TComPic * pcTexPic = m_pcSlice->getTexturePic();
3731#if H_3D_FCO
3732    if (pcTexPic && pcTexPic->getReconMark())
3733    {
3734#endif   
3735      TComPicYuv*   pcTexRec = pcTexPic->getPicYuvRec  ();
3736      UInt          uiPartAddr;
3737      Int           iWidth, iHeight;
3738      Int           iCurrPosX, iCurrPosY;
3739
3740      this->getPartIndexAndSize( uiPUIdx, uiPartAddr, iWidth, iHeight );
3741      pcTexRec->getTopLeftSamplePos( this->getAddr(), this->getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
3742
3743      Int iPUWidth, iPUHeight, iNumPart, iNumPartLine;
3744      this->getSPPara(iWidth, iHeight, iNumPart, iNumPartLine, iPUWidth, iPUHeight);
3745
3746      for (Int i=0; i<iNumPart; i++)
3747      {
3748        puhInterDirSP[i] = 0;
3749        pcMvFieldSP[2*i].getMv().set(0, 0);
3750        pcMvFieldSP[2*i+1].getMv().set(0, 0);
3751        pcMvFieldSP[2*i].setRefIdx(-1);
3752        pcMvFieldSP[2*i+1].setRefIdx(-1);
3753      }
3754
3755      Int         iTexCUAddr;
3756      Int         iTexAbsPartIdx;
3757      TComDataCU* pcTexCU;
3758      Int iPartition = 0;
3759      Int iInterDirSaved = 0;
3760      TComMvField cMvFieldSaved[2];
3761
3762      Int iOffsetX = iPUWidth/2;;
3763      Int iOffsetY = iPUHeight/2;
3764
3765      Int         iTexPosX, iTexPosY;
3766      const TComMv cMvRounding( 1 << ( 2 - 1 ), 1 << ( 2 - 1 ) );
3767
3768      Int         iCenterPosX = iCurrPosX + ( ( iWidth /  iPUWidth ) >> 1 )  * iPUWidth + ( iPUWidth >> 1 );
3769      Int         iCenterPosY = iCurrPosY + ( ( iHeight /  iPUHeight ) >> 1 )  * iPUHeight + (iPUHeight >> 1);
3770      Int         iTexCenterCUAddr, iTexCenterAbsPartIdx;
3771
3772      if(iWidth == iPUWidth && iHeight == iPUHeight)
3773      {
3774        iCenterPosX = iCurrPosX + (iWidth >> 1);
3775        iCenterPosY = iCurrPosY + (iHeight >> 1);
3776      }
3777
3778      // derivation of center motion parameters from the collocated texture CU
3779
3780      pcTexRec->getCUAddrAndPartIdx( iCenterPosX , iCenterPosY , iTexCenterCUAddr, iTexCenterAbsPartIdx );
3781      TComDataCU* pcDefaultCU    = pcTexPic->getCU( iTexCenterCUAddr );
3782
3783      if( pcDefaultCU->getPredictionMode( iTexCenterAbsPartIdx ) != MODE_INTRA )
3784      {
3785        for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )
3786        {
3787          RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
3788
3789          TComMvField cDefaultMvField;
3790          pcDefaultCU->getMvField( pcDefaultCU, iTexCenterAbsPartIdx, eCurrRefPicList, cDefaultMvField );
3791          Int         iDefaultRefIdx     = cDefaultMvField.getRefIdx();
3792          if (iDefaultRefIdx >= 0)
3793          {
3794            Int iDefaultRefPOC = pcDefaultCU->getSlice()->getRefPOC(eCurrRefPicList, iDefaultRefIdx);
3795            for (Int iRefPicList = 0; iRefPicList < m_pcSlice->getNumRefIdx( eCurrRefPicList ); iRefPicList++)
3796            {
3797              if (iDefaultRefPOC == m_pcSlice->getRefPOC(eCurrRefPicList, iRefPicList))
3798              {
3799                bSPIVMPFlag = true;
3800                TComMv cMv = cDefaultMvField.getMv() + cMvRounding;
3801                cMv >>= 2;
3802                cMvFieldSaved[eCurrRefPicList].setMvField(cMv, iRefPicList) ;
3803                break;
3804              }
3805            }
3806          }
3807        }
3808      }
3809      if ( bSPIVMPFlag == true )
3810      {   
3811        iInterDirSaved = (cMvFieldSaved[0].getRefIdx()!=-1 ? 1: 0) + (cMvFieldSaved[1].getRefIdx()!=-1 ? 2: 0);
3812        tmpDir = iInterDirSaved;
3813        tmpMV[0] = cMvFieldSaved[0];
3814        tmpMV[1] = cMvFieldSaved[1];
3815      }
3816
3817      if ( iInterDirSaved != 0 )
3818      {
3819        for (Int i=iCurrPosY; i < iCurrPosY + iHeight; i += iPUHeight)
3820        {
3821          for (Int j = iCurrPosX; j < iCurrPosX + iWidth; j += iPUWidth)
3822          {
3823            iTexPosX     = j + iOffsetX;
3824            iTexPosY     = i + iOffsetY; 
3825            pcTexRec->getCUAddrAndPartIdx( iTexPosX, iTexPosY, iTexCUAddr, iTexAbsPartIdx );
3826            pcTexCU  = pcTexPic->getCU( iTexCUAddr );
3827
3828            if( pcTexCU && !pcTexCU->isIntra(iTexAbsPartIdx) )
3829            {
3830              for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )
3831              {
3832                RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
3833                TComMvField cTexMvField;
3834                pcTexCU->getMvField( pcTexCU, iTexAbsPartIdx, eCurrRefPicList, cTexMvField );
3835                Int iValidDepRef = getPic()->isTextRefValid( eCurrRefPicList, cTexMvField.getRefIdx() );
3836                if( (cTexMvField.getRefIdx()>=0) && ( iValidDepRef >= 0 ) )
3837                {
3838                  TComMv cMv = cTexMvField.getMv() + cMvRounding;
3839                  cMv >>=2;         
3840                  pcMvFieldSP[2*iPartition + uiCurrRefListId].setMvField(cMv, iValidDepRef);
3841                }
3842              }
3843            }
3844            puhInterDirSP[iPartition] = (pcMvFieldSP[2*iPartition].getRefIdx()!=-1 ? 1: 0) + (pcMvFieldSP[2*iPartition+1].getRefIdx()!=-1 ? 2: 0);
3845            if (puhInterDirSP[iPartition] == 0)
3846            {
3847              if (iInterDirSaved != 0)
3848              {
3849                puhInterDirSP[iPartition] = iInterDirSaved;
3850                pcMvFieldSP[2*iPartition] = cMvFieldSaved[0];
3851                pcMvFieldSP[2*iPartition + 1] = cMvFieldSaved[1];
3852              }
3853            }
3854
3855            iPartition ++;
3856          }
3857        }
3858#if H_3D
3859      }
3860#endif
3861#if H_3D_FCO
3862    }
3863#endif
3864    if( tmpDir != 0 )
3865    {
3866      Int iCnloop = 0;
3867      for(iCnloop = 0; iCnloop < 2; iCnloop ++)
3868      {
3869        if ( !m_mergCands[MRG_A1+iCnloop].m_bAvailable )  // prunning to A1, B1
3870        {
3871          continue;
3872        }
3873        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])
3874        {
3875          m_mergCands[MRG_A1+iCnloop].m_bAvailable = false;
3876          break;
3877        }     
3878      }
3879      m_mergCands[MRG_T].setCand( tmpMV, tmpDir, false, bSPIVMPFlag);
3880
3881      if ( mrgCandIdx == iCount )
3882      {
3883        return;
3884      }
3885      iCount ++;
3886    }
3887  }
3888  /////////////////////////////////////////////////////////////////
3889  //////// DERIVE IvMC, IvMCShift,IvDCShift, IvDC  Candidates /////
3890  /////////////////////////////////////////////////////////////////
3891
3892  // { IvMCL0, IvMCL1, IvDCL0, IvDCL1, IvMCL0Shift, IvMCL1Shift, IvDCL0Shift, IvDCL1Shift }; 
3893  // An enumerator would be appropriate here!
3894  TComMv ivCandMv    [8];
3895  Int    ivCandRefIdx[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
3896
3897  // { IvMC, IvDC, IvMCShift, IvDCShift }; 
3898  Int    ivCandDir   [4] = {0, 0, 0, 0};
3899
3900  Bool ivMvPredFlag   = getSlice()->getIvMvPredFlag();
3901
3902  ivMvPredFlag &= (nPSW + nPSH > 12);
3903  if ( ivMvPredFlag && cDisInfo.m_aVIdxCan!=-1)
3904  {
3905    getInterViewMergeCands(uiPUIdx, ivCandRefIdx, ivCandMv, &cDisInfo, ivCandDir , bIsDepth, pcMvFieldSP, puhInterDirSP, bICFlag );
3906  } 
3907
3908  ///////////////////////////////////////////////
3909  //////// INTER VIEW MOTION COMP(IvMC) /////////
3910  ///////////////////////////////////////////////
3911  if( getSlice()->getIsDepth() )
3912  {
3913    ivCandDir[1] = ivCandDir[2] = ivCandDir[3] = 0;
3914  }
3915
3916  if( ivCandDir[0] )
3917  {
3918    tmpMV[0].setMvField( cZeroMv, NOT_VALID );
3919    tmpMV[1].setMvField( cZeroMv, NOT_VALID );
3920
3921    if( ( ivCandDir[0] & 1 ) == 1 )
3922    {
3923      tmpMV[0].setMvField( ivCandMv[ 0 ], ivCandRefIdx[ 0 ] );
3924    }
3925    if( ( ivCandDir[0] & 2 ) == 2 )
3926    {
3927      tmpMV[1].setMvField( ivCandMv[ 1 ], ivCandRefIdx[ 1 ] );
3928    }
3929
3930    Bool bRemoveSpa = false; //pruning
3931
3932    if (!bIsDepth)
3933    {
3934      for(Int i = 0; i < 2; i ++)
3935      {
3936        if ( !m_mergCands[MRG_A1 + i].m_bAvailable ) // prunning to A1, B1
3937        {
3938          continue;
3939        }
3940        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])
3941        {
3942          m_mergCands[MRG_A1+i].m_bAvailable = false;
3943          break;
3944        }     
3945      }
3946    }
3947    if (bIsDepth)
3948    {
3949      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])
3950      {
3951        bRemoveSpa                      = true;
3952      }
3953    }
3954    if (!bRemoveSpa)
3955    {
3956      Bool spiMvpFlag = false;
3957      if(!m_pcSlice->getIsDepth())
3958      {
3959        spiMvpFlag = true;
3960      }
3961#if H_3D_DBBP
3962      spiMvpFlag &= !bDBBPFlag;
3963#endif
3964
3965      m_mergCands[MRG_IVMC].setCand( tmpMV, ivCandDir[0], false, spiMvpFlag);
3966
3967      if ( mrgCandIdx == iCount )
3968      {
3969        return;
3970      }
3971      iCount ++;
3972    }
3973  } 
3974
3975  // early termination
3976  if (iCount == getSlice()->getMaxNumMergeCand()) 
3977  {
3978    return;
3979  }
3980#endif
3981
3982#if H_3D
3983  iCount += m_mergCands[MRG_A1].m_bAvailable + m_mergCands[MRG_B1].m_bAvailable;
3984#else
3985  //left
3986  UInt uiLeftPartIdx = 0;
3987  TComDataCU* pcCULeft = 0;
3988  pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB );
3989  Bool isAvailableA1 = pcCULeft &&
3990    pcCULeft->isDiffMER(xP -1, yP+nPSH-1, xP, yP) &&
3991    !( uiPUIdx == 1 && (cCurPS == SIZE_Nx2N || cCurPS == SIZE_nLx2N || cCurPS == SIZE_nRx2N) ) &&
3992    !pcCULeft->isIntra( uiLeftPartIdx ) ;
3993  if ( isAvailableA1 )
3994  {
3995    abCandIsInter[iCount] = true;
3996    // get Inter Dir
3997    puhInterDirNeighbours[iCount] = pcCULeft->getInterDir( uiLeftPartIdx );
3998    // get Mv from Left
3999    pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4000    if ( getSlice()->isInterB() )
4001    {
4002      pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4003    }
4004
4005    if ( mrgCandIdx == iCount )
4006    {
4007      return;
4008    }
4009    iCount ++;
4010  }
4011
4012  // early termination
4013  if (iCount == getSlice()->getMaxNumMergeCand()) 
4014  {
4015    return;
4016  }
4017
4018  // above
4019  UInt uiAbovePartIdx = 0;
4020  TComDataCU* pcCUAbove = 0;
4021  pcCUAbove = getPUAbove( uiAbovePartIdx, uiPartIdxRT );
4022  Bool isAvailableB1 = pcCUAbove &&
4023    pcCUAbove->isDiffMER(xP+nPSW-1, yP-1, xP, yP) &&
4024    !( uiPUIdx == 1 && (cCurPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD) ) &&
4025    !pcCUAbove->isIntra( uiAbovePartIdx );
4026  if ( isAvailableB1 && (!isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
4027  {
4028    abCandIsInter[iCount] = true;
4029    // get Inter Dir
4030    puhInterDirNeighbours[iCount] = pcCUAbove->getInterDir( uiAbovePartIdx );
4031    // get Mv from Left
4032    pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4033    if ( getSlice()->isInterB() )
4034    {
4035      pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4036    }
4037
4038    if ( mrgCandIdx == iCount )
4039    {
4040      return;
4041    }
4042    iCount ++;
4043  }
4044  // early termination
4045  if (iCount == getSlice()->getMaxNumMergeCand()) 
4046  {
4047    return;
4048  }
4049
4050  // above right
4051  UInt uiAboveRightPartIdx = 0;
4052  TComDataCU* pcCUAboveRight = 0;
4053  pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT );
4054  Bool isAvailableB0 = pcCUAboveRight &&
4055    pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP) &&
4056    !pcCUAboveRight->isIntra( uiAboveRightPartIdx );
4057  if ( isAvailableB0 && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
4058  {
4059    abCandIsInter[iCount] = true;
4060    // get Inter Dir
4061    puhInterDirNeighbours[iCount] = pcCUAboveRight->getInterDir( uiAboveRightPartIdx );
4062    // get Mv from Left
4063    pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4064    if ( getSlice()->isInterB() )
4065    {
4066      pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4067    }
4068
4069    if ( mrgCandIdx == iCount )
4070    {
4071      return;
4072    }
4073    iCount ++;
4074  }
4075  // early termination
4076  if (iCount == getSlice()->getMaxNumMergeCand()) 
4077  {
4078    return;
4079  }
4080#endif
4081
4082
4083#if H_3D_VSP
4084  /////////////////////////////////////////////////
4085  //////// VIEW SYNTHESIS PREDICTION (VSP) ////////
4086  /////////////////////////////////////////////////
4087  if (iCount<getSlice()->getMaxNumMergeCand())
4088  {
4089    if (
4090      (!getAvailableFlagA1() || !(pcCULeft->getVSPFlag(uiLeftPartIdx) != 0)) &&
4091#if H_3D_IC
4092      !bICFlag &&
4093#endif
4094#if H_3D_ARP
4095      !bARPFlag &&
4096#endif
4097#if H_3D
4098      (nPSW + nPSH > 12) &&
4099#endif
4100#if H_3D_DBBP
4101      !bDBBPFlag &&
4102#endif
4103      xAddVspCand( mrgCandIdx, &cDisInfo, iCount ) )
4104    {
4105      return;
4106    }
4107
4108    // early termination
4109    if (iCount == getSlice()->getMaxNumMergeCand())
4110    {
4111      return;
4112    }
4113#endif
4114#if H_3D_VSP
4115  }
4116#endif
4117
4118#if H_3D
4119  iCount += m_mergCands[MRG_B0].m_bAvailable;
4120#endif
4121
4122
4123#if H_3D_IV_MERGE
4124  /////////////////////////////////////////////
4125  //////// INTER VIEW DISP COMP (IvDC) ////////
4126  /////////////////////////////////////////////
4127  if( ivCandDir[1] && iCount < getSlice()->getMaxNumMergeCand() && !getSlice()->getIsDepth() )
4128  {
4129    assert(iCount < getSlice()->getMaxNumMergeCand());
4130
4131    tmpMV[0].setMvField( cZeroMv, NOT_VALID );
4132    tmpMV[1].setMvField( cZeroMv, NOT_VALID );
4133    if( ( ivCandDir[1] & 1 ) == 1 )
4134    {
4135      tmpMV[0].setMvField( ivCandMv[ 2 ], ivCandRefIdx[ 2 ] );
4136    }
4137    if( ( ivCandDir[1] & 2 ) == 2 )
4138    {
4139      tmpMV[1].setMvField( ivCandMv[ 3 ], ivCandRefIdx[ 3 ] );
4140    }
4141
4142    Bool bRemoveSpa = false; //pruning to A1, B1
4143    for(Int i = 0; i < 2; i ++)
4144    {
4145      if ( !m_mergCands[MRG_A1+i].m_bAvailable ) 
4146      {
4147        continue;
4148      }
4149      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])
4150      {
4151        bRemoveSpa                      = true;
4152        break;
4153      }     
4154    }
4155    if(!bRemoveSpa)
4156    {
4157#if H_3D_NBDV
4158      tmpMV[0].getMv().setIDVFlag (false);
4159      tmpMV[1].getMv().setIDVFlag (false);
4160#endif
4161      m_mergCands[MRG_IVDC].setCand( tmpMV, ivCandDir[1], false, false);
4162
4163      if ( mrgCandIdx == iCount )
4164        return;
4165      iCount ++;
4166
4167      // early termination
4168      if (iCount == getSlice()->getMaxNumMergeCand()) 
4169      {
4170        return;
4171      }
4172    }
4173  } 
4174#endif // H_3D_IV_MERGE
4175
4176
4177#if H_3D
4178  iCount += m_mergCands[MRG_A0].m_bAvailable + m_mergCands[MRG_B2].m_bAvailable;
4179#else
4180  //left bottom
4181  UInt uiLeftBottomPartIdx = 0;
4182  TComDataCU* pcCULeftBottom = 0;
4183  pcCULeftBottom = this->getPUBelowLeft( uiLeftBottomPartIdx, uiPartIdxLB );
4184  Bool isAvailableA0 = pcCULeftBottom &&
4185  pcCULeftBottom->isDiffMER(xP-1, yP+nPSH, xP, yP) &&
4186  !pcCULeftBottom->isIntra( uiLeftBottomPartIdx ) ;
4187  if ( isAvailableA0 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCULeftBottom, uiLeftBottomPartIdx ) ) )
4188  {
4189    abCandIsInter[iCount] = true;
4190    // get Inter Dir
4191    puhInterDirNeighbours[iCount] = pcCULeftBottom->getInterDir( uiLeftBottomPartIdx );
4192    // get Mv from Left
4193    pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4194    if ( getSlice()->isInterB() )
4195    {
4196      pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4197    }
4198    if ( mrgCandIdx == iCount )
4199    {
4200      return;
4201    }
4202    iCount ++;
4203  }
4204  // early termination
4205  if (iCount == getSlice()->getMaxNumMergeCand()) 
4206  {
4207    return;
4208  }
4209
4210  // above left
4211  if( iCount < 4 )
4212  {
4213    UInt uiAboveLeftPartIdx = 0;
4214    TComDataCU* pcCUAboveLeft = 0;
4215    pcCUAboveLeft = getPUAboveLeft( uiAboveLeftPartIdx, uiAbsPartAddr );
4216    Bool isAvailableB2 = pcCUAboveLeft &&
4217    pcCUAboveLeft->isDiffMER(xP-1, yP-1, xP, yP) &&
4218    !pcCUAboveLeft->isIntra( uiAboveLeftPartIdx );
4219    if ( isAvailableB2 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) )
4220        && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) ) )
4221    {
4222      abCandIsInter[iCount] = true;
4223      // get Inter Dir
4224      puhInterDirNeighbours[iCount] = pcCUAboveLeft->getInterDir( uiAboveLeftPartIdx );
4225      // get Mv from Left
4226      pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4227      if ( getSlice()->isInterB() )
4228      {
4229        pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4230      }
4231      if ( mrgCandIdx == iCount )
4232      {
4233        return;
4234      }
4235      iCount ++;
4236    }
4237  }
4238  // early termination
4239  if (iCount == getSlice()->getMaxNumMergeCand()) 
4240  {
4241    return;
4242  }
4243#endif
4244
4245
4246#if H_3D_IV_MERGE
4247  ////////////////////////////////////////////////////
4248  //////// SHIFTED IV (IvMCShift + IvDCShift) ////////
4249  ////////////////////////////////////////////////////
4250  if(  ivMvPredFlag && iCount < getSlice()->getMaxNumMergeCand() && !getSlice()->getIsDepth() ) 
4251  {
4252    if(xAddIvMRGCand( mrgCandIdx,  iCount, ivCandDir, ivCandMv, ivCandRefIdx ) )
4253    {
4254      return;
4255    }
4256    //early termination
4257    if (iCount == getSlice()->getMaxNumMergeCand()) 
4258    {
4259      return;
4260    }
4261  }
4262#endif
4263#if !H_3D
4264  if ( getSlice()->getEnableTMVPFlag())
4265  {
4266    //>> MTK colocated-RightBottom
4267    UInt uiPartIdxRB;
4268
4269    deriveRightBottomIdx( uiPUIdx, uiPartIdxRB ); 
4270
4271    UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
4272    UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
4273
4274    TComMv cColMv;
4275    Int iRefIdx;
4276    Int uiLCUIdx = -1;
4277
4278    if      ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )  // image boundary check
4279    {
4280    }
4281    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
4282    {
4283    }
4284    else
4285    {
4286      if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
4287        ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
4288      {
4289        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
4290        uiLCUIdx = getAddr();
4291      }
4292      else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
4293      {
4294        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdxTmp + uiNumPartInCUWidth + 1) % m_pcPic->getNumPartInCU() ];
4295      }
4296      else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
4297      {
4298        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
4299        uiLCUIdx = getAddr() + 1;
4300      }
4301      else //is the right bottom corner of LCU                       
4302      {
4303        uiAbsPartAddr = 0;
4304      }
4305    }
4306   
4307   
4308    iRefIdx = 0;
4309    Bool bExistMV = false;
4310    UInt uiPartIdxCenter;
4311    UInt uiCurLCUIdx = getAddr();
4312    Int dir = 0;
4313    UInt uiArrayAddr = iCount;
4314    xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );
4315    bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_0, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx );
4316    if( bExistMV == false )
4317    {
4318      bExistMV = xGetColMVP( REF_PIC_LIST_0, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
4319    }
4320    if( bExistMV )
4321    {
4322      dir |= 1;
4323      pcMvFieldNeighbours[ 2 * uiArrayAddr ].setMvField( cColMv, iRefIdx );
4324    }
4325
4326    if ( getSlice()->isInterB() )
4327    {
4328      bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_1, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx);
4329      if( bExistMV == false )
4330      {
4331        bExistMV = xGetColMVP( REF_PIC_LIST_1, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
4332      }
4333      if( bExistMV )
4334      {
4335        dir |= 2;
4336        pcMvFieldNeighbours[ 2 * uiArrayAddr + 1 ].setMvField( cColMv, iRefIdx );
4337      }
4338    }
4339   
4340    if (dir != 0)
4341    {
4342      puhInterDirNeighbours[uiArrayAddr] = dir;
4343      abCandIsInter[uiArrayAddr] = true;
4344      if ( mrgCandIdx == iCount )
4345      {
4346        return;
4347      }
4348      iCount++;
4349    }
4350  }
4351  // early termination 
4352  if (iCount == getSlice()->getMaxNumMergeCand()) 
4353  {
4354    return;
4355  }
4356  UInt uiArrayAddr = iCount;
4357  UInt uiCutoff = uiArrayAddr;
4358   
4359  if ( getSlice()->isInterB())
4360  {
4361    UInt uiPriorityList0[12] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3};
4362    UInt uiPriorityList1[12] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2};
4363
4364    for (Int idx=0; idx<uiCutoff*(uiCutoff-1) && uiArrayAddr!= getSlice()->getMaxNumMergeCand(); idx++)
4365    {
4366      Int i = uiPriorityList0[idx]; Int j = uiPriorityList1[idx];
4367      if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
4368      {
4369        abCandIsInter[uiArrayAddr] = true;
4370        puhInterDirNeighbours[uiArrayAddr] = 3;
4371
4372        // get Mv from cand[i] and cand[j]
4373        pcMvFieldNeighbours[uiArrayAddr << 1].setMvField(pcMvFieldNeighbours[i<<1].getMv(), pcMvFieldNeighbours[i<<1].getRefIdx());
4374        pcMvFieldNeighbours[( uiArrayAddr << 1 ) + 1].setMvField(pcMvFieldNeighbours[(j<<1)+1].getMv(), pcMvFieldNeighbours[(j<<1)+1].getRefIdx());
4375
4376        Int iRefPOCL0 = m_pcSlice->getRefPOC( REF_PIC_LIST_0, pcMvFieldNeighbours[(uiArrayAddr<<1)].getRefIdx() );
4377        Int iRefPOCL1 = m_pcSlice->getRefPOC( REF_PIC_LIST_1, pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getRefIdx() );
4378        if (iRefPOCL0 == iRefPOCL1 && pcMvFieldNeighbours[(uiArrayAddr<<1)].getMv() == pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getMv())
4379        {
4380          abCandIsInter[uiArrayAddr] = false;
4381        }
4382        else
4383        {
4384          uiArrayAddr++;
4385        }
4386      }
4387    }
4388  }
4389  // early termination
4390  if (uiArrayAddr == getSlice()->getMaxNumMergeCand()) 
4391  {
4392    return;
4393  }
4394  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);
4395  Int r = 0;
4396  Int refcnt = 0;
4397  while (uiArrayAddr < getSlice()->getMaxNumMergeCand())
4398  {
4399    abCandIsInter[uiArrayAddr] = true;
4400    puhInterDirNeighbours[uiArrayAddr] = 1;
4401    pcMvFieldNeighbours[uiArrayAddr << 1].setMvField( TComMv(0, 0), r);
4402
4403    if ( getSlice()->isInterB() )
4404    {
4405      puhInterDirNeighbours[uiArrayAddr] = 3;
4406      pcMvFieldNeighbours[(uiArrayAddr << 1) + 1].setMvField(TComMv(0, 0), r);
4407    }
4408    uiArrayAddr++;
4409    if ( refcnt == iNumRefIdx - 1 )
4410    {
4411      r = 0;
4412    }
4413    else
4414    {
4415      ++r;
4416      ++refcnt;
4417    }
4418  }
4419
4420  numValidMergeCand = uiArrayAddr;
4421#endif
4422}
4423#else
4424
4425//! Construct a list of merging candidates
4426Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx )
4427{
4428  UInt uiAbsPartAddr = m_absZIdxInCtu + uiAbsPartIdx;
4429  Bool abCandIsInter[ MRG_MAX_NUM_CANDS ];
4430  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
4431  {
4432    abCandIsInter[ui] = false;
4433    pcMvFieldNeighbours[ ( ui << 1 )     ].setRefIdx(NOT_VALID);
4434    pcMvFieldNeighbours[ ( ui << 1 ) + 1 ].setRefIdx(NOT_VALID);
4435  }
4436  numValidMergeCand = getSlice()->getMaxNumMergeCand();
4437  // compute the location of the current PU
4438  Int xP, yP, nPSW, nPSH;
4439  this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
4440
4441  Int iCount = 0;
4442
4443  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
4444  PartSize cCurPS = getPartitionSize( uiAbsPartIdx );
4445  deriveLeftRightTopIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLT, uiPartIdxRT );
4446  deriveLeftBottomIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLB );
4447
4448  //left
4449  UInt uiLeftPartIdx = 0;
4450  TComDataCU* pcCULeft = 0;
4451  pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB );
4452
4453  Bool isAvailableA1 = pcCULeft &&
4454                       pcCULeft->isDiffMER(xP -1, yP+nPSH-1, xP, yP) &&
4455                       !( uiPUIdx == 1 && (cCurPS == SIZE_Nx2N || cCurPS == SIZE_nLx2N || cCurPS == SIZE_nRx2N) ) &&
4456                       pcCULeft->isInter( uiLeftPartIdx ) ;
4457
4458  if ( isAvailableA1 )
4459  {
4460    abCandIsInter[iCount] = true;
4461    // get Inter Dir
4462    puhInterDirNeighbours[iCount] = pcCULeft->getInterDir( uiLeftPartIdx );
4463    // get Mv from Left
4464    pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4465    if ( getSlice()->isInterB() )
4466    {
4467      pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4468    }
4469    if ( mrgCandIdx == iCount )
4470    {
4471      return;
4472    }
4473    iCount ++;
4474  }
4475
4476  // early termination
4477  if (iCount == getSlice()->getMaxNumMergeCand())
4478  {
4479    return;
4480  }
4481  // above
4482  UInt uiAbovePartIdx = 0;
4483  TComDataCU* pcCUAbove = 0;
4484  pcCUAbove = getPUAbove( uiAbovePartIdx, uiPartIdxRT );
4485
4486  Bool isAvailableB1 = pcCUAbove &&
4487                       pcCUAbove->isDiffMER(xP+nPSW-1, yP-1, xP, yP) &&
4488                       !( uiPUIdx == 1 && (cCurPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD) ) &&
4489                       pcCUAbove->isInter( uiAbovePartIdx );
4490
4491  if ( isAvailableB1 && (!isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
4492  {
4493    abCandIsInter[iCount] = true;
4494    // get Inter Dir
4495    puhInterDirNeighbours[iCount] = pcCUAbove->getInterDir( uiAbovePartIdx );
4496    // get Mv from Left
4497    pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4498    if ( getSlice()->isInterB() )
4499    {
4500      pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4501    }
4502    if ( mrgCandIdx == iCount )
4503    {
4504      return;
4505    }
4506    iCount ++;
4507  }
4508  // early termination
4509  if (iCount == getSlice()->getMaxNumMergeCand())
4510  {
4511    return;
4512  }
4513
4514  // above right
4515  UInt uiAboveRightPartIdx = 0;
4516  TComDataCU* pcCUAboveRight = 0;
4517  pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT );
4518
4519  Bool isAvailableB0 = pcCUAboveRight &&
4520                       pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP) &&
4521                       pcCUAboveRight->isInter( uiAboveRightPartIdx );
4522
4523  if ( isAvailableB0 && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
4524  {
4525    abCandIsInter[iCount] = true;
4526    // get Inter Dir
4527    puhInterDirNeighbours[iCount] = pcCUAboveRight->getInterDir( uiAboveRightPartIdx );
4528    // get Mv from Left
4529    pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4530    if ( getSlice()->isInterB() )
4531    {
4532      pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4533    }
4534    if ( mrgCandIdx == iCount )
4535    {
4536      return;
4537    }
4538    iCount ++;
4539  }
4540  // early termination
4541  if (iCount == getSlice()->getMaxNumMergeCand())
4542  {
4543    return;
4544  }
4545
4546  //left bottom
4547  UInt uiLeftBottomPartIdx = 0;
4548  TComDataCU* pcCULeftBottom = 0;
4549  pcCULeftBottom = this->getPUBelowLeft( uiLeftBottomPartIdx, uiPartIdxLB );
4550
4551  Bool isAvailableA0 = pcCULeftBottom &&
4552                       pcCULeftBottom->isDiffMER(xP-1, yP+nPSH, xP, yP) &&
4553                       pcCULeftBottom->isInter( uiLeftBottomPartIdx ) ;
4554
4555  if ( isAvailableA0 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCULeftBottom, uiLeftBottomPartIdx ) ) )
4556  {
4557    abCandIsInter[iCount] = true;
4558    // get Inter Dir
4559    puhInterDirNeighbours[iCount] = pcCULeftBottom->getInterDir( uiLeftBottomPartIdx );
4560    // get Mv from Left
4561    pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4562    if ( getSlice()->isInterB() )
4563    {
4564      pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4565    }
4566    if ( mrgCandIdx == iCount )
4567    {
4568      return;
4569    }
4570    iCount ++;
4571  }
4572  // early termination
4573  if (iCount == getSlice()->getMaxNumMergeCand())
4574  {
4575    return;
4576  }
4577
4578  // above left
4579  if( iCount < 4 )
4580  {
4581    UInt uiAboveLeftPartIdx = 0;
4582    TComDataCU* pcCUAboveLeft = 0;
4583    pcCUAboveLeft = getPUAboveLeft( uiAboveLeftPartIdx, uiAbsPartAddr );
4584
4585    Bool isAvailableB2 = pcCUAboveLeft &&
4586                         pcCUAboveLeft->isDiffMER(xP-1, yP-1, xP, yP) &&
4587                         pcCUAboveLeft->isInter( uiAboveLeftPartIdx );
4588
4589    if ( isAvailableB2 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) )
4590        && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) ) )
4591    {
4592      abCandIsInter[iCount] = true;
4593      // get Inter Dir
4594      puhInterDirNeighbours[iCount] = pcCUAboveLeft->getInterDir( uiAboveLeftPartIdx );
4595      // get Mv from Left
4596      pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
4597      if ( getSlice()->isInterB() )
4598      {
4599        pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
4600      }
4601      if ( mrgCandIdx == iCount )
4602      {
4603        return;
4604      }
4605      iCount ++;
4606    }
4607  }
4608  // early termination
4609  if (iCount == getSlice()->getMaxNumMergeCand())
4610  {
4611    return;
4612  }
4613
4614  if ( getSlice()->getEnableTMVPFlag() )
4615  {
4616    //>> MTK colocated-RightBottom
4617    UInt uiPartIdxRB;
4618
4619    deriveRightBottomIdx( uiPUIdx, uiPartIdxRB );
4620
4621    UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
4622    const UInt numPartInCtuWidth  = m_pcPic->getNumPartInCtuWidth();
4623    const UInt numPartInCtuHeight = m_pcPic->getNumPartInCtuHeight();
4624
4625    TComMv cColMv;
4626    Int iRefIdx;
4627    Int ctuRsAddr = -1;
4628
4629    if (   ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth () ) < m_pcSlice->getSPS()->getPicWidthInLumaSamples () )  // image boundary check
4630        && ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() ) < m_pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
4631    {
4632      if ( ( uiAbsPartIdxTmp % numPartInCtuWidth < numPartInCtuWidth - 1 ) &&           // is not at the last column of CTU
4633        ( uiAbsPartIdxTmp / numPartInCtuWidth < numPartInCtuHeight - 1 ) )              // is not at the last row    of CTU
4634      {
4635        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + numPartInCtuWidth + 1 ];
4636        ctuRsAddr = getCtuRsAddr();
4637      }
4638      else if ( uiAbsPartIdxTmp % numPartInCtuWidth < numPartInCtuWidth - 1 )           // is not at the last column of CTU But is last row of CTU
4639      {
4640        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdxTmp + numPartInCtuWidth + 1) % m_pcPic->getNumPartitionsInCtu() ];
4641      }
4642      else if ( uiAbsPartIdxTmp / numPartInCtuWidth < numPartInCtuHeight - 1 )          // is not at the last row of CTU But is last column of CTU
4643      {
4644        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
4645        ctuRsAddr = getCtuRsAddr() + 1;
4646      }
4647      else //is the right bottom corner of CTU
4648      {
4649        uiAbsPartAddr = 0;
4650      }
4651    }
4652
4653    iRefIdx = 0;
4654
4655    Bool bExistMV = false;
4656    UInt uiPartIdxCenter;
4657    Int dir = 0;
4658    UInt uiArrayAddr = iCount;
4659    xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );
4660    bExistMV = ctuRsAddr >= 0 && xGetColMVP( REF_PIC_LIST_0, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx );
4661    if( bExistMV == false )
4662    {
4663      bExistMV = xGetColMVP( REF_PIC_LIST_0, getCtuRsAddr(), uiPartIdxCenter,  cColMv, iRefIdx );
4664    }
4665    if( bExistMV )
4666    {
4667      dir |= 1;
4668      pcMvFieldNeighbours[ 2 * uiArrayAddr ].setMvField( cColMv, iRefIdx );
4669    }
4670
4671    if ( getSlice()->isInterB() )
4672    {
4673      bExistMV = ctuRsAddr >= 0 && xGetColMVP( REF_PIC_LIST_1, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx);
4674      if( bExistMV == false )
4675      {
4676        bExistMV = xGetColMVP( REF_PIC_LIST_1, getCtuRsAddr(), uiPartIdxCenter, cColMv, iRefIdx );
4677      }
4678      if( bExistMV )
4679      {
4680        dir |= 2;
4681        pcMvFieldNeighbours[ 2 * uiArrayAddr + 1 ].setMvField( cColMv, iRefIdx );
4682      }
4683    }
4684
4685    if (dir != 0)
4686    {
4687      puhInterDirNeighbours[uiArrayAddr] = dir;
4688      abCandIsInter[uiArrayAddr] = true;
4689
4690      if ( mrgCandIdx == iCount )
4691      {
4692        return;
4693      }
4694      iCount++;
4695    }
4696  }
4697  // early termination
4698  if (iCount == getSlice()->getMaxNumMergeCand())
4699  {
4700    return;
4701  }
4702
4703  UInt uiArrayAddr = iCount;
4704  UInt uiCutoff = uiArrayAddr;
4705
4706  if ( getSlice()->isInterB() )
4707  {
4708    static const UInt NUM_PRIORITY_LIST=12;
4709    static const UInt uiPriorityList0[NUM_PRIORITY_LIST] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3};
4710    static const UInt uiPriorityList1[NUM_PRIORITY_LIST] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2};
4711
4712    for (Int idx=0; idx<uiCutoff*(uiCutoff-1) && uiArrayAddr!= getSlice()->getMaxNumMergeCand(); idx++)
4713    {
4714      assert(idx<NUM_PRIORITY_LIST);
4715      Int i = uiPriorityList0[idx];
4716      Int j = uiPriorityList1[idx];
4717      if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
4718      {
4719        abCandIsInter[uiArrayAddr] = true;
4720        puhInterDirNeighbours[uiArrayAddr] = 3;
4721
4722        // get Mv from cand[i] and cand[j]
4723        pcMvFieldNeighbours[uiArrayAddr << 1].setMvField(pcMvFieldNeighbours[i<<1].getMv(), pcMvFieldNeighbours[i<<1].getRefIdx());
4724        pcMvFieldNeighbours[( uiArrayAddr << 1 ) + 1].setMvField(pcMvFieldNeighbours[(j<<1)+1].getMv(), pcMvFieldNeighbours[(j<<1)+1].getRefIdx());
4725
4726        Int iRefPOCL0 = m_pcSlice->getRefPOC( REF_PIC_LIST_0, pcMvFieldNeighbours[(uiArrayAddr<<1)].getRefIdx() );
4727        Int iRefPOCL1 = m_pcSlice->getRefPOC( REF_PIC_LIST_1, pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getRefIdx() );
4728        if (iRefPOCL0 == iRefPOCL1 && pcMvFieldNeighbours[(uiArrayAddr<<1)].getMv() == pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getMv())
4729        {
4730          abCandIsInter[uiArrayAddr] = false;
4731        }
4732        else
4733        {
4734          uiArrayAddr++;
4735        }
4736      }
4737    }
4738  }
4739  // early termination
4740  if (uiArrayAddr == getSlice()->getMaxNumMergeCand())
4741  {
4742    return;
4743  }
4744
4745  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);
4746
4747  Int r = 0;
4748  Int refcnt = 0;
4749  while (uiArrayAddr < getSlice()->getMaxNumMergeCand())
4750  {
4751    abCandIsInter[uiArrayAddr] = true;
4752    puhInterDirNeighbours[uiArrayAddr] = 1;
4753    pcMvFieldNeighbours[uiArrayAddr << 1].setMvField( TComMv(0, 0), r);
4754
4755    if ( getSlice()->isInterB() )
4756    {
4757      puhInterDirNeighbours[uiArrayAddr] = 3;
4758      pcMvFieldNeighbours[(uiArrayAddr << 1) + 1].setMvField(TComMv(0, 0), r);
4759    }
4760    uiArrayAddr++;
4761
4762    if ( refcnt == iNumRefIdx - 1 )
4763    {
4764      r = 0;
4765    }
4766    else
4767    {
4768      ++r;
4769      ++refcnt;
4770    }
4771  }
4772  numValidMergeCand = uiArrayAddr;
4773}
4774#endif
4775
4776/** Check whether the current PU and a spatial neighboring PU are in a same ME region.
4777 * \param xN, yN   location of the upper-left corner pixel of a neighboring PU
4778 * \param xP, yP   location of the upper-left corner pixel of the current PU
4779 */
4780Bool TComDataCU::isDiffMER(Int xN, Int yN, Int xP, Int yP)
4781{
4782
4783  UInt plevel = this->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() + 2;
4784  if ((xN>>plevel)!= (xP>>plevel))
4785  {
4786    return true;
4787  }
4788  if ((yN>>plevel)!= (yP>>plevel))
4789  {
4790    return true;
4791  }
4792  return false;
4793}
4794
4795/** Calculate the location of upper-left corner pixel and size of the current PU.
4796 * \param partIdx       PU index within a CU
4797 * \param xP, yP        location of the upper-left corner pixel of the current PU
4798 * \param nPSW, nPSH    size of the current PU
4799 */
4800Void TComDataCU::getPartPosition( UInt partIdx, Int& xP, Int& yP, Int& nPSW, Int& nPSH)
4801{
4802  UInt col = m_uiCUPelX;
4803  UInt row = m_uiCUPelY;
4804
4805  switch ( m_pePartSize[0] )
4806  {
4807  case SIZE_2NxN:
4808    nPSW = getWidth(0);
4809    nPSH = getHeight(0) >> 1;
4810    xP   = col;
4811    yP   = (partIdx ==0)? row: row + nPSH;
4812    break;
4813  case SIZE_Nx2N:
4814    nPSW = getWidth(0) >> 1;
4815    nPSH = getHeight(0);
4816    xP   = (partIdx ==0)? col: col + nPSW;
4817    yP   = row;
4818    break;
4819  case SIZE_NxN:
4820    nPSW = getWidth(0) >> 1;
4821    nPSH = getHeight(0) >> 1;
4822    xP   = col + (partIdx&0x1)*nPSW;
4823    yP   = row + (partIdx>>1)*nPSH;
4824    break;
4825  case SIZE_2NxnU:
4826    nPSW = getWidth(0);
4827    nPSH = ( partIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
4828    xP   = col;
4829    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
4830
4831    break;
4832  case SIZE_2NxnD:
4833    nPSW = getWidth(0);
4834    nPSH = ( partIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
4835    xP   = col;
4836    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
4837    break;
4838  case SIZE_nLx2N:
4839    nPSW = ( partIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
4840    nPSH = getHeight(0);
4841    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
4842    yP   = row;
4843    break;
4844  case SIZE_nRx2N:
4845    nPSW = ( partIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
4846    nPSH = getHeight(0);
4847    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
4848    yP   = row;
4849    break;
4850  default:
4851    assert ( m_pePartSize[0] == SIZE_2Nx2N );
4852    nPSW = getWidth(0);
4853    nPSH = getHeight(0);
4854    xP   = col ;
4855    yP   = row ;
4856
4857    break;
4858  }
4859}
4860
4861/** Constructs a list of candidates for AMVP
4862 * \param uiPartIdx
4863 * \param uiPartAddr
4864 * \param eRefPicList
4865 * \param iRefIdx
4866 * \param pInfo
4867 */
4868Void TComDataCU::fillMvpCand ( UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, AMVPInfo* pInfo )
4869{
4870  TComMv cMvPred;
4871  Bool bAddedSmvp = false;
4872
4873  pInfo->iN = 0;
4874  if (iRefIdx < 0)
4875  {
4876    return;
4877  }
4878
4879  //-- Get Spatial MV
4880  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
4881  const UInt numPartInCtuWidth  = m_pcPic->getNumPartInCtuWidth();
4882  const UInt numPartInCtuHeight = m_pcPic->getNumPartInCtuHeight();
4883  Bool bAdded = false;
4884
4885  deriveLeftRightTopIdx( uiPartIdx, uiPartIdxLT, uiPartIdxRT );
4886  deriveLeftBottomIdx( uiPartIdx, uiPartIdxLB );
4887
4888  TComDataCU* tmpCU = NULL;
4889  UInt idx;
4890  tmpCU = getPUBelowLeft(idx, uiPartIdxLB);
4891  bAddedSmvp = (tmpCU != NULL) && (tmpCU->isInter(idx));
4892
4893  if (!bAddedSmvp)
4894  {
4895    tmpCU = getPULeft(idx, uiPartIdxLB);
4896    bAddedSmvp = (tmpCU != NULL) && (tmpCU->isInter(idx));
4897  }
4898
4899  // Left predictor search
4900  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
4901  if (!bAdded)
4902  {
4903    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
4904  }
4905
4906  if(!bAdded)
4907  {
4908    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
4909    if (!bAdded)
4910    {
4911      xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
4912    }
4913  }
4914
4915  // Above predictor search
4916  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
4917
4918  if (!bAdded)
4919  {
4920    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
4921  }
4922
4923  if(!bAdded)
4924  {
4925    xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
4926  }
4927
4928  if(!bAddedSmvp)
4929  {
4930    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
4931    if (!bAdded)
4932    {
4933      bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
4934    }
4935
4936    if(!bAdded)
4937    {
4938      xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
4939    }
4940  }
4941
4942  if ( pInfo->iN == 2 )
4943  {
4944    if ( pInfo->m_acMvCand[ 0 ] == pInfo->m_acMvCand[ 1 ] )
4945    {
4946      pInfo->iN = 1;
4947    }
4948  }
4949
4950  if ( getSlice()->getEnableTMVPFlag() )
4951  {
4952    // Get Temporal Motion Predictor
4953    Int iRefIdx_Col = iRefIdx;
4954    TComMv cColMv;
4955    UInt uiPartIdxRB;
4956    UInt uiAbsPartIdx;
4957    UInt uiAbsPartAddr;
4958
4959    deriveRightBottomIdx( uiPartIdx, uiPartIdxRB );
4960    uiAbsPartAddr = m_absZIdxInCtu + uiPartAddr;
4961
4962    //----  co-located RightBottom Temporal Predictor (H) ---//
4963    uiAbsPartIdx = g_auiZscanToRaster[uiPartIdxRB];
4964    Int ctuRsAddr = -1;
4965    if (  ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdx] + m_pcPic->getMinCUWidth () ) < m_pcSlice->getSPS()->getPicWidthInLumaSamples () )  // image boundary check
4966       && ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdx] + m_pcPic->getMinCUHeight() ) < m_pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
4967    {
4968      if ( ( uiAbsPartIdx % numPartInCtuWidth < numPartInCtuWidth - 1 ) &&  // is not at the last column of CTU
4969           ( uiAbsPartIdx / numPartInCtuWidth < numPartInCtuHeight - 1 ) )  // is not at the last row    of CTU
4970      {
4971        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + numPartInCtuWidth + 1 ];
4972        ctuRsAddr = getCtuRsAddr();
4973      }
4974      else if ( uiAbsPartIdx % numPartInCtuWidth < numPartInCtuWidth - 1 )  // is not at the last column of CTU But is last row of CTU
4975      {
4976        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdx + numPartInCtuWidth + 1) % m_pcPic->getNumPartitionsInCtu() ];
4977      }
4978      else if ( uiAbsPartIdx / numPartInCtuWidth < numPartInCtuHeight - 1 ) // is not at the last row of CTU But is last column of CTU
4979      {
4980        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + 1 ];
4981        ctuRsAddr = getCtuRsAddr() + 1;
4982      }
4983      else //is the right bottom corner of CTU
4984      {
4985        uiAbsPartAddr = 0;
4986      }
4987    }
4988    if ( ctuRsAddr >= 0 && xGetColMVP( eRefPicList, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx_Col
4989#if H_3D_TMVP
4990         , 0
4991#endif
4992 ) )
4993    {
4994      pInfo->m_acMvCand[pInfo->iN++] = cColMv;
4995    }
4996    else
4997    {
4998      UInt uiPartIdxCenter;
4999      xDeriveCenterIdx( uiPartIdx, uiPartIdxCenter );
5000      if (xGetColMVP( eRefPicList, getCtuRsAddr(), uiPartIdxCenter,  cColMv, iRefIdx_Col
5001#if H_3D_TMVP
5002         , 0
5003#endif
5004))
5005      {
5006        pInfo->m_acMvCand[pInfo->iN++] = cColMv;
5007      }
5008    }
5009    //----  co-located RightBottom Temporal Predictor  ---//
5010  }
5011
5012  if (pInfo->iN > AMVP_MAX_NUM_CANDS)
5013  {
5014    pInfo->iN = AMVP_MAX_NUM_CANDS;
5015  }
5016
5017  while (pInfo->iN < AMVP_MAX_NUM_CANDS)
5018  {
5019    pInfo->m_acMvCand[pInfo->iN].set(0,0);
5020    pInfo->iN++;
5021  }
5022  return ;
5023}
5024
5025
5026Bool TComDataCU::isBipredRestriction(UInt puIdx)
5027{
5028  Int width = 0;
5029  Int height = 0;
5030  UInt partAddr;
5031
5032#if H_3D_DBBP
5033  if( getDBBPFlag(0) )
5034  {
5035    return true;
5036  }
5037#endif
5038
5039  getPartIndexAndSize( puIdx, partAddr, width, height );
5040  if ( getWidth(0) == 8 && (width < 8 || height < 8) )
5041  {
5042    return true;
5043  }
5044  return false;
5045}
5046
5047
5048Void TComDataCU::clipMv    (TComMv&  rcMv)
5049{
5050  const TComSPS &sps=*(m_pcSlice->getSPS());
5051  Int  iMvShift = 2;
5052#if H_3D_IC
5053  if( getSlice()->getIsDepth() )
5054    iMvShift = 0;
5055#endif
5056
5057  Int iOffset = 8;
5058  Int iHorMax = ( sps.getPicWidthInLumaSamples() + iOffset - (Int)m_uiCUPelX - 1 ) << iMvShift;
5059  Int iHorMin = (      -(Int)sps.getMaxCUWidth() - iOffset - (Int)m_uiCUPelX + 1 ) << iMvShift;
5060
5061  Int iVerMax = ( sps.getPicHeightInLumaSamples() + iOffset - (Int)m_uiCUPelY - 1 ) << iMvShift;
5062  Int iVerMin = (      -(Int)sps.getMaxCUHeight() - iOffset - (Int)m_uiCUPelY + 1 ) << iMvShift;
5063
5064  rcMv.setHor( min (iHorMax, max (iHorMin, rcMv.getHor())) );
5065  rcMv.setVer( min (iVerMax, max (iVerMin, rcMv.getVer())) );
5066}
5067
5068#if NH_MV
5069Void TComDataCU::checkMvVertRest (TComMv&  rcMv,  RefPicList eRefPicList, int iRefIdx )
5070{
5071  if ( getSlice()->getSPS()->getInterViewMvVertConstraintFlag() )
5072  {
5073    if ( getSlice()->getRefPic( eRefPicList, iRefIdx )->getPOC() == getSlice()->getPOC() )
5074    {
5075        //When inter_view_mv_vert_constraint_flag is equal to 1,
5076        //the vertical component of the motion vectors used for inter-layer prediction
5077        //shall be equal to or less than 56 in units of luma samples
5078        assert ( rcMv.getVer() <= (56<<2) );
5079    }
5080  }
5081}
5082#endif
5083
5084UInt TComDataCU::getIntraSizeIdx(UInt uiAbsPartIdx)
5085{
5086  UInt uiShift = ( m_pePartSize[uiAbsPartIdx]==SIZE_NxN ? 1 : 0 );
5087
5088  UChar uiWidth = m_puhWidth[uiAbsPartIdx]>>uiShift;
5089  UInt  uiCnt = 0;
5090  while( uiWidth )
5091  {
5092    uiCnt++;
5093    uiWidth>>=1;
5094  }
5095  uiCnt-=2;
5096  return uiCnt > 6 ? 6 : uiCnt;
5097}
5098
5099Void TComDataCU::clearCbf( UInt uiIdx, ComponentID compID, UInt uiNumParts )
5100{
5101  memset( &m_puhCbf[compID][uiIdx], 0, sizeof(UChar)*uiNumParts);
5102}
5103
5104/** Set a I_PCM flag for all sub-partitions of a partition.
5105 * \param bIpcmFlag I_PCM flag
5106 * \param uiAbsPartIdx patition index
5107 * \param uiDepth CU depth
5108 * \returns Void
5109 */
5110Void TComDataCU::setIPCMFlagSubParts  (Bool bIpcmFlag, UInt uiAbsPartIdx, UInt uiDepth)
5111{
5112  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
5113
5114  memset(m_pbIPCMFlag + uiAbsPartIdx, bIpcmFlag, sizeof(Bool)*uiCurrPartNumb );
5115}
5116
5117/** Test whether the block at uiPartIdx is skipped.
5118 * \param uiPartIdx Partition index
5119 * \returns true if the current the block is skipped
5120 */
5121Bool TComDataCU::isSkipped( UInt uiPartIdx )
5122{
5123  return ( getSkipFlag( uiPartIdx ) );
5124}
5125
5126#if H_3D_IC
5127Bool TComDataCU::isIC( UInt uiPartIdx )
5128{
5129    if ( m_pcSlice->isIntra () )
5130    {
5131        return false;
5132    }
5133    return ( ( getSkipFlag(uiPartIdx) || getPredictionMode(uiPartIdx) == MODE_INTER) && getICFlag( uiPartIdx ) && isICFlagRequired( uiPartIdx ) );
5134}
5135#endif
5136
5137// ====================================================================================================================
5138// Protected member functions
5139// ====================================================================================================================
5140
5141Bool TComDataCU::xAddMVPCand( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
5142{
5143  TComDataCU* pcTmpCU = NULL;
5144  UInt uiIdx;
5145  switch( eDir )
5146  {
5147    case MD_LEFT:
5148    {
5149      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
5150      break;
5151    }
5152    case MD_ABOVE:
5153    {
5154      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx);
5155      break;
5156    }
5157    case MD_ABOVE_RIGHT:
5158    {
5159      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
5160      break;
5161    }
5162    case MD_BELOW_LEFT:
5163    {
5164      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
5165      break;
5166    }
5167    case MD_ABOVE_LEFT:
5168    {
5169      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
5170      break;
5171    }
5172    default:
5173    {
5174      break;
5175    }
5176  }
5177
5178  if ( pcTmpCU == NULL )
5179  {
5180    return false;
5181  }
5182
5183  if ( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0 && m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC() == pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ))
5184  {
5185    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
5186
5187    pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
5188    return true;
5189  }
5190
5191  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
5192  if(       eRefPicList == REF_PIC_LIST_0 )
5193  {
5194    eRefPicList2nd = REF_PIC_LIST_1;
5195  }
5196  else if ( eRefPicList == REF_PIC_LIST_1)
5197  {
5198    eRefPicList2nd = REF_PIC_LIST_0;
5199  }
5200
5201
5202  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
5203  Int iNeibRefPOC;
5204
5205
5206  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0 )
5207  {
5208    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
5209    if( iNeibRefPOC == iCurrRefPOC ) // Same Reference Frame But Diff List//
5210    {
5211      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
5212      pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
5213      return true;
5214    }
5215  }
5216  return false;
5217}
5218
5219/**
5220 * \param pInfo
5221 * \param eRefPicList
5222 * \param iRefIdx
5223 * \param uiPartUnitIdx
5224 * \param eDir
5225 * \returns Bool
5226 */
5227Bool TComDataCU::xAddMVPCandOrder( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
5228{
5229  TComDataCU* pcTmpCU = NULL;
5230  UInt uiIdx;
5231  switch( eDir )
5232  {
5233  case MD_LEFT:
5234    {
5235      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
5236      break;
5237    }
5238  case MD_ABOVE:
5239    {
5240      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx);
5241      break;
5242    }
5243  case MD_ABOVE_RIGHT:
5244    {
5245      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
5246      break;
5247    }
5248  case MD_BELOW_LEFT:
5249    {
5250      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
5251      break;
5252    }
5253  case MD_ABOVE_LEFT:
5254    {
5255      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
5256      break;
5257    }
5258  default:
5259    {
5260      break;
5261    }
5262  }
5263
5264  if ( pcTmpCU == NULL )
5265  {
5266    return false;
5267  }
5268
5269  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
5270  if(       eRefPicList == REF_PIC_LIST_0 )
5271  {
5272    eRefPicList2nd = REF_PIC_LIST_1;
5273  }
5274  else if ( eRefPicList == REF_PIC_LIST_1)
5275  {
5276    eRefPicList2nd = REF_PIC_LIST_0;
5277  }
5278
5279  Int iCurrPOC = m_pcSlice->getPOC();
5280  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
5281  Int iNeibPOC = iCurrPOC;
5282  Int iNeibRefPOC;
5283  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getIsLongTerm();
5284  Bool bIsNeibRefLongTerm = false;
5285
5286  //---------------  V1 (END) ------------------//
5287  if( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0)
5288  {
5289    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) );
5290    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
5291    TComMv rcMv;
5292
5293    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) )->getIsLongTerm();
5294    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm )
5295    {
5296      if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
5297      {
5298        rcMv = cMvPred;
5299      }
5300      else
5301      {
5302        Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
5303        if ( iScale == 4096 )
5304        {
5305          rcMv = cMvPred;
5306        }
5307        else
5308        {
5309          rcMv = cMvPred.scaleMv( iScale );
5310        }
5311      }
5312
5313      pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
5314      return true;
5315    }
5316  }
5317  //---------------------- V2(END) --------------------//
5318  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0)
5319  {
5320    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
5321    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
5322    TComMv rcMv;
5323
5324    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) )->getIsLongTerm();
5325    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm )
5326    {
5327      if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
5328      {
5329        rcMv = cMvPred;
5330      }
5331      else
5332      {
5333        Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
5334        if ( iScale == 4096 )
5335        {
5336          rcMv = cMvPred;
5337        }
5338        else
5339        {
5340          rcMv = cMvPred.scaleMv( iScale );
5341        }
5342      }
5343
5344      pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
5345      return true;
5346    }
5347  }
5348  //---------------------- V3(END) --------------------//
5349  return false;
5350}
5351
5352Bool TComDataCU::xGetColMVP( RefPicList eRefPicList, Int ctuRsAddr, Int uiPartUnitIdx, TComMv& rcMv, Int& riRefIdx
5353#if H_3D_TMVP
5354  , Bool bMRG
5355#endif
5356)
5357{
5358  UInt uiAbsPartAddr = uiPartUnitIdx;
5359
5360  RefPicList  eColRefPicList;
5361  Int iColPOC, iColRefPOC, iCurrPOC, iCurrRefPOC, iScale;
5362  TComMv cColMv;
5363
5364  // use coldir.
5365  TComPic *pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());
5366  TComDataCU *pColCtu = pColPic->getCtu( ctuRsAddr );
5367  if(pColCtu->getPic()==0||pColCtu->getPartitionSize(uiPartUnitIdx)==NUMBER_OF_PART_SIZES)
5368  {
5369    return false;
5370  }
5371  iCurrPOC = m_pcSlice->getPOC();
5372  iColPOC = pColCtu->getSlice()->getPOC();
5373
5374  if (!pColCtu->isInter(uiAbsPartAddr))
5375  {
5376    return false;
5377  }
5378
5379  eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());
5380
5381  Int iColRefIdx = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
5382
5383  if (iColRefIdx < 0 )
5384  {
5385    eColRefPicList = RefPicList(1 - eColRefPicList);
5386    iColRefIdx = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
5387
5388    if (iColRefIdx < 0 )
5389    {
5390      return false;
5391    }
5392  }
5393
5394  // Scale the vector.
5395  iColRefPOC = pColCtu->getSlice()->getRefPOC(eColRefPicList, iColRefIdx);
5396  cColMv = pColCtu->getCUMvField(eColRefPicList)->getMv(uiAbsPartAddr);
5397
5398  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
5399
5400  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();
5401  Bool bIsColRefLongTerm = pColCtu->getSlice()->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
5402
5403  if ( bIsCurrRefLongTerm != bIsColRefLongTerm )
5404  {
5405#if H_3D_TMVP
5406    Int iAlterRefIdx  = m_pcSlice->getAlterRefIdx(eRefPicList);
5407    if(bMRG && iAlterRefIdx > 0)
5408    {
5409      riRefIdx = iAlterRefIdx;
5410      bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();
5411      iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
5412      assert(bIsCurrRefLongTerm == bIsColRefLongTerm);
5413    }
5414    else
5415    {
5416#endif
5417    return false;
5418#if H_3D_TMVP
5419    }
5420#endif
5421  }
5422
5423  if ( bIsCurrRefLongTerm || bIsColRefLongTerm )
5424  {
5425#if H_3D_TMVP
5426    Int iCurrViewId    = m_pcSlice->getViewId (); 
5427    Int iCurrRefViewId = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getViewId (); 
5428    Int iColViewId     = pColCU->getSlice()->getViewId(); 
5429    Int iColRefViewId  = pColCU->getSlice()->getRefPic( eColRefPicList, pColCU->getCUMvField(eColRefPicList)->getRefIdx(uiAbsPartAddr))->getViewId(); 
5430    iScale = 4096;
5431    if ( iCurrRefViewId != iCurrViewId && iColViewId != iColRefViewId )
5432    {
5433      iScale = xGetDistScaleFactor( iCurrViewId, iCurrRefViewId, iColViewId, iColRefViewId );
5434    }
5435    if ( bMRG && iScale != 4096 && m_pcSlice->getIvMvScalingFlag( ) ) 
5436    {
5437      rcMv = cColMv.scaleMv( iScale );
5438    }
5439    else
5440    {
5441#endif
5442    rcMv = cColMv;
5443#if H_3D_TMVP
5444    }
5445#endif
5446  }
5447  else
5448  {
5449    iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iColPOC, iColRefPOC);
5450    if ( iScale == 4096 )
5451    {
5452      rcMv = cColMv;
5453    }
5454    else
5455    {
5456      rcMv = cColMv.scaleMv( iScale );
5457    }
5458  }
5459
5460  return true;
5461}
5462
5463Int TComDataCU::xGetDistScaleFactor(Int iCurrPOC, Int iCurrRefPOC, Int iColPOC, Int iColRefPOC)
5464{
5465  Int iDiffPocD = iColPOC - iColRefPOC;
5466  Int iDiffPocB = iCurrPOC - iCurrRefPOC;
5467
5468  if( iDiffPocD == iDiffPocB )
5469  {
5470    return 4096;
5471  }
5472  else
5473  {
5474    Int iTDB      = Clip3( -128, 127, iDiffPocB );
5475    Int iTDD      = Clip3( -128, 127, iDiffPocD );
5476    Int iX        = (0x4000 + abs(iTDD/2)) / iTDD;
5477    Int iScale    = Clip3( -4096, 4095, (iTDB * iX + 32) >> 6 );
5478    return iScale;
5479  }
5480}
5481
5482Void TComDataCU::xDeriveCenterIdx( UInt uiPartIdx, UInt& ruiPartIdxCenter )
5483{
5484  UInt uiPartAddr;
5485  Int  iPartWidth;
5486  Int  iPartHeight;
5487  getPartIndexAndSize( uiPartIdx, uiPartAddr, iPartWidth, iPartHeight);
5488
5489  ruiPartIdxCenter = m_absZIdxInCtu+uiPartAddr; // partition origin.
5490  ruiPartIdxCenter = g_auiRasterToZscan[ g_auiZscanToRaster[ ruiPartIdxCenter ]
5491                                        + ( iPartHeight/m_pcPic->getMinCUHeight()  )/2*m_pcPic->getNumPartInCtuWidth()
5492                                        + ( iPartWidth/m_pcPic->getMinCUWidth()  )/2];
5493}
5494
5495#if NH_3D
5496Void TComDataCU::compressMV(Int scale)
5497{
5498   Int scaleFactor = (4 / scale ) * AMVP_DECIMATION_FACTOR / m_unitSize;
5499#else
5500Void TComDataCU::compressMV()
5501{
5502  Int scaleFactor = 4 * AMVP_DECIMATION_FACTOR / m_unitSize;
5503#endif
5504  if (scaleFactor > 0)
5505  {
5506    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
5507    {
5508      m_acCUMvField[i].compress(m_pePredMode, scaleFactor);
5509    }
5510  }
5511}
5512
5513UInt TComDataCU::getCoefScanIdx(const UInt uiAbsPartIdx, const UInt uiWidth, const UInt uiHeight, const ComponentID compID) const
5514{
5515  //------------------------------------------------
5516
5517  //this mechanism is available for intra only
5518
5519  if (!isIntra(uiAbsPartIdx))
5520  {
5521    return SCAN_DIAG;
5522  }
5523
5524  //------------------------------------------------
5525
5526  //check that MDCS can be used for this TU
5527
5528  const ChromaFormat format = getPic()->getChromaFormat();
5529
5530  const UInt maximumWidth  = MDCS_MAXIMUM_WIDTH  >> getComponentScaleX(compID, format);
5531  const UInt maximumHeight = MDCS_MAXIMUM_HEIGHT >> getComponentScaleY(compID, format);
5532
5533  if ((uiWidth > maximumWidth) || (uiHeight > maximumHeight))
5534  {
5535    return SCAN_DIAG;
5536  }
5537
5538  //------------------------------------------------
5539
5540  //otherwise, select the appropriate mode
5541
5542  UInt uiDirMode  = getIntraDir(toChannelType(compID), uiAbsPartIdx);
5543#if NH_3D_DMM
5544  mapDmmToIntraDir( uiDirMode );
5545#endif
5546
5547  if (uiDirMode==DM_CHROMA_IDX)
5548  {
5549    const TComSPS *sps=getSlice()->getSPS();
5550    const UInt partsPerMinCU = 1<<(2*(sps->getMaxTotalCUDepth() - sps->getLog2DiffMaxMinCodingBlockSize()));
5551    uiDirMode = getIntraDir(CHANNEL_TYPE_LUMA, getChromasCorrespondingPULumaIdx(uiAbsPartIdx, getPic()->getChromaFormat(), partsPerMinCU));
5552#if NH_3D_DMM
5553    mapDmmToIntraDir( uiDirMode );
5554#endif
5555  }
5556
5557  if (isChroma(compID) && (format == CHROMA_422))
5558  {
5559    uiDirMode = g_chroma422IntraAngleMappingTable[uiDirMode];
5560  }
5561
5562  //------------------
5563
5564  if      (abs((Int)uiDirMode - VER_IDX) <= MDCS_ANGLE_LIMIT)
5565  {
5566    return SCAN_HOR;
5567  }
5568  else if (abs((Int)uiDirMode - HOR_IDX) <= MDCS_ANGLE_LIMIT)
5569  {
5570    return SCAN_VER;
5571  }
5572  else
5573  {
5574    return SCAN_DIAG;
5575  }
5576}
5577
5578#if NH_3D_VSO
5579Void TComDataCU::getPosInPic( UInt uiAbsPartIndex, Int& riPosX, Int& riPosY ) const
5580{
5581  riPosX = g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelX();
5582  riPosY = g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelY(); 
5583}
5584#endif
5585
5586#if H_3D_IV_MERGE
5587Void TComDataCU::getDispforDepth (UInt uiPartIdx, UInt uiPartAddr, DisInfo* pDisp)
5588{
5589  assert(getPartitionSize( uiPartAddr ) == SIZE_2Nx2N);
5590
5591  TComMv cMv; 
5592  if ( getSlice()->getDefaultRefViewIdxAvailableFlag() )
5593  {
5594    Int iViewIdx = getSlice()->getDefaultRefViewIdx();
5595    pDisp->m_aVIdxCan = iViewIdx;
5596    Int iDisp     = getSlice()->getDepthToDisparityB( iViewIdx )[ (Int64) (1 << ( getSlice()->getSPS()->getBitDepthY() - 1 )) ];
5597
5598    cMv.setHor(iDisp);
5599    cMv.setVer(0);
5600    pDisp->m_acNBDV = cMv;
5601    pDisp->m_aVIdxCan = iViewIdx;
5602  }
5603}
5604#endif
5605
5606#if H_3D
5607Bool TComDataCU::getNeighDepth ( UInt uiPartIdx, UInt uiPartAddr, Pel* pNeighDepth, Int index )
5608{
5609  UInt  uiPartIdxLT, uiPartIdxRT;
5610  this->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, 0, 0 );
5611  UInt uiMidPart, uiPartNeighbor; 
5612  TComDataCU* pcCUNeighbor;
5613  Bool bDepAvail = false;
5614  Pel *pDepth  = this->getPic()->getPicYuvRec()->getLumaAddr();
5615  Int iDepStride =  this->getPic()->getPicYuvRec()->getStride();
5616
5617  Int xP, yP, nPSW, nPSH;
5618  this->getPartPosition( uiPartIdx, xP, yP, nPSW, nPSH );
5619
5620  switch( index )
5621  {
5622  case 0: // Mid Left
5623    uiMidPart = g_auiZscanToRaster[uiPartIdxLT] + (nPSH>>1) / this->getPic()->getMinCUHeight() * this->getPic()->getNumPartInWidth();
5624    pcCUNeighbor = this->getPULeft( uiPartNeighbor, g_auiRasterToZscan[uiMidPart] );
5625    if ( pcCUNeighbor )
5626    {
5627      if( !this->getSlice()->getPPS()->getConstrainedIntraPred() )
5628      {
5629        *pNeighDepth = pDepth[ (yP+(nPSH>>1)) * iDepStride + (xP-1) ];
5630        bDepAvail = true;
5631      }
5632      else if ( pcCUNeighbor->getPredictionMode( uiPartNeighbor ) == MODE_INTRA )
5633      {
5634        *pNeighDepth = pDepth[ (yP+(nPSH>>1)) * iDepStride + (xP-1) ];
5635        bDepAvail = true;
5636      }
5637    }
5638    break;
5639  case 1: // Mid Above
5640    uiMidPart = g_auiZscanToRaster[uiPartIdxLT] + (nPSW>>1) / this->getPic()->getMinCUWidth();
5641    pcCUNeighbor = this->getPUAbove( uiPartNeighbor, g_auiRasterToZscan[uiMidPart] );
5642    if( pcCUNeighbor )
5643    {
5644      if( !this->getSlice()->getPPS()->getConstrainedIntraPred() )
5645      {
5646        *pNeighDepth = pDepth[ (yP-1) * iDepStride + (xP + (nPSW>>1)) ];
5647        bDepAvail = true;
5648      }
5649      else if ( pcCUNeighbor->getPredictionMode( uiPartNeighbor ) == MODE_INTRA )
5650      {
5651        *pNeighDepth = pDepth[ (yP-1) * iDepStride + (xP + (nPSW>>1)) ];
5652        bDepAvail = true;
5653      }
5654    }
5655    break;
5656  default:
5657    break;
5658  }
5659
5660  return bDepAvail;
5661}
5662#endif
5663#if H_3D_NBDV
5664//Notes from QC:
5665//TBD#1: DoNBDV related contributions are just partially integrated under the marco of H_3D_NBDV_REF, remove this comment once DoNBDV and BVSP are done
5666//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
5667//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
5668Void TComDataCU::getDisMvpCandNBDV( DisInfo* pDInfo
5669#if H_3D_NBDV_REF
5670, Bool bDepthRefine
5671#endif
5672)
5673{
5674  //// ******* Init variables ******* /////
5675  // Init disparity struct for results
5676  pDInfo->m_aVIdxCan = -1;
5677
5678  // Init struct for disparities from MCP neighboring blocks
5679  IDVInfo cIDVInfo;
5680  cIDVInfo.m_bFound = false; 
5681  UInt uiPartIdx = 0;
5682  UInt uiPartAddr = 0;
5683  for (UInt iCurDvMcpCand = 0; iCurDvMcpCand < IDV_CANDS; iCurDvMcpCand++)
5684  {
5685    for (UInt iList = 0; iList < 2; iList++)
5686    {
5687      cIDVInfo.m_acMvCand[iList][iCurDvMcpCand].setZero();
5688      cIDVInfo.m_aVIdxCan[iList][iCurDvMcpCand] = 0; 
5689      cIDVInfo.m_bAvailab[iList][iCurDvMcpCand] = false; 
5690    }
5691  }
5692#if H_3D_NBDV_REF
5693  if( !m_pcSlice->getDepthRefinementFlag( ) )
5694  {
5695    bDepthRefine = false;
5696  }
5697#endif
5698  // Get Positions 
5699  PartSize eCUMode    = getPartitionSize( uiPartAddr );   
5700  assert(eCUMode == SIZE_2Nx2N);
5701  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB; 
5702
5703  deriveLeftRightTopIdxGeneral(uiPartAddr, uiPartIdx, uiPartIdxLT, uiPartIdxRT );
5704  deriveLeftBottomIdxGeneral  (uiPartAddr, uiPartIdx, uiPartIdxLB );
5705
5706  //// ******* Get disparity from temporal neighboring blocks ******* /////
5707  if ( getSlice()->getEnableTMVPFlag() )
5708  {
5709    TComMv cColMv;
5710    Int iTargetViewIdx = 0;
5711    Int iTStartViewIdx = 0;   
5712
5713    ///*** Derive center position ***
5714    UInt uiPartIdxCenter;
5715    Int  uiLCUIdx   = getAddr();
5716    xDeriveCenterIdx(uiPartIdx, uiPartIdxCenter );
5717
5718    ///*** Search temporal candidate pictures for disparity vector ***
5719    const Int iNumCandPics = getPic()->getNumDdvCandPics();
5720    for(Int curCandPic = 0; curCandPic < iNumCandPics; curCandPic++)
5721    {
5722      RefPicList eCurRefPicList   = REF_PIC_LIST_0 ;
5723      Int        curCandPicRefIdx = 0;
5724      if( curCandPic == 0 ) 
5725      { 
5726        eCurRefPicList   = RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0);
5727        curCandPicRefIdx = getSlice()->getColRefIdx();
5728      }
5729      else                 
5730      {
5731        eCurRefPicList   = getPic()->getRapRefList();
5732        curCandPicRefIdx = getPic()->getRapRefIdx();
5733      }
5734
5735      Bool bCheck = xGetColDisMV( curCandPic, eCurRefPicList, curCandPicRefIdx, uiLCUIdx,   uiPartIdxCenter,  cColMv, iTargetViewIdx, iTStartViewIdx );
5736
5737      if( bCheck )
5738      {
5739        pDInfo->m_acNBDV = cColMv;
5740        pDInfo->m_aVIdxCan  = iTargetViewIdx;
5741
5742#if H_3D_NBDV_REF
5743        TComPic* picDepth = NULL;   
5744#if H_3D_FCO_VSP_DONBDV_E0163
5745        picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
5746        if ( picDepth->getPicYuvRec() != NULL  ) 
5747        {
5748          cColMv.setZero();
5749        }
5750        else // Go back with virtual depth
5751        {
5752          picDepth = getSlice()->getIvPic( true, iTargetViewIdx );
5753        }
5754
5755        assert(picDepth != NULL);
5756#else
5757        picDepth = getSlice()->getIvPic( true, iTargetViewIdx );
5758#endif
5759        if (picDepth && bDepthRefine)
5760        {
5761          estimateDVFromDM(iTargetViewIdx, uiPartIdx, picDepth, uiPartAddr, &cColMv );
5762        }
5763        pDInfo->m_acDoNBDV  = cColMv;
5764#endif //H_3D_NBDV_REF
5765        return;
5766      }
5767    }
5768  } 
5769
5770  UInt uiIdx = 0;
5771  Bool        bCheckMcpDv = false;   
5772  TComDataCU* pcTmpCU     = NULL;
5773
5774  //// ******* Get disparity from left block ******* /////
5775  pcTmpCU = getPULeft(uiIdx, uiPartIdxLB, true, false);
5776  bCheckMcpDv = true; 
5777  if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_LEFT
5778#if H_3D_NBDV_REF
5779    , bDepthRefine
5780#endif
5781    ) )
5782    return;
5783
5784  //// ******* Get disparity from above block ******* /////
5785  pcTmpCU = getPUAbove(uiIdx, uiPartIdxRT, true, false, true);
5786  if(pcTmpCU != NULL )
5787  {
5788    bCheckMcpDv = ( ( getAddr() - pcTmpCU->getAddr() ) == 0);
5789    if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_ABOVE
5790#if H_3D_NBDV_REF
5791      , bDepthRefine
5792#endif
5793      ) )
5794      return;
5795  }
5796
5797  //// ******* Search MCP blocks ******* /////
5798  if( cIDVInfo.m_bFound ) 
5799  {
5800    for( Int curPos = 0 ; curPos < IDV_CANDS ; curPos++ ) 
5801    {
5802      for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
5803      {
5804        if( cIDVInfo.m_bAvailab[iList][curPos] )
5805        {
5806          TComMv cDispVec = cIDVInfo.m_acMvCand[iList][ curPos ];
5807          pDInfo->m_acNBDV = cDispVec;
5808          pDInfo->m_aVIdxCan = cIDVInfo.m_aVIdxCan[iList][ curPos ];
5809#if H_3D_NBDV_REF
5810#if H_3D_FCO_VSP_DONBDV_E0163
5811          TComPic* picDepth  = NULL;
5812
5813          picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
5814          if ( picDepth->getPicYuvRec() != NULL ) 
5815          {
5816            cDispVec.setZero();
5817          }
5818          else // Go back with virtual depth
5819          {
5820            picDepth = getSlice()->getIvPic( true, pDInfo->m_aVIdxCan );
5821          }
5822
5823          assert(picDepth != NULL);
5824#else
5825          TComPic* picDepth = getSlice()->getIvPic( true, pDInfo->m_aVIdxCan );
5826#endif
5827
5828          if (picDepth && bDepthRefine)
5829          {
5830            estimateDVFromDM (pDInfo->m_aVIdxCan, uiPartIdx, picDepth, uiPartAddr, &cDispVec);
5831          }
5832          pDInfo->m_acDoNBDV = cDispVec;
5833#endif
5834          return;
5835        }
5836      }
5837    }
5838  }
5839
5840  TComMv defaultDV(0, 0);
5841  pDInfo->m_acNBDV = defaultDV;
5842
5843  if (getSlice()->getDefaultRefViewIdxAvailableFlag())
5844  {
5845    pDInfo->m_aVIdxCan = getSlice()->getDefaultRefViewIdx();
5846
5847#if H_3D_NBDV_REF
5848    TComPic* picDepth = NULL;
5849#if H_3D_FCO_VSP_DONBDV_E0163
5850    picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
5851    if ( picDepth->getPicYuvRec() != NULL ) 
5852    {
5853      defaultDV.setZero();
5854    }
5855    else // Go back with virtual depth
5856    {
5857      picDepth = getSlice()->getIvPic( true, getSlice()->getDefaultRefViewIdx());
5858    }
5859
5860    assert(picDepth != NULL);
5861#else
5862    picDepth = getSlice()->getIvPic( true, getSlice()->getDefaultRefViewIdx());
5863#endif
5864    if (picDepth && bDepthRefine)
5865    {
5866      estimateDVFromDM(getSlice()->getDefaultRefViewIdx(), uiPartIdx, picDepth, uiPartAddr, &defaultDV ); // from base view
5867    }
5868    pDInfo->m_acDoNBDV = defaultDV;
5869#endif
5870  }
5871}
5872
5873#if H_3D_NBDV_REF
5874Pel TComDataCU::getMcpFromDM(TComPicYuv* pcBaseViewDepthPicYuv, TComMv* mv, Int iBlkX, Int iBlkY, Int iBlkWidth, Int iBlkHeight, Int* aiShiftLUT )
5875{
5876  Int iPictureWidth  = pcBaseViewDepthPicYuv->getWidth();
5877  Int iPictureHeight = pcBaseViewDepthPicYuv->getHeight();
5878 
5879  Int depthStartPosX = Clip3(0,   iPictureWidth - 1,  iBlkX + ((mv->getHor()+2)>>2));
5880  Int depthStartPosY = Clip3(0,   iPictureHeight - 1, iBlkY + ((mv->getVer()+2)>>2));
5881  Int depthEndPosX   = Clip3(0,   iPictureWidth - 1,  iBlkX + iBlkWidth - 1 + ((mv->getHor()+2)>>2));
5882  Int depthEndPosY   = Clip3(0,   iPictureHeight - 1, iBlkY + iBlkHeight - 1 + ((mv->getVer()+2)>>2));
5883
5884  Pel* depthTL  = pcBaseViewDepthPicYuv->getLumaAddr();
5885  Int depStride =  pcBaseViewDepthPicYuv->getStride();
5886
5887  Pel  maxDepthVal = 0;
5888  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthStartPosX ]);      // Left Top
5889  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthStartPosX ]);      // Left Bottom
5890  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthEndPosX   ]);      // Right Top
5891  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthEndPosX   ]);      // Right Bottom
5892
5893  return aiShiftLUT[ maxDepthVal ];
5894}
5895
5896Void TComDataCU::estimateDVFromDM(Int refViewIdx, UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred )
5897{
5898  if (picDepth)
5899  {
5900    UInt uiAbsPartAddrCurrCU = m_uiAbsIdxInLCU + uiPartAddr;
5901    Int iWidth, iHeight;
5902    getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight ); // The modified value of uiPartAddr won't be used any more
5903
5904    TComPicYuv* pcBaseViewDepthPicYuv = picDepth->getPicYuvRec();
5905    Int iBlkX = ( getAddr() % picDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
5906    Int iBlkY = ( getAddr() / picDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
5907
5908    Int* aiShiftLUT = getSlice()->getDepthToDisparityB(refViewIdx );
5909
5910    Pel iDisp = getMcpFromDM( pcBaseViewDepthPicYuv, cMvPred, iBlkX, iBlkY, iWidth, iHeight, aiShiftLUT );
5911    cMvPred->setHor( iDisp );
5912  }
5913}
5914#endif //H_3D_NBDV_REF
5915
5916
5917Bool TComDataCU::xCheckSpatialNBDV( TComDataCU* pcTmpCU, UInt uiIdx, DisInfo* pNbDvInfo, Bool bSearchForMvpDv, IDVInfo* paIDVInfo, UInt uiMvpDvPos
5918#if H_3D_NBDV_REF
5919, Bool bDepthRefine
5920#endif
5921)
5922{
5923  if( pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ) )
5924  {
5925    Bool bTmpIsSkipped = pcTmpCU->isSkipped( uiIdx );
5926    for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
5927    {
5928      RefPicList eRefPicList = RefPicList(iList);
5929      Int      refId = pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ;
5930      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
5931
5932      if( refId >= 0)
5933      {
5934        Int refViewIdx  = pcTmpCU->getSlice()->getRefPic(eRefPicList, refId)->getViewIndex();
5935        if (refViewIdx != m_pcSlice->getViewIndex()) 
5936        {
5937          pNbDvInfo->m_acNBDV = cMvPred;
5938          pNbDvInfo->m_aVIdxCan = refViewIdx;
5939#if H_3D_NBDV_REF
5940          TComPic* picDepth = NULL;
5941          assert(getSlice()->getRefPic(eRefPicList, refId)->getPOC() == getSlice()->getPOC());         
5942#if H_3D_FCO_VSP_DONBDV_E0163
5943          picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
5944          if ( picDepth->getPicYuvRec() != NULL ) 
5945          {
5946            cMvPred.setZero();
5947          }
5948          else// Go back with virtual depth
5949          {
5950            picDepth = getSlice()->getIvPic (true, refViewIdx );
5951          }
5952          assert(picDepth != NULL);
5953#else
5954          picDepth   = getSlice()->getIvPic (true, refViewIdx );
5955#endif
5956          UInt uiPartIdx = 0;   //Notes from MTK: Please confirm that using 0 as partition index and partition address is correct for CU-level DoNBDV
5957          UInt uiPartAddr = 0;  //QC: confirmed
5958
5959          if (picDepth && bDepthRefine)
5960          {
5961            estimateDVFromDM(refViewIdx, uiPartIdx, picDepth, uiPartAddr, &cMvPred );
5962          }
5963          pNbDvInfo->m_acDoNBDV = cMvPred;
5964#endif
5965          return true;
5966        }
5967        else if ( bSearchForMvpDv && cMvPred.getIDVFlag() && bTmpIsSkipped )
5968        {
5969          assert( uiMvpDvPos < IDV_CANDS );
5970          paIDVInfo->m_acMvCand[iList][ uiMvpDvPos ] = TComMv( cMvPred.getIDVHor(), cMvPred.getIDVVer() );
5971          //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.
5972          paIDVInfo->m_aVIdxCan[iList][ uiMvpDvPos ] = cMvPred.getIDVVId();
5973          paIDVInfo->m_bAvailab[iList][ uiMvpDvPos ] = true;
5974          paIDVInfo->m_bFound                        = true; 
5975        }
5976      }
5977    }
5978  }
5979  return false; 
5980}
5981 
5982Void TComDataCU::xDeriveRightBottomNbIdx(Int &riLCUIdxRBNb, Int &riPartIdxRBNb )
5983{
5984  UInt uiPartIdx = 0;
5985  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth(); 
5986  Int uiLCUIdx = getAddr();
5987
5988  UInt uiPartIdxRB;
5989  deriveRightBottomIdx(uiPartIdx, uiPartIdxRB ); 
5990  UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
5991
5992  if (( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() )>= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
5993  {
5994    riLCUIdxRBNb  = -1;
5995    riPartIdxRBNb = -1;
5996  }
5997  else if(( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() )>= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
5998  {
5999    riLCUIdxRBNb  = -1;
6000    riPartIdxRBNb = -1;
6001  }
6002  else
6003  {
6004    if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
6005      ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
6006    {
6007      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
6008      riLCUIdxRBNb  = uiLCUIdx; 
6009    }
6010    else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
6011    {
6012      riPartIdxRBNb = -1;
6013      riLCUIdxRBNb  = -1;
6014    }
6015    else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
6016    {
6017      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
6018      riLCUIdxRBNb = uiLCUIdx + 1;
6019    }
6020    else //is the right bottom corner of LCU                       
6021    {
6022      riPartIdxRBNb = -1;
6023      riLCUIdxRBNb  = -1;
6024    }
6025  }
6026}
6027
6028
6029Void TComDataCU::setDvInfoSubParts( DisInfo cDvInfo, UInt uiAbsPartIdx, UInt uiDepth )
6030{
6031  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
6032  for (UInt ui = 0; ui < uiCurrPartNumb; ui++ )
6033  {
6034    m_pDvInfo[uiAbsPartIdx + ui] = cDvInfo;
6035  }
6036}
6037#if H_3D_VSP
6038Void TComDataCU::setDvInfoSubParts( DisInfo cDvInfo, UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth )
6039{
6040  setSubPartT<DisInfo>( cDvInfo, m_pDvInfo, uiAbsPartIdx, uiDepth, uiPUIdx );
6041}
6042#endif
6043
6044Bool TComDataCU::xGetColDisMV( Int currCandPic, RefPicList eRefPicList, Int refidx, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv , Int & iTargetViewIdx, Int & iStartViewIdx )
6045{
6046
6047  RefPicList  eColRefPicList = REF_PIC_LIST_0;
6048  Int iColViewIdx, iColRefViewIdx;
6049  TComPic *pColPic = getSlice()->getRefPic( eRefPicList, refidx);
6050  TComDataCU *pColCU = pColPic->getCU( uiCUAddr );
6051  iColViewIdx = pColCU->getSlice()->getViewIndex();
6052  if (pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==SIZE_NONE||pColCU->isIntra(uiPartUnitIdx))
6053  {
6054    return false;
6055  }
6056  for (Int ilist = 0; ilist < (pColCU->getSlice()->isInterB()? 2:1); ilist++) 
6057  {
6058    if(pColCU->getSlice()->isInterB())
6059    {
6060      eColRefPicList = RefPicList(ilist);
6061    }
6062
6063    Int iColRefIdx = pColCU->getCUMvField(eColRefPicList)->getRefIdx(uiPartUnitIdx);
6064
6065    if (iColRefIdx < 0)
6066    {
6067      continue;
6068    }
6069
6070    iColRefViewIdx = pColCU->getSlice()->getRefPic(eColRefPicList, iColRefIdx)->getViewIndex();
6071
6072    if ( iColViewIdx    == iColRefViewIdx ) // temporal vector
6073    {
6074      continue;
6075    }
6076    else 
6077    {
6078      if(getPic()->isTempIVRefValid(currCandPic, ilist,  iColRefIdx))
6079      {
6080        rcMv = pColCU->getCUMvField(eColRefPicList)->getMv(uiPartUnitIdx);
6081        rcMv.setIDVFlag(0);
6082        iTargetViewIdx  = iColRefViewIdx ;
6083        iStartViewIdx   = iColViewIdx   ;
6084        return true;   
6085      }
6086    }
6087  }
6088
6089  return false;
6090}
6091#endif
6092#if  H_3D_FAST_TEXTURE_ENCODING
6093Void
6094TComDataCU::getIVNStatus       ( UInt uiPartIdx,  DisInfo* pDInfo, Bool& bIVFMerge, Int& iIVFMaxD)
6095{
6096  TComSlice*    pcSlice         = getSlice (); 
6097  Int iViewIndex = pDInfo->m_aVIdxCan;
6098  //--- get base CU/PU and check prediction mode ---
6099  TComPic*    pcBasePic   = pcSlice->getIvPic( false, iViewIndex );
6100  TComPicYuv* pcBaseRec   = pcBasePic->getPicYuvRec   ();
6101
6102  UInt          uiPartAddr;
6103  Int           iWidth;
6104  Int           iHeight;
6105  getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
6106
6107  Int  iCurrPosX, iCurrPosY;
6108  pcBaseRec->getTopLeftSamplePos( getAddr(), getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
6109
6110  iCurrPosX  += ( ( iWidth  - 1 ) >> 1 );
6111  iCurrPosY  += ( ( iHeight - 1 ) >> 1 );
6112
6113  Bool depthRefineFlag = false; 
6114#if H_3D_NBDV_REF
6115  depthRefineFlag = m_pcSlice->getDepthRefinementFlag( ); 
6116#endif // H_3D_NBDV_REF
6117
6118  TComMv      cDv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
6119  if( depthRefineFlag )
6120  {
6121    cDv.setVer(0);
6122  }
6123
6124  Int         iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6125  Int         iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
6126  Int         iBaseLPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX - (iWidth >> 1) + ( (cDv.getHor() + 2 ) >> 2 ) );
6127  Int         iBaseLPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
6128  Int         iBaseRPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + (iWidth >> 1) + 1 + ( (cDv.getHor() + 2 ) >> 2 ) );
6129  Int         iBaseRPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
6130  Int         iBaseUPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6131  Int         iBaseUPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY - (iHeight >> 1) + ( (cDv.getVer() + 2 ) >> 2 )); 
6132  Int         iBaseDPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6133  Int         iBaseDPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + (iHeight >> 1) + 1 + ( (cDv.getVer() + 2 ) >> 2 )); 
6134
6135  Int         iBaseCUAddr;
6136  Int         iBaseAbsPartIdx;
6137  Int         iBaseLCUAddr;
6138  Int         iBaseLAbsPartIdx;
6139  Int         iBaseRCUAddr;
6140  Int         iBaseRAbsPartIdx;
6141  Int         iBaseUCUAddr;
6142  Int         iBaseUAbsPartIdx;
6143  Int         iBaseDCUAddr;
6144  Int         iBaseDAbsPartIdx;
6145  pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY , iBaseCUAddr, iBaseAbsPartIdx );
6146  pcBaseRec->getCUAddrAndPartIdx( iBaseLPosX , iBaseLPosY , iBaseLCUAddr, iBaseLAbsPartIdx );
6147  pcBaseRec->getCUAddrAndPartIdx( iBaseRPosX , iBaseRPosY , iBaseRCUAddr, iBaseRAbsPartIdx );
6148  pcBaseRec->getCUAddrAndPartIdx( iBaseUPosX , iBaseUPosY , iBaseUCUAddr, iBaseUAbsPartIdx );
6149  pcBaseRec->getCUAddrAndPartIdx( iBaseDPosX , iBaseDPosY , iBaseDCUAddr, iBaseDAbsPartIdx );
6150  TComDataCU* pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
6151  TComDataCU* pcBaseLCU    = pcBasePic->getCU( iBaseLCUAddr );
6152  TComDataCU* pcBaseRCU    = pcBasePic->getCU( iBaseRCUAddr );
6153  TComDataCU* pcBaseUCU    = pcBasePic->getCU( iBaseUCUAddr );
6154  TComDataCU* pcBaseDCU    = pcBasePic->getCU( iBaseDCUAddr );
6155  bIVFMerge = pcBaseLCU->getMergeFlag( iBaseLAbsPartIdx ) && pcBaseCU->getMergeFlag( iBaseAbsPartIdx ) && pcBaseRCU->getMergeFlag( iBaseRAbsPartIdx ) && pcBaseUCU->getMergeFlag( iBaseUAbsPartIdx ) && pcBaseDCU->getMergeFlag( iBaseDAbsPartIdx );
6156  Int aiDepthL[5]; //depth level
6157  aiDepthL[0] = pcBaseCU->getDepth(iBaseAbsPartIdx);
6158  aiDepthL[1] = pcBaseLCU->getDepth(iBaseLAbsPartIdx);
6159  aiDepthL[2] = pcBaseRCU->getDepth(iBaseRAbsPartIdx);
6160  aiDepthL[3] = pcBaseUCU->getDepth(iBaseUAbsPartIdx);
6161  aiDepthL[4] = pcBaseDCU->getDepth(iBaseDAbsPartIdx);
6162  for (Int i = 0; i < 5; i++)
6163  {
6164    if (iIVFMaxD < aiDepthL[i])
6165      iIVFMaxD = aiDepthL[i];
6166  }
6167}
6168#endif
6169
6170#if H_3D_SPIVMP
6171Void TComDataCU::getSPPara(Int iPUWidth, Int iPUHeight, Int& iNumSP, Int& iNumSPInOneLine, Int& iSPWidth, Int& iSPHeight)
6172{
6173  Int iSubPUSize = ( getSlice()->getIsDepth() ? getSlice()->getMpiSubPbSize() : getSlice()->getSubPbSize() );
6174
6175  iNumSPInOneLine = iPUWidth/iSubPUSize;
6176  Int iNumSPInOneColumn = iPUHeight/iSubPUSize;
6177  iNumSPInOneLine = (iPUHeight % iSubPUSize != 0 || iPUWidth % iSubPUSize != 0 ) ? 1 : iNumSPInOneLine;
6178  iNumSPInOneColumn = (iPUHeight % iSubPUSize != 0  || iPUWidth % iSubPUSize != 0 ) ? 1 : iNumSPInOneColumn;
6179  iNumSP = iNumSPInOneLine * iNumSPInOneColumn;
6180
6181  iSPWidth = iNumSPInOneLine == 1 ? iPUWidth: iSubPUSize; 
6182  iSPHeight = iNumSPInOneColumn == 1 ? iPUHeight: iSubPUSize; 
6183}
6184
6185Void TComDataCU::getSPAbsPartIdx(UInt uiBaseAbsPartIdx, Int iWidth, Int iHeight, Int iPartIdx, Int iNumPartLine, UInt& ruiPartAddr )
6186{
6187  uiBaseAbsPartIdx += m_uiAbsIdxInLCU;
6188  Int iBasePelX = g_auiRasterToPelX[g_auiZscanToRaster[uiBaseAbsPartIdx]];
6189  Int iBasePelY = g_auiRasterToPelY[g_auiZscanToRaster[uiBaseAbsPartIdx]];
6190  Int iCurrPelX = iBasePelX + iPartIdx%iNumPartLine * iWidth;
6191  Int iCurrPelY = iBasePelY + iPartIdx/iNumPartLine * iHeight;
6192  Int iCurrRaster = iCurrPelY / getPic()->getMinCUHeight() * getPic()->getNumPartInWidth() + iCurrPelX/getPic()->getMinCUWidth();
6193  ruiPartAddr = g_auiRasterToZscan[iCurrRaster];
6194  ruiPartAddr -= m_uiAbsIdxInLCU; 
6195}
6196
6197Void TComDataCU::setInterDirSP( UInt uiDir, UInt uiAbsPartIdx, Int iWidth, Int iHeight )
6198{
6199  uiAbsPartIdx += getZorderIdxInCU();
6200  Int iStartPelX = g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]];
6201  Int iStartPelY = g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
6202  Int iEndPelX = iStartPelX + iWidth;
6203  Int iEndPelY = iStartPelY + iHeight;
6204
6205  Int iCurrRaster, uiPartAddr;
6206
6207  for (Int i=iStartPelY; i<iEndPelY; i+=getPic()->getMinCUHeight())
6208  {
6209    for (Int j=iStartPelX; j < iEndPelX; j += getPic()->getMinCUWidth())
6210    {
6211      iCurrRaster = i / getPic()->getMinCUHeight() * getPic()->getNumPartInWidth() + j/getPic()->getMinCUWidth();
6212      uiPartAddr = g_auiRasterToZscan[iCurrRaster];
6213      uiPartAddr -= getZorderIdxInCU(); 
6214
6215      m_puhInterDir[uiPartAddr] = uiDir;
6216    }
6217  }
6218}
6219#endif
6220
6221#if H_3D_IV_MERGE
6222Bool
6223TComDataCU::getInterViewMergeCands(UInt uiPartIdx, Int* paiPdmRefIdx, TComMv* pacPdmMv, DisInfo* pDInfo, Int* availableMcDc , Bool bIsDepth           
6224#if H_3D_SPIVMP
6225, TComMvField* pcMvFieldSP, UChar* puhInterDirSP
6226#endif
6227, Bool bICFlag
6228)
6229{
6230  TComSlice*    pcSlice = getSlice (); 
6231  Int iViewIndex        = pDInfo->m_aVIdxCan;
6232
6233  //--- get base CU/PU and check prediction mode ---
6234  TComPic*    pcBasePic   = pcSlice->getIvPic( bIsDepth, iViewIndex );
6235  TComPicYuv* pcBaseRec   = pcBasePic->getPicYuvRec   ();
6236
6237  UInt          uiPartAddr;
6238  Int           iWidth;
6239  Int           iHeight;
6240  getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
6241
6242  Int  iCurrPosX, iCurrPosY;
6243  pcBaseRec->getTopLeftSamplePos( getAddr(), getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
6244
6245#if !H_3D_SPIVMP
6246  iCurrPosX  += ( iWidth  >> 1 );
6247  iCurrPosY  += ( iHeight >> 1 );
6248#endif
6249
6250  Bool depthRefineFlag = false; 
6251#if H_3D_NBDV_REF
6252  depthRefineFlag = m_pcSlice->getDepthRefinementFlag( ); 
6253#endif // H_3D_NBDV_REF
6254
6255  TComMv      cDv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
6256  if( depthRefineFlag )
6257  {
6258    cDv.setVer(0);
6259  }
6260
6261  Bool abPdmAvailable[8] =  {false, false, false, false, false, false, false, false};
6262#if H_3D_NBDV
6263  for( Int i = 0; i < 8; i++)
6264  {
6265    pacPdmMv[i].setIDVFlag   (false);
6266  }
6267#endif
6268
6269  if(!bICFlag)
6270  {
6271
6272#if H_3D_SPIVMP
6273    ////////////////////////////////
6274    //////////sub-PU IvMC///////////
6275    ////////////////////////////////
6276    if(!m_pcSlice->getIsDepth())
6277    {
6278      if (!getDBBPFlag(0))
6279      {
6280        Int iNumSPInOneLine, iNumSP, iSPWidth, iSPHeight;
6281        getSPPara(iWidth, iHeight, iNumSP, iNumSPInOneLine, iSPWidth, iSPHeight);
6282
6283        for (Int i=0; i<iNumSP; i++)
6284        {
6285          puhInterDirSP[i] = 0;
6286          pcMvFieldSP[2*i].getMv().set(0, 0);
6287          pcMvFieldSP[2*i+1].getMv().set(0,0);
6288          pcMvFieldSP[2*i].setRefIdx(-1);
6289          pcMvFieldSP[2*i+1].setRefIdx(-1);
6290        }
6291
6292        Int         iBaseCUAddr;
6293        Int         iBaseAbsPartIdx;
6294        TComDataCU* pcBaseCU;
6295        Int iPartition = 0;
6296
6297        Int iDelX = iSPWidth/2;
6298        Int iDelY = iSPHeight/2;
6299
6300        Int         iCenterPosX = iCurrPosX + ( ( iWidth /  iSPWidth ) >> 1 )  * iSPWidth + ( iSPWidth >> 1 );
6301        Int         iCenterPosY = iCurrPosY + ( ( iHeight /  iSPHeight ) >> 1 )  * iSPHeight + (iSPHeight >> 1);
6302        Int         iRefCenterCUAddr, iRefCenterAbsPartIdx;
6303
6304        if(iWidth == iSPWidth && iHeight == iSPHeight)
6305        {
6306          iCenterPosX = iCurrPosX + (iWidth >> 1);
6307          iCenterPosY = iCurrPosY + (iHeight >> 1);
6308        }
6309
6310        Int iRefCenterPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCenterPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6311        Int iRefCenterPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCenterPosY + ( (cDv.getVer() + 2 ) >> 2 ) ); 
6312
6313        pcBaseRec->getCUAddrAndPartIdx( iRefCenterPosX , iRefCenterPosY , iRefCenterCUAddr, iRefCenterAbsPartIdx );
6314        TComDataCU* pcDefaultCU    = pcBasePic->getCU( iRefCenterCUAddr );
6315        if(!( pcDefaultCU->getPredictionMode( iRefCenterAbsPartIdx ) == MODE_INTRA ))
6316        {
6317          for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )       
6318          {
6319            RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
6320            Bool stopLoop = false;
6321            for(Int iLoop = 0; iLoop < 2 && !stopLoop; ++iLoop)
6322            {
6323              RefPicList eDefaultRefPicList = (iLoop ==1)? RefPicList( 1 -  uiCurrRefListId ) : RefPicList( uiCurrRefListId );
6324              TComMvField cDefaultMvField;
6325              pcDefaultCU->getMvField( pcDefaultCU, iRefCenterAbsPartIdx, eDefaultRefPicList, cDefaultMvField );
6326              Int         iDefaultRefIdx     = cDefaultMvField.getRefIdx();
6327              if (iDefaultRefIdx >= 0)
6328              {
6329                Int iDefaultRefPOC = pcDefaultCU->getSlice()->getRefPOC(eDefaultRefPicList, iDefaultRefIdx);
6330                if (iDefaultRefPOC != pcSlice->getPOC())   
6331                {
6332                  for (Int iPdmRefIdx = 0; iPdmRefIdx < pcSlice->getNumRefIdx( eCurrRefPicList ); iPdmRefIdx++)
6333                  {
6334                    if (iDefaultRefPOC == pcSlice->getRefPOC(eCurrRefPicList, iPdmRefIdx))
6335                    {
6336                      abPdmAvailable[ uiCurrRefListId ] = true;
6337                      TComMv cMv(cDefaultMvField.getHor(), cDefaultMvField.getVer());
6338#if H_3D_NBDV
6339#if H_3D_IV_MERGE
6340                      if( !bIsDepth )
6341                      {
6342#endif
6343                        cMv.setIDVFlag   (true);
6344                        cMv.setIDVHor    (cDv.getHor());                 
6345                        cMv.setIDVVer    (cDv.getVer()); 
6346                        cMv.setIDVVId    (iViewIndex); 
6347#if H_3D_IV_MERGE
6348                      }
6349#endif
6350#endif
6351                      paiPdmRefIdx  [ uiCurrRefListId ] = iPdmRefIdx;
6352                      pacPdmMv      [ uiCurrRefListId ] = cMv;
6353                      stopLoop = true;
6354                      break;
6355                    }
6356                  }
6357                }
6358              }
6359            }
6360          }
6361        }
6362        availableMcDc[0] = ( abPdmAvailable[0]? 1 : 0) + (abPdmAvailable[1]? 2 : 0);
6363
6364        if(availableMcDc[0])
6365        {
6366
6367          Int         iBasePosX, iBasePosY;
6368          for (Int i=iCurrPosY; i < iCurrPosY + iHeight; i += iSPHeight)
6369          {
6370            for (Int j = iCurrPosX; j < iCurrPosX + iWidth; j += iSPWidth)
6371            {
6372              iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, j + iDelX + ( (cDv.getHor() + 2 ) >> 2 ));
6373              iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, i + iDelY + ( (cDv.getVer() + 2 ) >> 2 )); 
6374
6375              pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY, iBaseCUAddr, iBaseAbsPartIdx );
6376              pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
6377              if(!( pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) == MODE_INTRA ))
6378              {
6379                for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )
6380                {
6381                  RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
6382                  Bool bLoopStop = false;
6383                  for(Int iLoop = 0; iLoop < 2 && !bLoopStop; ++iLoop)
6384                  {
6385                    RefPicList eBaseRefPicList = (iLoop ==1)? RefPicList( 1 -  uiCurrRefListId ) : RefPicList( uiCurrRefListId );
6386                    TComMvField cBaseMvField;
6387                    pcBaseCU->getMvField( pcBaseCU, iBaseAbsPartIdx, eBaseRefPicList, cBaseMvField );
6388                    Int         iBaseRefIdx     = cBaseMvField.getRefIdx();
6389                    if (iBaseRefIdx >= 0)
6390                    {
6391                      Int iBaseRefPOC = pcBaseCU->getSlice()->getRefPOC(eBaseRefPicList, iBaseRefIdx);
6392                      if (iBaseRefPOC != pcSlice->getPOC())   
6393                      {
6394                        for (Int iPdmRefIdx = 0; iPdmRefIdx < pcSlice->getNumRefIdx( eCurrRefPicList ); iPdmRefIdx++)
6395                        {
6396                          if (iBaseRefPOC == pcSlice->getRefPOC(eCurrRefPicList, iPdmRefIdx))
6397                          {
6398                            abPdmAvailable[ uiCurrRefListId ] = true;
6399                            TComMv cMv(cBaseMvField.getHor(), cBaseMvField.getVer());
6400
6401                            if( !bIsDepth )
6402                            {
6403                              cMv.setIDVFlag   (true);
6404                              cMv.setIDVHor    (cDv.getHor());                 
6405                              cMv.setIDVVer    (cDv.getVer()); 
6406                              cMv.setIDVVId    (iViewIndex); 
6407                            }
6408
6409                            bLoopStop = true;
6410
6411                            pcMvFieldSP[2*iPartition + uiCurrRefListId].setMvField(cMv, iPdmRefIdx);
6412                            break;
6413                          }
6414                        }
6415                      }
6416                    }
6417                  }
6418                }
6419              }
6420
6421              puhInterDirSP[iPartition] = (pcMvFieldSP[2*iPartition].getRefIdx()!=-1 ? 1: 0) + (pcMvFieldSP[2*iPartition+1].getRefIdx()!=-1 ? 2: 0);
6422              if (puhInterDirSP[iPartition] == 0)
6423              {
6424                puhInterDirSP[iPartition] = availableMcDc[0];
6425                pcMvFieldSP[2*iPartition].setMvField(pacPdmMv[0], paiPdmRefIdx[0]);
6426                pcMvFieldSP[2*iPartition + 1].setMvField(pacPdmMv[1], paiPdmRefIdx[1]);
6427
6428              }
6429              iPartition ++;
6430            }
6431          }
6432        }
6433      }
6434
6435      iCurrPosX  += ( iWidth  >> 1 );
6436      iCurrPosY  += ( iHeight >> 1 );
6437    }
6438#endif
6439
6440    ////////////////////////////////
6441    /////// IvMC + IvMCShift ///////
6442    ////////////////////////////////
6443
6444#if H_3D_SPIVMP
6445    if(m_pcSlice->getIsDepth())
6446    {
6447      iCurrPosX  += ( iWidth  >> 1 );
6448      iCurrPosY  += ( iHeight >> 1 );
6449    }
6450    for(Int iLoopCan = ( (m_pcSlice->getIsDepth() || getDBBPFlag(0)) ? 0 : 1 ); iLoopCan < ( 2 - m_pcSlice->getIsDepth() ); iLoopCan ++) 
6451#else
6452    for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6453#endif
6454    {
6455      // iLoopCan == 0 --> IvMC
6456      // iLoopCan == 1 --> IvMCShift
6457
6458      Int         iBaseCUAddr;
6459      Int         iBaseAbsPartIdx;
6460
6461      Int offsetW = (iLoopCan == 0) ? 0 : ( iWidth  * 2 );
6462      Int offsetH = (iLoopCan == 0) ? 0 : ( iHeight * 2 );
6463
6464      Int         iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + offsetW + 2 ) >> 2 ) );
6465      Int         iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + offsetH + 2 ) >> 2 ) ); 
6466      pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY , iBaseCUAddr, iBaseAbsPartIdx );
6467
6468      TComDataCU* pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
6469      if(!( pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) == MODE_INTRA ))
6470      {
6471        // Loop reference picture list of current slice (X in spec).
6472        for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )       
6473        {
6474          RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
6475
6476          Bool stopLoop = false;
6477          // Loop reference picture list of candidate slice (Y in spec)
6478          for(Int iLoop = 0; iLoop < 2 && !stopLoop; ++iLoop)
6479          {
6480            RefPicList eBaseRefPicList = (iLoop ==1)? RefPicList( 1 -  uiCurrRefListId ) : RefPicList( uiCurrRefListId );
6481            TComMvField cBaseMvField;
6482            pcBaseCU->getMvField( pcBaseCU, iBaseAbsPartIdx, eBaseRefPicList, cBaseMvField );
6483            Int         iBaseRefIdx     = cBaseMvField.getRefIdx();
6484            if (iBaseRefIdx >= 0)
6485            {
6486              Int iBaseRefPOC = pcBaseCU->getSlice()->getRefPOC(eBaseRefPicList, iBaseRefIdx);
6487              if (iBaseRefPOC != pcSlice->getPOC())   
6488              {
6489                for (Int iPdmRefIdx = 0; iPdmRefIdx < pcSlice->getNumRefIdx( eCurrRefPicList ); iPdmRefIdx++)
6490                {
6491                  if (iBaseRefPOC == pcSlice->getRefPOC(eCurrRefPicList, iPdmRefIdx))
6492                  {
6493                    abPdmAvailable[ (uiCurrRefListId + (iLoopCan<<2)) ] = true;
6494                    TComMv cMv(cBaseMvField.getHor(), cBaseMvField.getVer());
6495#if H_3D_NBDV
6496#if H_3D_IV_MERGE
6497                    if( !bIsDepth )
6498                    {
6499#endif
6500                      cMv.setIDVFlag   (true);
6501                      cMv.setIDVHor    (cDv.getHor());                 
6502                      cMv.setIDVVer    (cDv.getVer()); 
6503                      cMv.setIDVVId    (iViewIndex); 
6504#if H_3D_IV_MERGE
6505                    }
6506#endif
6507#endif
6508                    paiPdmRefIdx  [ (uiCurrRefListId + (iLoopCan<<2)) ] = iPdmRefIdx;
6509                    pacPdmMv      [ (uiCurrRefListId + (iLoopCan<<2)) ] = cMv;
6510                    stopLoop = true;
6511                    break;
6512                  }
6513                }
6514              }
6515            }
6516          }
6517        }
6518      }
6519    }
6520#if H_3D_SPIVMP
6521    for(Int iLoopCan = ( (m_pcSlice->getIsDepth() || getDBBPFlag(0)) ? 0 : 1 ); iLoopCan < ( 2 - m_pcSlice->getIsDepth() ); iLoopCan ++)
6522#else
6523    for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6524#endif
6525    {
6526      availableMcDc[(iLoopCan << 1)] = ( abPdmAvailable[(iLoopCan<<2)] ? 1 : 0 ) + ( abPdmAvailable[1 + (iLoopCan<<2)] ? 2 : 0);
6527    }
6528
6529  }
6530
6531  ////////////////////////////////
6532  /////// IvDC + IvDCShift ///////
6533  ////////////////////////////////
6534
6535  if( !getSlice()->getIsDepth() )
6536  {
6537    for( Int iRefListId = 0; iRefListId < 2 ; iRefListId++ )
6538    {
6539      RefPicList  eRefPicListDMV       = RefPicList( iRefListId );
6540      Int         iNumRefPics       = pcSlice->getNumRefIdx( eRefPicListDMV );
6541      for( Int iPdmRefIdx = 0; iPdmRefIdx < iNumRefPics; iPdmRefIdx++ )
6542      {
6543        if(( pcSlice->getRefPOC( eRefPicListDMV, iPdmRefIdx ) == pcSlice->getPOC()) && (pcSlice->getRefPic( eRefPicListDMV, iPdmRefIdx )->getViewIndex() == pDInfo->m_aVIdxCan))
6544        {
6545          for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6546          {
6547            Int ioffsetDV = (iLoopCan == 0) ? 0 : 4;
6548            abPdmAvailable[ iRefListId + 2 + (iLoopCan<<2) ] = true;
6549            paiPdmRefIdx  [ iRefListId + 2 + (iLoopCan<<2) ] = iPdmRefIdx;
6550#if H_3D_NBDV_REF
6551            TComMv cMv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
6552#endif
6553            cMv.setHor( cMv.getHor() + ioffsetDV );
6554#if H_3D_IV_MERGE
6555            if( bIsDepth )
6556            {
6557              cMv.setHor((cMv.getHor()+2)>>2); 
6558            }
6559#endif
6560            cMv.setVer( 0 );
6561            pacPdmMv      [iRefListId + 2 + (iLoopCan<<2)] = cMv;
6562          }
6563          break;
6564        }
6565      }
6566    }
6567    for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6568    {
6569      availableMcDc[1 + (iLoopCan << 1)] = ( abPdmAvailable[2 + (iLoopCan<<2)] ? 1 : 0 ) + ( abPdmAvailable[3 + (iLoopCan<<2)] ? 2 : 0 );
6570    }
6571  }
6572  return false;
6573}
6574#endif
6575#if H_3D_ARP
6576Void TComDataCU::setARPWSubParts ( UChar w, UInt uiAbsPartIdx, UInt uiDepth )
6577{
6578  assert( sizeof( *m_puhARPW) == 1 );
6579  memset( m_puhARPW + uiAbsPartIdx, w, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
6580}
6581#endif
6582
6583#if H_3D_IC
6584Void TComDataCU::setICFlagSubParts( Bool bICFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
6585{
6586  memset( m_pbICFlag + uiAbsPartIdx, bICFlag, (m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ))*sizeof(Bool) );
6587}
6588
6589Bool TComDataCU::isICFlagRequired( UInt uiAbsPartIdx )
6590{
6591  UInt uiPartAddr;
6592  UInt iNumbPart;
6593
6594  if( !( getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ) )
6595  {
6596    return false;
6597  }
6598
6599  if( getSlice()->getIcSkipParseFlag() )
6600  {
6601    if( getMergeFlag( uiAbsPartIdx ) && getMergeIndex( uiAbsPartIdx ) == 0 )
6602    {
6603      return false;
6604    }
6605  }
6606
6607  if( getMergeFlag( uiAbsPartIdx ) )
6608  {
6609    return true;
6610  }
6611
6612
6613  Int iWidth, iHeight;
6614
6615  iNumbPart = ( getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ? 1 : ( getPartitionSize( uiAbsPartIdx ) == SIZE_NxN ? 4 : 2 ) );
6616
6617  for(UInt i = 0; i < iNumbPart; i++)
6618  {
6619    getPartIndexAndSize( i, uiPartAddr, iWidth, iHeight, uiAbsPartIdx, true );
6620    uiPartAddr += uiAbsPartIdx;
6621
6622    for(UInt uiRefIdx = 0; uiRefIdx < 2; uiRefIdx++)
6623    {
6624      RefPicList eRefList = uiRefIdx ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
6625      Int iBestRefIdx = getCUMvField(eRefList)->getRefIdx(uiPartAddr);
6626
6627      if( ( getInterDir( uiPartAddr ) & ( uiRefIdx+1 ) ) && iBestRefIdx >= 0 && getSlice()->getViewIndex() != getSlice()->getRefPic( eRefList, iBestRefIdx )->getViewIndex() )
6628      {
6629        return true;
6630      }
6631    }
6632  }
6633
6634  return false;
6635}
6636#endif
6637#if NH_3D_DMM
6638Void TComDataCU::setDmm1WedgeTabIdxSubParts( UInt tabIdx, UInt uiAbsPartIdx, UInt uiDepth )
6639{
6640  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
6641  for( UInt ui = 0; ui < uiCurrPartNumb; ui++ ) { m_dmm1WedgeTabIdx[uiAbsPartIdx+ui] = tabIdx; }
6642}
6643#endif
6644
6645#if H_3D_VSP
6646Void TComDataCU::setMvFieldPUForVSP( TComDataCU* pcCU, UInt partAddr, Int width, Int height, RefPicList eRefPicList, Int iRefIdx, Int &vspSize )
6647{
6648  // Get depth reference
6649  Int depthRefViewIdx = pcCU->getDvInfo(partAddr).m_aVIdxCan;
6650 
6651#if H_3D_FCO_VSP_DONBDV_E0163
6652  TComPic* pRefPicBaseDepth = 0;
6653  Bool     bIsCurrDepthCoded = false;
6654  pRefPicBaseDepth  = pcCU->getSlice()->getIvPic( true, pcCU->getSlice()->getViewIndex() );
6655  if ( pRefPicBaseDepth->getPicYuvRec() != NULL  ) 
6656  {
6657    bIsCurrDepthCoded = true;
6658  }
6659  else 
6660  {
6661    pRefPicBaseDepth = pcCU->getSlice()->getIvPic (true, depthRefViewIdx );
6662  }
6663#else
6664  TComPic* pRefPicBaseDepth = pcCU->getSlice()->getIvPic (true, depthRefViewIdx );
6665#endif
6666  assert(pRefPicBaseDepth != NULL);
6667  TComPicYuv* pcBaseViewDepthPicYuv = pRefPicBaseDepth->getPicYuvRec();
6668  assert(pcBaseViewDepthPicYuv != NULL);
6669  pcBaseViewDepthPicYuv->extendPicBorder();
6670
6671  // Get texture reference
6672  assert(iRefIdx >= 0);
6673  TComPic* pRefPicBaseTxt = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx );
6674  TComPicYuv* pcBaseViewTxtPicYuv = pRefPicBaseTxt->getPicYuvRec();
6675  assert(pcBaseViewTxtPicYuv != NULL);
6676
6677  // Initialize LUT according to the reference viewIdx
6678  Int txtRefViewIdx = pRefPicBaseTxt->getViewIndex();
6679  Int* pShiftLUT    = pcCU->getSlice()->getDepthToDisparityB( txtRefViewIdx );
6680  assert( txtRefViewIdx < pcCU->getSlice()->getViewIndex() );
6681
6682  // prepare Dv to access depth map or reference view
6683  TComMv cDv  = pcCU->getDvInfo(partAddr).m_acNBDV;
6684  pcCU->clipMv(cDv);
6685
6686#if H_3D_FCO_VSP_DONBDV_E0163
6687  if ( bIsCurrDepthCoded )
6688  {
6689      cDv.setZero();
6690  }
6691#endif
6692
6693  // fetch virtual depth map & convert depth to motion vector, which are stored in the motion memory
6694  xSetMvFieldForVSP( pcCU, pcBaseViewDepthPicYuv, &cDv, partAddr, width, height, pShiftLUT, eRefPicList, iRefIdx, pcCU->getSlice()->getIsDepth(), vspSize );
6695}
6696
6697Void TComDataCU::xSetMvFieldForVSP( TComDataCU *cu, TComPicYuv *picRefDepth, TComMv *dv, UInt partAddr, Int width, Int height, Int *shiftLUT, RefPicList refPicList, Int refIdx, Bool isDepth, Int &vspSize )
6698{
6699  TComCUMvField *cuMvField = cu->getCUMvField( refPicList );
6700  Int partAddrRasterSubPULine  = g_auiZscanToRaster[ partAddr ];
6701  Int numPartsLine    = cu->getPic()->getNumPartInWidth();
6702
6703  Int nTxtPerMvInfoX = 4; // cu->getPic()->getMinCUWidth();
6704  Int nTxtPerMvInfoY = 4; // cu->getPic()->getMinCUHeight();
6705
6706  Int refDepStride = picRefDepth->getStride();
6707
6708  TComMv tmpMv(0, 0);
6709  tmpMv.setIDVFlag(false);
6710
6711  Int refDepOffset  = ( (dv->getHor()+2) >> 2 ) + ( (dv->getVer()+2) >> 2 ) * refDepStride;
6712  Pel *refDepth     = picRefDepth->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refDepOffset;
6713
6714  if ((height % 8))
6715  {
6716    vspSize = 1; // 8x4
6717  }
6718  else if ((width % 8))
6719  {
6720    vspSize = 0; // 4x8
6721  }
6722  else
6723  {
6724    Bool ULvsBR, URvsBL;
6725    ULvsBR = refDepth[0]       < refDepth[refDepStride * (height-1) + width-1];
6726    URvsBL = refDepth[width-1] < refDepth[refDepStride * (height-1)];
6727    vspSize = ( ULvsBR ^ URvsBL ) ? 0 : 1;
6728  }
6729 
6730  Int subBlockW, subBlockH;
6731  if (vspSize)
6732  {
6733    subBlockW = 8;
6734    subBlockH = 4;
6735  }
6736  else
6737  {
6738    subBlockW = 4;
6739    subBlockH = 8;
6740  }
6741 
6742  Int numPartsInSubPUW = subBlockW / nTxtPerMvInfoX;
6743  Int numPartsInSubPUH = subBlockH / nTxtPerMvInfoY * numPartsLine;
6744
6745  for( Int y=0; y<height; y+=subBlockH, partAddrRasterSubPULine+=numPartsInSubPUH )
6746  {
6747    Pel *refDepthTmp[4];
6748    refDepthTmp[0] = refDepth + refDepStride * y;
6749    refDepthTmp[1] = refDepthTmp[0] + subBlockW - 1;
6750    refDepthTmp[2] = refDepthTmp[0] + refDepStride * (subBlockH - 1);
6751    refDepthTmp[3] = refDepthTmp[2] + subBlockW - 1;
6752
6753    Int partAddrRasterSubPU = partAddrRasterSubPULine;
6754    for( Int x=0; x<width; x+=subBlockW, partAddrRasterSubPU+=numPartsInSubPUW )
6755    {
6756      Pel  maxDepthVal;
6757      maxDepthVal = refDepthTmp[0][x];
6758      maxDepthVal = std::max( maxDepthVal, refDepthTmp[1][x]);
6759      maxDepthVal = std::max( maxDepthVal, refDepthTmp[2][x]);
6760      maxDepthVal = std::max( maxDepthVal, refDepthTmp[3][x]);
6761      tmpMv.setHor( (Short) shiftLUT[ maxDepthVal ] );
6762
6763      Int partAddrRasterPartLine = partAddrRasterSubPU;
6764      for( Int sY=0; sY<numPartsInSubPUH; sY+=numPartsLine, partAddrRasterPartLine += numPartsLine )
6765      {
6766        Int partAddrRasterPart = partAddrRasterPartLine;
6767        for( Int sX=0; sX<numPartsInSubPUW; sX+=1, partAddrRasterPart++ )
6768        {
6769          cuMvField->setMv    ( g_auiRasterToZscan[ partAddrRasterPart ], tmpMv );
6770          cuMvField->setRefIdx( g_auiRasterToZscan[ partAddrRasterPart ], refIdx );
6771        }
6772      }
6773    }
6774  }
6775
6776  vspSize = (vspSize<<2)+1;
6777
6778}
6779#endif
6780
6781//! \}
Note: See TracBrowser for help on using the repository browser.