source: 3DVCSoftware/branches/HTM-14.1-update-dev3-MediaTek/source/Lib/TLibCommon/TComDataCU.cpp @ 1217

Last change on this file since 1217 was 1217, checked in by mediatek-htm, 9 years ago

Reactive DoNBDV ( the MACRO is "NH_3D_NBDV_REF")

By Yi-Wen Chen (yiwen.chen@…)

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