source: 3DVCSoftware/branches/HTM-14.1-update-dev2-Qualcomm/source/Lib/TLibCommon/TComDataCU.cpp @ 1213

Last change on this file since 1213 was 1213, checked in by qualcomm, 9 years ago

TMVP for 3D-HEVC. Ying Chen

  • Property svn:eol-style set to native
File size: 230.0 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-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 H_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 H_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 H_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 H_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 H_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 H_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 H_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 H_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 H_3D_NBDV
1416  memcpy( rpcCU->getDvInfo()         + m_uiAbsIdxInLCU, 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 H_3D_NBDV_REF
2163    depthRefineFlag = m_pcSlice->getDepthRefinementFlag(  );
2164#endif // H_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 H_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 H_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 NH_3D_TMVP //to be changed to NH_3D_TMVP in future migration
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 H_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 H_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 H_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#if NH_3D_TMVP
4770      iRefIdx =0; 
4771#endif
4772      bExistMV = ctuRsAddr >= 0 && xGetColMVP( REF_PIC_LIST_1, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx);
4773      if( bExistMV == false )
4774      {
4775        bExistMV = xGetColMVP( REF_PIC_LIST_1, getCtuRsAddr(), uiPartIdxCenter, cColMv, iRefIdx );
4776      }
4777      if( bExistMV )
4778      {
4779        dir |= 2;
4780        pcMvFieldNeighbours[ 2 * uiArrayAddr + 1 ].setMvField( cColMv, iRefIdx );
4781      }
4782    }
4783
4784    if (dir != 0)
4785    {
4786      puhInterDirNeighbours[uiArrayAddr] = dir;
4787      abCandIsInter[uiArrayAddr] = true;
4788
4789      if ( mrgCandIdx == iCount )
4790      {
4791        return;
4792      }
4793      iCount++;
4794    }
4795  }
4796  // early termination
4797  if (iCount == getSlice()->getMaxNumMergeCand())
4798  {
4799    return;
4800  }
4801
4802  UInt uiArrayAddr = iCount;
4803  UInt uiCutoff = uiArrayAddr;
4804
4805  if ( getSlice()->isInterB() )
4806  {
4807    static const UInt NUM_PRIORITY_LIST=12;
4808    static const UInt uiPriorityList0[NUM_PRIORITY_LIST] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3};
4809    static const UInt uiPriorityList1[NUM_PRIORITY_LIST] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2};
4810
4811    for (Int idx=0; idx<uiCutoff*(uiCutoff-1) && uiArrayAddr!= getSlice()->getMaxNumMergeCand(); idx++)
4812    {
4813      assert(idx<NUM_PRIORITY_LIST);
4814      Int i = uiPriorityList0[idx];
4815      Int j = uiPriorityList1[idx];
4816      if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
4817      {
4818        abCandIsInter[uiArrayAddr] = true;
4819        puhInterDirNeighbours[uiArrayAddr] = 3;
4820
4821        // get Mv from cand[i] and cand[j]
4822        pcMvFieldNeighbours[uiArrayAddr << 1].setMvField(pcMvFieldNeighbours[i<<1].getMv(), pcMvFieldNeighbours[i<<1].getRefIdx());
4823        pcMvFieldNeighbours[( uiArrayAddr << 1 ) + 1].setMvField(pcMvFieldNeighbours[(j<<1)+1].getMv(), pcMvFieldNeighbours[(j<<1)+1].getRefIdx());
4824
4825        Int iRefPOCL0 = m_pcSlice->getRefPOC( REF_PIC_LIST_0, pcMvFieldNeighbours[(uiArrayAddr<<1)].getRefIdx() );
4826        Int iRefPOCL1 = m_pcSlice->getRefPOC( REF_PIC_LIST_1, pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getRefIdx() );
4827        if (iRefPOCL0 == iRefPOCL1 && pcMvFieldNeighbours[(uiArrayAddr<<1)].getMv() == pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getMv())
4828        {
4829          abCandIsInter[uiArrayAddr] = false;
4830        }
4831        else
4832        {
4833          uiArrayAddr++;
4834        }
4835      }
4836    }
4837  }
4838  // early termination
4839  if (uiArrayAddr == getSlice()->getMaxNumMergeCand())
4840  {
4841    return;
4842  }
4843
4844  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);
4845
4846  Int r = 0;
4847  Int refcnt = 0;
4848  while (uiArrayAddr < getSlice()->getMaxNumMergeCand())
4849  {
4850    abCandIsInter[uiArrayAddr] = true;
4851    puhInterDirNeighbours[uiArrayAddr] = 1;
4852    pcMvFieldNeighbours[uiArrayAddr << 1].setMvField( TComMv(0, 0), r);
4853
4854    if ( getSlice()->isInterB() )
4855    {
4856      puhInterDirNeighbours[uiArrayAddr] = 3;
4857      pcMvFieldNeighbours[(uiArrayAddr << 1) + 1].setMvField(TComMv(0, 0), r);
4858    }
4859    uiArrayAddr++;
4860
4861    if ( refcnt == iNumRefIdx - 1 )
4862    {
4863      r = 0;
4864    }
4865    else
4866    {
4867      ++r;
4868      ++refcnt;
4869    }
4870  }
4871  numValidMergeCand = uiArrayAddr;
4872}
4873#endif
4874
4875/** Check whether the current PU and a spatial neighboring PU are in a same ME region.
4876 * \param xN, yN   location of the upper-left corner pixel of a neighboring PU
4877 * \param xP, yP   location of the upper-left corner pixel of the current PU
4878 */
4879Bool TComDataCU::isDiffMER(Int xN, Int yN, Int xP, Int yP)
4880{
4881
4882  UInt plevel = this->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() + 2;
4883  if ((xN>>plevel)!= (xP>>plevel))
4884  {
4885    return true;
4886  }
4887  if ((yN>>plevel)!= (yP>>plevel))
4888  {
4889    return true;
4890  }
4891  return false;
4892}
4893
4894/** Calculate the location of upper-left corner pixel and size of the current PU.
4895 * \param partIdx       PU index within a CU
4896 * \param xP, yP        location of the upper-left corner pixel of the current PU
4897 * \param nPSW, nPSH    size of the current PU
4898 */
4899Void TComDataCU::getPartPosition( UInt partIdx, Int& xP, Int& yP, Int& nPSW, Int& nPSH)
4900{
4901  UInt col = m_uiCUPelX;
4902  UInt row = m_uiCUPelY;
4903
4904  switch ( m_pePartSize[0] )
4905  {
4906  case SIZE_2NxN:
4907    nPSW = getWidth(0);
4908    nPSH = getHeight(0) >> 1;
4909    xP   = col;
4910    yP   = (partIdx ==0)? row: row + nPSH;
4911    break;
4912  case SIZE_Nx2N:
4913    nPSW = getWidth(0) >> 1;
4914    nPSH = getHeight(0);
4915    xP   = (partIdx ==0)? col: col + nPSW;
4916    yP   = row;
4917    break;
4918  case SIZE_NxN:
4919    nPSW = getWidth(0) >> 1;
4920    nPSH = getHeight(0) >> 1;
4921    xP   = col + (partIdx&0x1)*nPSW;
4922    yP   = row + (partIdx>>1)*nPSH;
4923    break;
4924  case SIZE_2NxnU:
4925    nPSW = getWidth(0);
4926    nPSH = ( partIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
4927    xP   = col;
4928    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
4929
4930    break;
4931  case SIZE_2NxnD:
4932    nPSW = getWidth(0);
4933    nPSH = ( partIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
4934    xP   = col;
4935    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
4936    break;
4937  case SIZE_nLx2N:
4938    nPSW = ( partIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
4939    nPSH = getHeight(0);
4940    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
4941    yP   = row;
4942    break;
4943  case SIZE_nRx2N:
4944    nPSW = ( partIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
4945    nPSH = getHeight(0);
4946    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
4947    yP   = row;
4948    break;
4949  default:
4950    assert ( m_pePartSize[0] == SIZE_2Nx2N );
4951    nPSW = getWidth(0);
4952    nPSH = getHeight(0);
4953    xP   = col ;
4954    yP   = row ;
4955
4956    break;
4957  }
4958}
4959
4960/** Constructs a list of candidates for AMVP
4961 * \param uiPartIdx
4962 * \param uiPartAddr
4963 * \param eRefPicList
4964 * \param iRefIdx
4965 * \param pInfo
4966 */
4967Void TComDataCU::fillMvpCand ( UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, AMVPInfo* pInfo )
4968{
4969  TComMv cMvPred;
4970  Bool bAddedSmvp = false;
4971
4972  pInfo->iN = 0;
4973  if (iRefIdx < 0)
4974  {
4975    return;
4976  }
4977
4978  //-- Get Spatial MV
4979  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
4980  const UInt numPartInCtuWidth  = m_pcPic->getNumPartInCtuWidth();
4981  const UInt numPartInCtuHeight = m_pcPic->getNumPartInCtuHeight();
4982  Bool bAdded = false;
4983
4984  deriveLeftRightTopIdx( uiPartIdx, uiPartIdxLT, uiPartIdxRT );
4985  deriveLeftBottomIdx( uiPartIdx, uiPartIdxLB );
4986
4987  TComDataCU* tmpCU = NULL;
4988  UInt idx;
4989  tmpCU = getPUBelowLeft(idx, uiPartIdxLB);
4990  bAddedSmvp = (tmpCU != NULL) && (tmpCU->isInter(idx));
4991
4992  if (!bAddedSmvp)
4993  {
4994    tmpCU = getPULeft(idx, uiPartIdxLB);
4995    bAddedSmvp = (tmpCU != NULL) && (tmpCU->isInter(idx));
4996  }
4997
4998  // Left predictor search
4999  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
5000  if (!bAdded)
5001  {
5002    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
5003  }
5004
5005  if(!bAdded)
5006  {
5007    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
5008    if (!bAdded)
5009    {
5010      xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
5011    }
5012  }
5013
5014  // Above predictor search
5015  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
5016
5017  if (!bAdded)
5018  {
5019    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
5020  }
5021
5022  if(!bAdded)
5023  {
5024    xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
5025  }
5026
5027  if(!bAddedSmvp)
5028  {
5029    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
5030    if (!bAdded)
5031    {
5032      bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
5033    }
5034
5035    if(!bAdded)
5036    {
5037      xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
5038    }
5039  }
5040
5041  if ( pInfo->iN == 2 )
5042  {
5043    if ( pInfo->m_acMvCand[ 0 ] == pInfo->m_acMvCand[ 1 ] )
5044    {
5045      pInfo->iN = 1;
5046    }
5047  }
5048
5049  if ( getSlice()->getEnableTMVPFlag() )
5050  {
5051    // Get Temporal Motion Predictor
5052    Int iRefIdx_Col = iRefIdx;
5053    TComMv cColMv;
5054    UInt uiPartIdxRB;
5055    UInt uiAbsPartIdx;
5056    UInt uiAbsPartAddr;
5057
5058    deriveRightBottomIdx( uiPartIdx, uiPartIdxRB );
5059    uiAbsPartAddr = m_absZIdxInCtu + uiPartAddr;
5060
5061    //----  co-located RightBottom Temporal Predictor (H) ---//
5062    uiAbsPartIdx = g_auiZscanToRaster[uiPartIdxRB];
5063    Int ctuRsAddr = -1;
5064    if (  ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdx] + m_pcPic->getMinCUWidth () ) < m_pcSlice->getSPS()->getPicWidthInLumaSamples () )  // image boundary check
5065       && ( ( m_pcPic->getCtu(m_ctuRsAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdx] + m_pcPic->getMinCUHeight() ) < m_pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
5066    {
5067      if ( ( uiAbsPartIdx % numPartInCtuWidth < numPartInCtuWidth - 1 ) &&  // is not at the last column of CTU
5068           ( uiAbsPartIdx / numPartInCtuWidth < numPartInCtuHeight - 1 ) )  // is not at the last row    of CTU
5069      {
5070        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + numPartInCtuWidth + 1 ];
5071        ctuRsAddr = getCtuRsAddr();
5072      }
5073      else if ( uiAbsPartIdx % numPartInCtuWidth < numPartInCtuWidth - 1 )  // is not at the last column of CTU But is last row of CTU
5074      {
5075        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdx + numPartInCtuWidth + 1) % m_pcPic->getNumPartitionsInCtu() ];
5076      }
5077      else if ( uiAbsPartIdx / numPartInCtuWidth < numPartInCtuHeight - 1 ) // is not at the last row of CTU But is last column of CTU
5078      {
5079        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + 1 ];
5080        ctuRsAddr = getCtuRsAddr() + 1;
5081      }
5082      else //is the right bottom corner of CTU
5083      {
5084        uiAbsPartAddr = 0;
5085      }
5086    }
5087    if ( ctuRsAddr >= 0 && xGetColMVP( eRefPicList, ctuRsAddr, uiAbsPartAddr, cColMv, iRefIdx_Col
5088#if NH_3D_TMVP
5089         , 0
5090#endif
5091 ) )
5092    {
5093      pInfo->m_acMvCand[pInfo->iN++] = cColMv;
5094    }
5095    else
5096    {
5097      UInt uiPartIdxCenter;
5098      xDeriveCenterIdx( uiPartIdx, uiPartIdxCenter );
5099      if (xGetColMVP( eRefPicList, getCtuRsAddr(), uiPartIdxCenter,  cColMv, iRefIdx_Col
5100#if NH_3D_TMVP
5101         , 0
5102#endif
5103))
5104      {
5105        pInfo->m_acMvCand[pInfo->iN++] = cColMv;
5106      }
5107    }
5108    //----  co-located RightBottom Temporal Predictor  ---//
5109  }
5110
5111  if (pInfo->iN > AMVP_MAX_NUM_CANDS)
5112  {
5113    pInfo->iN = AMVP_MAX_NUM_CANDS;
5114  }
5115
5116  while (pInfo->iN < AMVP_MAX_NUM_CANDS)
5117  {
5118    pInfo->m_acMvCand[pInfo->iN].set(0,0);
5119    pInfo->iN++;
5120  }
5121  return ;
5122}
5123
5124
5125Bool TComDataCU::isBipredRestriction(UInt puIdx)
5126{
5127  Int width = 0;
5128  Int height = 0;
5129  UInt partAddr;
5130
5131#if H_3D_DBBP
5132  if( getDBBPFlag(0) )
5133  {
5134    return true;
5135  }
5136#endif
5137
5138  getPartIndexAndSize( puIdx, partAddr, width, height );
5139  if ( getWidth(0) == 8 && (width < 8 || height < 8) )
5140  {
5141    return true;
5142  }
5143  return false;
5144}
5145
5146
5147Void TComDataCU::clipMv    (TComMv&  rcMv)
5148{
5149  const TComSPS &sps=*(m_pcSlice->getSPS());
5150  Int  iMvShift = 2;
5151#if H_3D_IC
5152  if( getSlice()->getIsDepth() )
5153    iMvShift = 0;
5154#endif
5155
5156  Int iOffset = 8;
5157  Int iHorMax = ( sps.getPicWidthInLumaSamples() + iOffset - (Int)m_uiCUPelX - 1 ) << iMvShift;
5158  Int iHorMin = (      -(Int)sps.getMaxCUWidth() - iOffset - (Int)m_uiCUPelX + 1 ) << iMvShift;
5159
5160  Int iVerMax = ( sps.getPicHeightInLumaSamples() + iOffset - (Int)m_uiCUPelY - 1 ) << iMvShift;
5161  Int iVerMin = (      -(Int)sps.getMaxCUHeight() - iOffset - (Int)m_uiCUPelY + 1 ) << iMvShift;
5162
5163  rcMv.setHor( min (iHorMax, max (iHorMin, rcMv.getHor())) );
5164  rcMv.setVer( min (iVerMax, max (iVerMin, rcMv.getVer())) );
5165}
5166
5167#if NH_MV
5168Void TComDataCU::checkMvVertRest (TComMv&  rcMv,  RefPicList eRefPicList, int iRefIdx )
5169{
5170  if ( getSlice()->getSPS()->getInterViewMvVertConstraintFlag() )
5171  {
5172    if ( getSlice()->getRefPic( eRefPicList, iRefIdx )->getPOC() == getSlice()->getPOC() )
5173    {
5174        //When inter_view_mv_vert_constraint_flag is equal to 1,
5175        //the vertical component of the motion vectors used for inter-layer prediction
5176        //shall be equal to or less than 56 in units of luma samples
5177        assert ( rcMv.getVer() <= (56<<2) );
5178    }
5179  }
5180}
5181#endif
5182
5183UInt TComDataCU::getIntraSizeIdx(UInt uiAbsPartIdx)
5184{
5185  UInt uiShift = ( m_pePartSize[uiAbsPartIdx]==SIZE_NxN ? 1 : 0 );
5186
5187  UChar uiWidth = m_puhWidth[uiAbsPartIdx]>>uiShift;
5188  UInt  uiCnt = 0;
5189  while( uiWidth )
5190  {
5191    uiCnt++;
5192    uiWidth>>=1;
5193  }
5194  uiCnt-=2;
5195  return uiCnt > 6 ? 6 : uiCnt;
5196}
5197
5198Void TComDataCU::clearCbf( UInt uiIdx, ComponentID compID, UInt uiNumParts )
5199{
5200  memset( &m_puhCbf[compID][uiIdx], 0, sizeof(UChar)*uiNumParts);
5201}
5202
5203/** Set a I_PCM flag for all sub-partitions of a partition.
5204 * \param bIpcmFlag I_PCM flag
5205 * \param uiAbsPartIdx patition index
5206 * \param uiDepth CU depth
5207 * \returns Void
5208 */
5209Void TComDataCU::setIPCMFlagSubParts  (Bool bIpcmFlag, UInt uiAbsPartIdx, UInt uiDepth)
5210{
5211  UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
5212
5213  memset(m_pbIPCMFlag + uiAbsPartIdx, bIpcmFlag, sizeof(Bool)*uiCurrPartNumb );
5214}
5215
5216/** Test whether the block at uiPartIdx is skipped.
5217 * \param uiPartIdx Partition index
5218 * \returns true if the current the block is skipped
5219 */
5220Bool TComDataCU::isSkipped( UInt uiPartIdx )
5221{
5222  return ( getSkipFlag( uiPartIdx ) );
5223}
5224
5225#if H_3D_IC
5226Bool TComDataCU::isIC( UInt uiPartIdx )
5227{
5228    if ( m_pcSlice->isIntra () )
5229    {
5230        return false;
5231    }
5232    return ( ( getSkipFlag(uiPartIdx) || getPredictionMode(uiPartIdx) == MODE_INTER) && getICFlag( uiPartIdx ) && isICFlagRequired( uiPartIdx ) );
5233}
5234#endif
5235
5236// ====================================================================================================================
5237// Protected member functions
5238// ====================================================================================================================
5239
5240Bool TComDataCU::xAddMVPCand( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
5241{
5242  TComDataCU* pcTmpCU = NULL;
5243  UInt uiIdx;
5244  switch( eDir )
5245  {
5246    case MD_LEFT:
5247    {
5248      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
5249      break;
5250    }
5251    case MD_ABOVE:
5252    {
5253      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx);
5254      break;
5255    }
5256    case MD_ABOVE_RIGHT:
5257    {
5258      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
5259      break;
5260    }
5261    case MD_BELOW_LEFT:
5262    {
5263      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
5264      break;
5265    }
5266    case MD_ABOVE_LEFT:
5267    {
5268      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
5269      break;
5270    }
5271    default:
5272    {
5273      break;
5274    }
5275  }
5276
5277  if ( pcTmpCU == NULL )
5278  {
5279    return false;
5280  }
5281
5282  if ( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0 && m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC() == pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ))
5283  {
5284    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
5285
5286    pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
5287    return true;
5288  }
5289
5290  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
5291  if(       eRefPicList == REF_PIC_LIST_0 )
5292  {
5293    eRefPicList2nd = REF_PIC_LIST_1;
5294  }
5295  else if ( eRefPicList == REF_PIC_LIST_1)
5296  {
5297    eRefPicList2nd = REF_PIC_LIST_0;
5298  }
5299
5300
5301  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
5302  Int iNeibRefPOC;
5303
5304
5305  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0 )
5306  {
5307    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
5308    if( iNeibRefPOC == iCurrRefPOC ) // Same Reference Frame But Diff List//
5309    {
5310      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
5311      pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
5312      return true;
5313    }
5314  }
5315  return false;
5316}
5317
5318/**
5319 * \param pInfo
5320 * \param eRefPicList
5321 * \param iRefIdx
5322 * \param uiPartUnitIdx
5323 * \param eDir
5324 * \returns Bool
5325 */
5326Bool TComDataCU::xAddMVPCandOrder( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
5327{
5328  TComDataCU* pcTmpCU = NULL;
5329  UInt uiIdx;
5330  switch( eDir )
5331  {
5332  case MD_LEFT:
5333    {
5334      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
5335      break;
5336    }
5337  case MD_ABOVE:
5338    {
5339      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx);
5340      break;
5341    }
5342  case MD_ABOVE_RIGHT:
5343    {
5344      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
5345      break;
5346    }
5347  case MD_BELOW_LEFT:
5348    {
5349      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
5350      break;
5351    }
5352  case MD_ABOVE_LEFT:
5353    {
5354      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
5355      break;
5356    }
5357  default:
5358    {
5359      break;
5360    }
5361  }
5362
5363  if ( pcTmpCU == NULL )
5364  {
5365    return false;
5366  }
5367
5368  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
5369  if(       eRefPicList == REF_PIC_LIST_0 )
5370  {
5371    eRefPicList2nd = REF_PIC_LIST_1;
5372  }
5373  else if ( eRefPicList == REF_PIC_LIST_1)
5374  {
5375    eRefPicList2nd = REF_PIC_LIST_0;
5376  }
5377
5378  Int iCurrPOC = m_pcSlice->getPOC();
5379  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
5380  Int iNeibPOC = iCurrPOC;
5381  Int iNeibRefPOC;
5382  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getIsLongTerm();
5383  Bool bIsNeibRefLongTerm = false;
5384
5385  //---------------  V1 (END) ------------------//
5386  if( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0)
5387  {
5388    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) );
5389    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
5390    TComMv rcMv;
5391
5392    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) )->getIsLongTerm();
5393    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm )
5394    {
5395      if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
5396      {
5397        rcMv = cMvPred;
5398      }
5399      else
5400      {
5401        Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
5402        if ( iScale == 4096 )
5403        {
5404          rcMv = cMvPred;
5405        }
5406        else
5407        {
5408          rcMv = cMvPred.scaleMv( iScale );
5409        }
5410      }
5411
5412      pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
5413      return true;
5414    }
5415  }
5416  //---------------------- V2(END) --------------------//
5417  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0)
5418  {
5419    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
5420    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
5421    TComMv rcMv;
5422
5423    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) )->getIsLongTerm();
5424    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm )
5425    {
5426      if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
5427      {
5428        rcMv = cMvPred;
5429      }
5430      else
5431      {
5432        Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
5433        if ( iScale == 4096 )
5434        {
5435          rcMv = cMvPred;
5436        }
5437        else
5438        {
5439          rcMv = cMvPred.scaleMv( iScale );
5440        }
5441      }
5442
5443      pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
5444      return true;
5445    }
5446  }
5447  //---------------------- V3(END) --------------------//
5448  return false;
5449}
5450
5451Bool TComDataCU::xGetColMVP( RefPicList eRefPicList, Int ctuRsAddr, Int uiPartUnitIdx, TComMv& rcMv, Int& riRefIdx
5452#if NH_3D_TMVP
5453  , Bool bMRG
5454#endif
5455)
5456{
5457  UInt uiAbsPartAddr = uiPartUnitIdx;
5458
5459  RefPicList  eColRefPicList;
5460  Int iColPOC, iColRefPOC, iCurrPOC, iCurrRefPOC, iScale;
5461  TComMv cColMv;
5462
5463  // use coldir.
5464  TComPic *pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());
5465  TComDataCU *pColCtu = pColPic->getCtu( ctuRsAddr );
5466  if(pColCtu->getPic()==0||pColCtu->getPartitionSize(uiPartUnitIdx)==NUMBER_OF_PART_SIZES)
5467  {
5468    return false;
5469  }
5470  iCurrPOC = m_pcSlice->getPOC();
5471  iColPOC = pColCtu->getSlice()->getPOC();
5472
5473  if (!pColCtu->isInter(uiAbsPartAddr))
5474  {
5475    return false;
5476  }
5477
5478  eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());
5479
5480  Int iColRefIdx = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
5481
5482  if (iColRefIdx < 0 )
5483  {
5484    eColRefPicList = RefPicList(1 - eColRefPicList);
5485    iColRefIdx = pColCtu->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
5486
5487    if (iColRefIdx < 0 )
5488    {
5489      return false;
5490    }
5491  }
5492
5493  // Scale the vector.
5494  iColRefPOC = pColCtu->getSlice()->getRefPOC(eColRefPicList, iColRefIdx);
5495  cColMv = pColCtu->getCUMvField(eColRefPicList)->getMv(uiAbsPartAddr);
5496
5497  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
5498
5499  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();
5500  Bool bIsColRefLongTerm = pColCtu->getSlice()->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
5501
5502  if ( bIsCurrRefLongTerm != bIsColRefLongTerm )
5503  {
5504#if NH_3D_TMVP
5505    Int iAlterRefIdx  = m_pcSlice->getAlterRefIdx(eRefPicList);
5506    if(bMRG && iAlterRefIdx > 0)
5507    {
5508      riRefIdx = iAlterRefIdx;
5509      bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();
5510      iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
5511      assert(bIsCurrRefLongTerm == bIsColRefLongTerm);
5512    }
5513    else
5514    {
5515#endif
5516    return false;
5517#if NH_3D_TMVP
5518    }
5519#endif
5520  }
5521
5522  if ( bIsCurrRefLongTerm || bIsColRefLongTerm )
5523  {
5524#if NH_3D_TMVP
5525    Int iCurrViewId    = m_pcSlice->getViewId (); 
5526    Int iCurrRefViewId = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getViewId (); 
5527    Int iColViewId     = pColCtu->getSlice()->getViewId(); 
5528    Int iColRefViewId  = pColCtu->getSlice()->getRefPic( eColRefPicList, pColCtu->getCUMvField(eColRefPicList)->getRefIdx(uiAbsPartAddr))->getViewId(); 
5529    iScale = 4096;
5530    if ( iCurrRefViewId != iCurrViewId && iColViewId != iColRefViewId )
5531    {
5532      iScale = xGetDistScaleFactor( iCurrViewId, iCurrRefViewId, iColViewId, iColRefViewId );
5533    }
5534    if ( bMRG && iScale != 4096 && m_pcSlice->getIvMvScalingFlag( ) ) 
5535    {
5536      rcMv = cColMv.scaleMv( iScale );
5537    }
5538    else
5539    {
5540#endif
5541    rcMv = cColMv;
5542#if NH_3D_TMVP
5543    }
5544#endif
5545  }
5546  else
5547  {
5548    iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iColPOC, iColRefPOC);
5549    if ( iScale == 4096 )
5550    {
5551      rcMv = cColMv;
5552    }
5553    else
5554    {
5555      rcMv = cColMv.scaleMv( iScale );
5556    }
5557  }
5558
5559  return true;
5560}
5561
5562Int TComDataCU::xGetDistScaleFactor(Int iCurrPOC, Int iCurrRefPOC, Int iColPOC, Int iColRefPOC)
5563{
5564  Int iDiffPocD = iColPOC - iColRefPOC;
5565  Int iDiffPocB = iCurrPOC - iCurrRefPOC;
5566
5567  if( iDiffPocD == iDiffPocB )
5568  {
5569    return 4096;
5570  }
5571  else
5572  {
5573    Int iTDB      = Clip3( -128, 127, iDiffPocB );
5574    Int iTDD      = Clip3( -128, 127, iDiffPocD );
5575    Int iX        = (0x4000 + abs(iTDD/2)) / iTDD;
5576    Int iScale    = Clip3( -4096, 4095, (iTDB * iX + 32) >> 6 );
5577    return iScale;
5578  }
5579}
5580
5581Void TComDataCU::xDeriveCenterIdx( UInt uiPartIdx, UInt& ruiPartIdxCenter )
5582{
5583  UInt uiPartAddr;
5584  Int  iPartWidth;
5585  Int  iPartHeight;
5586  getPartIndexAndSize( uiPartIdx, uiPartAddr, iPartWidth, iPartHeight);
5587
5588  ruiPartIdxCenter = m_absZIdxInCtu+uiPartAddr; // partition origin.
5589  ruiPartIdxCenter = g_auiRasterToZscan[ g_auiZscanToRaster[ ruiPartIdxCenter ]
5590                                        + ( iPartHeight/m_pcPic->getMinCUHeight()  )/2*m_pcPic->getNumPartInCtuWidth()
5591                                        + ( iPartWidth/m_pcPic->getMinCUWidth()  )/2];
5592}
5593
5594#if NH_3D
5595Void TComDataCU::compressMV(Int scale)
5596{
5597   Int scaleFactor = (4 / scale ) * AMVP_DECIMATION_FACTOR / m_unitSize;
5598#else
5599Void TComDataCU::compressMV()
5600{
5601  Int scaleFactor = 4 * AMVP_DECIMATION_FACTOR / m_unitSize;
5602#endif
5603  if (scaleFactor > 0)
5604  {
5605    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
5606    {
5607      m_acCUMvField[i].compress(m_pePredMode, scaleFactor);
5608    }
5609  }
5610}
5611
5612UInt TComDataCU::getCoefScanIdx(const UInt uiAbsPartIdx, const UInt uiWidth, const UInt uiHeight, const ComponentID compID) const
5613{
5614  //------------------------------------------------
5615
5616  //this mechanism is available for intra only
5617
5618  if (!isIntra(uiAbsPartIdx))
5619  {
5620    return SCAN_DIAG;
5621  }
5622
5623  //------------------------------------------------
5624
5625  //check that MDCS can be used for this TU
5626
5627  const ChromaFormat format = getPic()->getChromaFormat();
5628
5629  const UInt maximumWidth  = MDCS_MAXIMUM_WIDTH  >> getComponentScaleX(compID, format);
5630  const UInt maximumHeight = MDCS_MAXIMUM_HEIGHT >> getComponentScaleY(compID, format);
5631
5632  if ((uiWidth > maximumWidth) || (uiHeight > maximumHeight))
5633  {
5634    return SCAN_DIAG;
5635  }
5636
5637  //------------------------------------------------
5638
5639  //otherwise, select the appropriate mode
5640
5641  UInt uiDirMode  = getIntraDir(toChannelType(compID), uiAbsPartIdx);
5642
5643#if H_3D_DIM
5644    mapDepthModeToIntraDir( uiDirMode );
5645#endif
5646
5647  if (uiDirMode==DM_CHROMA_IDX)
5648  {
5649    const TComSPS *sps=getSlice()->getSPS();
5650    const UInt partsPerMinCU = 1<<(2*(sps->getMaxTotalCUDepth() - sps->getLog2DiffMaxMinCodingBlockSize()));
5651    uiDirMode = getIntraDir(CHANNEL_TYPE_LUMA, getChromasCorrespondingPULumaIdx(uiAbsPartIdx, getPic()->getChromaFormat(), partsPerMinCU));
5652#if H_3D_DIM
5653      mapDepthModeToIntraDir( uiDirMode );
5654#endif
5655  }
5656
5657  if (isChroma(compID) && (format == CHROMA_422))
5658  {
5659    uiDirMode = g_chroma422IntraAngleMappingTable[uiDirMode];
5660  }
5661
5662  //------------------
5663
5664  if      (abs((Int)uiDirMode - VER_IDX) <= MDCS_ANGLE_LIMIT)
5665  {
5666    return SCAN_HOR;
5667  }
5668  else if (abs((Int)uiDirMode - HOR_IDX) <= MDCS_ANGLE_LIMIT)
5669  {
5670    return SCAN_VER;
5671  }
5672  else
5673  {
5674    return SCAN_DIAG;
5675  }
5676}
5677
5678#if NH_3D_VSO
5679Void TComDataCU::getPosInPic( UInt uiAbsPartIndex, Int& riPosX, Int& riPosY ) const
5680{
5681  riPosX = g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelX();
5682  riPosY = g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelY(); 
5683}
5684#endif
5685
5686#if H_3D_IV_MERGE
5687Void TComDataCU::getDispforDepth (UInt uiPartIdx, UInt uiPartAddr, DisInfo* pDisp)
5688{
5689  assert(getPartitionSize( uiPartAddr ) == SIZE_2Nx2N);
5690
5691  TComMv cMv; 
5692  if ( getSlice()->getDefaultRefViewIdxAvailableFlag() )
5693  {
5694    Int iViewIdx = getSlice()->getDefaultRefViewIdx();
5695    pDisp->m_aVIdxCan = iViewIdx;
5696    Int iDisp     = getSlice()->getDepthToDisparityB( iViewIdx )[ (Int64) (1 << ( getSlice()->getSPS()->getBitDepthY() - 1 )) ];
5697
5698    cMv.setHor(iDisp);
5699    cMv.setVer(0);
5700    pDisp->m_acNBDV = cMv;
5701    pDisp->m_aVIdxCan = iViewIdx;
5702  }
5703}
5704#endif
5705
5706#if H_3D
5707Bool TComDataCU::getNeighDepth ( UInt uiPartIdx, UInt uiPartAddr, Pel* pNeighDepth, Int index )
5708{
5709  UInt  uiPartIdxLT, uiPartIdxRT;
5710  this->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, 0, 0 );
5711  UInt uiMidPart, uiPartNeighbor; 
5712  TComDataCU* pcCUNeighbor;
5713  Bool bDepAvail = false;
5714  Pel *pDepth  = this->getPic()->getPicYuvRec()->getLumaAddr();
5715  Int iDepStride =  this->getPic()->getPicYuvRec()->getStride();
5716
5717  Int xP, yP, nPSW, nPSH;
5718  this->getPartPosition( uiPartIdx, xP, yP, nPSW, nPSH );
5719
5720  switch( index )
5721  {
5722  case 0: // Mid Left
5723    uiMidPart = g_auiZscanToRaster[uiPartIdxLT] + (nPSH>>1) / this->getPic()->getMinCUHeight() * this->getPic()->getNumPartInWidth();
5724    pcCUNeighbor = this->getPULeft( uiPartNeighbor, g_auiRasterToZscan[uiMidPart] );
5725    if ( pcCUNeighbor )
5726    {
5727      if( !this->getSlice()->getPPS()->getConstrainedIntraPred() )
5728      {
5729        *pNeighDepth = pDepth[ (yP+(nPSH>>1)) * iDepStride + (xP-1) ];
5730        bDepAvail = true;
5731      }
5732      else if ( pcCUNeighbor->getPredictionMode( uiPartNeighbor ) == MODE_INTRA )
5733      {
5734        *pNeighDepth = pDepth[ (yP+(nPSH>>1)) * iDepStride + (xP-1) ];
5735        bDepAvail = true;
5736      }
5737    }
5738    break;
5739  case 1: // Mid Above
5740    uiMidPart = g_auiZscanToRaster[uiPartIdxLT] + (nPSW>>1) / this->getPic()->getMinCUWidth();
5741    pcCUNeighbor = this->getPUAbove( uiPartNeighbor, g_auiRasterToZscan[uiMidPart] );
5742    if( pcCUNeighbor )
5743    {
5744      if( !this->getSlice()->getPPS()->getConstrainedIntraPred() )
5745      {
5746        *pNeighDepth = pDepth[ (yP-1) * iDepStride + (xP + (nPSW>>1)) ];
5747        bDepAvail = true;
5748      }
5749      else if ( pcCUNeighbor->getPredictionMode( uiPartNeighbor ) == MODE_INTRA )
5750      {
5751        *pNeighDepth = pDepth[ (yP-1) * iDepStride + (xP + (nPSW>>1)) ];
5752        bDepAvail = true;
5753      }
5754    }
5755    break;
5756  default:
5757    break;
5758  }
5759
5760  return bDepAvail;
5761}
5762#endif
5763#if H_3D_NBDV
5764//Notes from QC:
5765//TBD#1: DoNBDV related contributions are just partially integrated under the marco of H_3D_NBDV_REF, remove this comment once DoNBDV and BVSP are done
5766//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
5767//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
5768Void TComDataCU::getDisMvpCandNBDV( DisInfo* pDInfo
5769#if H_3D_NBDV_REF
5770, Bool bDepthRefine
5771#endif
5772)
5773{
5774  //// ******* Init variables ******* /////
5775  // Init disparity struct for results
5776  pDInfo->m_aVIdxCan = -1;
5777
5778  // Init struct for disparities from MCP neighboring blocks
5779  IDVInfo cIDVInfo;
5780  cIDVInfo.m_bFound = false; 
5781  UInt uiPartIdx = 0;
5782  UInt uiPartAddr = 0;
5783  for (UInt iCurDvMcpCand = 0; iCurDvMcpCand < IDV_CANDS; iCurDvMcpCand++)
5784  {
5785    for (UInt iList = 0; iList < 2; iList++)
5786    {
5787      cIDVInfo.m_acMvCand[iList][iCurDvMcpCand].setZero();
5788      cIDVInfo.m_aVIdxCan[iList][iCurDvMcpCand] = 0; 
5789      cIDVInfo.m_bAvailab[iList][iCurDvMcpCand] = false; 
5790    }
5791  }
5792#if H_3D_NBDV_REF
5793  if( !m_pcSlice->getDepthRefinementFlag( ) )
5794  {
5795    bDepthRefine = false;
5796  }
5797#endif
5798  // Get Positions 
5799  PartSize eCUMode    = getPartitionSize( uiPartAddr );   
5800  assert(eCUMode == SIZE_2Nx2N);
5801  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB; 
5802
5803  deriveLeftRightTopIdxGeneral(uiPartAddr, uiPartIdx, uiPartIdxLT, uiPartIdxRT );
5804  deriveLeftBottomIdxGeneral  (uiPartAddr, uiPartIdx, uiPartIdxLB );
5805
5806  //// ******* Get disparity from temporal neighboring blocks ******* /////
5807  if ( getSlice()->getEnableTMVPFlag() )
5808  {
5809    TComMv cColMv;
5810    Int iTargetViewIdx = 0;
5811    Int iTStartViewIdx = 0;   
5812
5813    ///*** Derive center position ***
5814    UInt uiPartIdxCenter;
5815    Int  uiLCUIdx   = getAddr();
5816    xDeriveCenterIdx(uiPartIdx, uiPartIdxCenter );
5817
5818    ///*** Search temporal candidate pictures for disparity vector ***
5819    const Int iNumCandPics = getPic()->getNumDdvCandPics();
5820    for(Int curCandPic = 0; curCandPic < iNumCandPics; curCandPic++)
5821    {
5822      RefPicList eCurRefPicList   = REF_PIC_LIST_0 ;
5823      Int        curCandPicRefIdx = 0;
5824      if( curCandPic == 0 ) 
5825      { 
5826        eCurRefPicList   = RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0);
5827        curCandPicRefIdx = getSlice()->getColRefIdx();
5828      }
5829      else                 
5830      {
5831        eCurRefPicList   = getPic()->getRapRefList();
5832        curCandPicRefIdx = getPic()->getRapRefIdx();
5833      }
5834
5835      Bool bCheck = xGetColDisMV( curCandPic, eCurRefPicList, curCandPicRefIdx, uiLCUIdx,   uiPartIdxCenter,  cColMv, iTargetViewIdx, iTStartViewIdx );
5836
5837      if( bCheck )
5838      {
5839        pDInfo->m_acNBDV = cColMv;
5840        pDInfo->m_aVIdxCan  = iTargetViewIdx;
5841
5842#if H_3D_NBDV_REF
5843        TComPic* picDepth = NULL;   
5844#if H_3D_FCO_VSP_DONBDV_E0163
5845        picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
5846        if ( picDepth->getPicYuvRec() != NULL  ) 
5847        {
5848          cColMv.setZero();
5849        }
5850        else // Go back with virtual depth
5851        {
5852          picDepth = getSlice()->getIvPic( true, iTargetViewIdx );
5853        }
5854
5855        assert(picDepth != NULL);
5856#else
5857        picDepth = getSlice()->getIvPic( true, iTargetViewIdx );
5858#endif
5859        if (picDepth && bDepthRefine)
5860        {
5861          estimateDVFromDM(iTargetViewIdx, uiPartIdx, picDepth, uiPartAddr, &cColMv );
5862        }
5863        pDInfo->m_acDoNBDV  = cColMv;
5864#endif //H_3D_NBDV_REF
5865        return;
5866      }
5867    }
5868  } 
5869
5870  UInt uiIdx = 0;
5871  Bool        bCheckMcpDv = false;   
5872  TComDataCU* pcTmpCU     = NULL;
5873
5874  //// ******* Get disparity from left block ******* /////
5875  pcTmpCU = getPULeft(uiIdx, uiPartIdxLB, true, false);
5876  bCheckMcpDv = true; 
5877  if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_LEFT
5878#if H_3D_NBDV_REF
5879    , bDepthRefine
5880#endif
5881    ) )
5882    return;
5883
5884  //// ******* Get disparity from above block ******* /////
5885  pcTmpCU = getPUAbove(uiIdx, uiPartIdxRT, true, false, true);
5886  if(pcTmpCU != NULL )
5887  {
5888    bCheckMcpDv = ( ( getAddr() - pcTmpCU->getAddr() ) == 0);
5889    if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_ABOVE
5890#if H_3D_NBDV_REF
5891      , bDepthRefine
5892#endif
5893      ) )
5894      return;
5895  }
5896
5897  //// ******* Search MCP blocks ******* /////
5898  if( cIDVInfo.m_bFound ) 
5899  {
5900    for( Int curPos = 0 ; curPos < IDV_CANDS ; curPos++ ) 
5901    {
5902      for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
5903      {
5904        if( cIDVInfo.m_bAvailab[iList][curPos] )
5905        {
5906          TComMv cDispVec = cIDVInfo.m_acMvCand[iList][ curPos ];
5907          pDInfo->m_acNBDV = cDispVec;
5908          pDInfo->m_aVIdxCan = cIDVInfo.m_aVIdxCan[iList][ curPos ];
5909#if H_3D_NBDV_REF
5910#if H_3D_FCO_VSP_DONBDV_E0163
5911          TComPic* picDepth  = NULL;
5912
5913          picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
5914          if ( picDepth->getPicYuvRec() != NULL ) 
5915          {
5916            cDispVec.setZero();
5917          }
5918          else // Go back with virtual depth
5919          {
5920            picDepth = getSlice()->getIvPic( true, pDInfo->m_aVIdxCan );
5921          }
5922
5923          assert(picDepth != NULL);
5924#else
5925          TComPic* picDepth = getSlice()->getIvPic( true, pDInfo->m_aVIdxCan );
5926#endif
5927
5928          if (picDepth && bDepthRefine)
5929          {
5930            estimateDVFromDM (pDInfo->m_aVIdxCan, uiPartIdx, picDepth, uiPartAddr, &cDispVec);
5931          }
5932          pDInfo->m_acDoNBDV = cDispVec;
5933#endif
5934          return;
5935        }
5936      }
5937    }
5938  }
5939
5940  TComMv defaultDV(0, 0);
5941  pDInfo->m_acNBDV = defaultDV;
5942
5943  if (getSlice()->getDefaultRefViewIdxAvailableFlag())
5944  {
5945    pDInfo->m_aVIdxCan = getSlice()->getDefaultRefViewIdx();
5946
5947#if H_3D_NBDV_REF
5948    TComPic* picDepth = NULL;
5949#if H_3D_FCO_VSP_DONBDV_E0163
5950    picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
5951    if ( picDepth->getPicYuvRec() != NULL ) 
5952    {
5953      defaultDV.setZero();
5954    }
5955    else // Go back with virtual depth
5956    {
5957      picDepth = getSlice()->getIvPic( true, getSlice()->getDefaultRefViewIdx());
5958    }
5959
5960    assert(picDepth != NULL);
5961#else
5962    picDepth = getSlice()->getIvPic( true, getSlice()->getDefaultRefViewIdx());
5963#endif
5964    if (picDepth && bDepthRefine)
5965    {
5966      estimateDVFromDM(getSlice()->getDefaultRefViewIdx(), uiPartIdx, picDepth, uiPartAddr, &defaultDV ); // from base view
5967    }
5968    pDInfo->m_acDoNBDV = defaultDV;
5969#endif
5970  }
5971}
5972
5973#if H_3D_NBDV_REF
5974Pel TComDataCU::getMcpFromDM(TComPicYuv* pcBaseViewDepthPicYuv, TComMv* mv, Int iBlkX, Int iBlkY, Int iBlkWidth, Int iBlkHeight, Int* aiShiftLUT )
5975{
5976  Int iPictureWidth  = pcBaseViewDepthPicYuv->getWidth();
5977  Int iPictureHeight = pcBaseViewDepthPicYuv->getHeight();
5978 
5979  Int depthStartPosX = Clip3(0,   iPictureWidth - 1,  iBlkX + ((mv->getHor()+2)>>2));
5980  Int depthStartPosY = Clip3(0,   iPictureHeight - 1, iBlkY + ((mv->getVer()+2)>>2));
5981  Int depthEndPosX   = Clip3(0,   iPictureWidth - 1,  iBlkX + iBlkWidth - 1 + ((mv->getHor()+2)>>2));
5982  Int depthEndPosY   = Clip3(0,   iPictureHeight - 1, iBlkY + iBlkHeight - 1 + ((mv->getVer()+2)>>2));
5983
5984  Pel* depthTL  = pcBaseViewDepthPicYuv->getLumaAddr();
5985  Int depStride =  pcBaseViewDepthPicYuv->getStride();
5986
5987  Pel  maxDepthVal = 0;
5988  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthStartPosX ]);      // Left Top
5989  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthStartPosX ]);      // Left Bottom
5990  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthEndPosX   ]);      // Right Top
5991  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthEndPosX   ]);      // Right Bottom
5992
5993  return aiShiftLUT[ maxDepthVal ];
5994}
5995
5996Void TComDataCU::estimateDVFromDM(Int refViewIdx, UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred )
5997{
5998  if (picDepth)
5999  {
6000    UInt uiAbsPartAddrCurrCU = m_uiAbsIdxInLCU + uiPartAddr;
6001    Int iWidth, iHeight;
6002    getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight ); // The modified value of uiPartAddr won't be used any more
6003
6004    TComPicYuv* pcBaseViewDepthPicYuv = picDepth->getPicYuvRec();
6005    Int iBlkX = ( getAddr() % picDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
6006    Int iBlkY = ( getAddr() / picDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
6007
6008    Int* aiShiftLUT = getSlice()->getDepthToDisparityB(refViewIdx );
6009
6010    Pel iDisp = getMcpFromDM( pcBaseViewDepthPicYuv, cMvPred, iBlkX, iBlkY, iWidth, iHeight, aiShiftLUT );
6011    cMvPred->setHor( iDisp );
6012  }
6013}
6014#endif //H_3D_NBDV_REF
6015
6016
6017Bool TComDataCU::xCheckSpatialNBDV( TComDataCU* pcTmpCU, UInt uiIdx, DisInfo* pNbDvInfo, Bool bSearchForMvpDv, IDVInfo* paIDVInfo, UInt uiMvpDvPos
6018#if H_3D_NBDV_REF
6019, Bool bDepthRefine
6020#endif
6021)
6022{
6023  if( pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ) )
6024  {
6025    Bool bTmpIsSkipped = pcTmpCU->isSkipped( uiIdx );
6026    for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
6027    {
6028      RefPicList eRefPicList = RefPicList(iList);
6029      Int      refId = pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ;
6030      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
6031
6032      if( refId >= 0)
6033      {
6034        Int refViewIdx  = pcTmpCU->getSlice()->getRefPic(eRefPicList, refId)->getViewIndex();
6035        if (refViewIdx != m_pcSlice->getViewIndex()) 
6036        {
6037          pNbDvInfo->m_acNBDV = cMvPred;
6038          pNbDvInfo->m_aVIdxCan = refViewIdx;
6039#if H_3D_NBDV_REF
6040          TComPic* picDepth = NULL;
6041          assert(getSlice()->getRefPic(eRefPicList, refId)->getPOC() == getSlice()->getPOC());         
6042#if H_3D_FCO_VSP_DONBDV_E0163
6043          picDepth  = getSlice()->getIvPic(true, getSlice()->getViewIndex() );
6044          if ( picDepth->getPicYuvRec() != NULL ) 
6045          {
6046            cMvPred.setZero();
6047          }
6048          else// Go back with virtual depth
6049          {
6050            picDepth = getSlice()->getIvPic (true, refViewIdx );
6051          }
6052          assert(picDepth != NULL);
6053#else
6054          picDepth   = getSlice()->getIvPic (true, refViewIdx );
6055#endif
6056          UInt uiPartIdx = 0;   //Notes from MTK: Please confirm that using 0 as partition index and partition address is correct for CU-level DoNBDV
6057          UInt uiPartAddr = 0;  //QC: confirmed
6058
6059          if (picDepth && bDepthRefine)
6060          {
6061            estimateDVFromDM(refViewIdx, uiPartIdx, picDepth, uiPartAddr, &cMvPred );
6062          }
6063          pNbDvInfo->m_acDoNBDV = cMvPred;
6064#endif
6065          return true;
6066        }
6067        else if ( bSearchForMvpDv && cMvPred.getIDVFlag() && bTmpIsSkipped )
6068        {
6069          assert( uiMvpDvPos < IDV_CANDS );
6070          paIDVInfo->m_acMvCand[iList][ uiMvpDvPos ] = TComMv( cMvPred.getIDVHor(), cMvPred.getIDVVer() );
6071          //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.
6072          paIDVInfo->m_aVIdxCan[iList][ uiMvpDvPos ] = cMvPred.getIDVVId();
6073          paIDVInfo->m_bAvailab[iList][ uiMvpDvPos ] = true;
6074          paIDVInfo->m_bFound                        = true; 
6075        }
6076      }
6077    }
6078  }
6079  return false; 
6080}
6081 
6082Void TComDataCU::xDeriveRightBottomNbIdx(Int &riLCUIdxRBNb, Int &riPartIdxRBNb )
6083{
6084  UInt uiPartIdx = 0;
6085  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth(); 
6086  Int uiLCUIdx = getAddr();
6087
6088  UInt uiPartIdxRB;
6089  deriveRightBottomIdx(uiPartIdx, uiPartIdxRB ); 
6090  UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
6091
6092  if (( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() )>= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
6093  {
6094    riLCUIdxRBNb  = -1;
6095    riPartIdxRBNb = -1;
6096  }
6097  else if(( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() )>= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
6098  {
6099    riLCUIdxRBNb  = -1;
6100    riPartIdxRBNb = -1;
6101  }
6102  else
6103  {
6104    if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
6105      ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
6106    {
6107      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
6108      riLCUIdxRBNb  = uiLCUIdx; 
6109    }
6110    else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
6111    {
6112      riPartIdxRBNb = -1;
6113      riLCUIdxRBNb  = -1;
6114    }
6115    else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
6116    {
6117      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
6118      riLCUIdxRBNb = uiLCUIdx + 1;
6119    }
6120    else //is the right bottom corner of LCU                       
6121    {
6122      riPartIdxRBNb = -1;
6123      riLCUIdxRBNb  = -1;
6124    }
6125  }
6126}
6127
6128
6129Void TComDataCU::setDvInfoSubParts( DisInfo cDvInfo, UInt uiAbsPartIdx, UInt uiDepth )
6130{
6131  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
6132  for (UInt ui = 0; ui < uiCurrPartNumb; ui++ )
6133  {
6134    m_pDvInfo[uiAbsPartIdx + ui] = cDvInfo;
6135  }
6136}
6137#if H_3D_VSP
6138Void TComDataCU::setDvInfoSubParts( DisInfo cDvInfo, UInt uiAbsPartIdx, UInt uiPUIdx, UInt uiDepth )
6139{
6140  setSubPartT<DisInfo>( cDvInfo, m_pDvInfo, uiAbsPartIdx, uiDepth, uiPUIdx );
6141}
6142#endif
6143
6144Bool TComDataCU::xGetColDisMV( Int currCandPic, RefPicList eRefPicList, Int refidx, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv , Int & iTargetViewIdx, Int & iStartViewIdx )
6145{
6146
6147  RefPicList  eColRefPicList = REF_PIC_LIST_0;
6148  Int iColViewIdx, iColRefViewIdx;
6149  TComPic *pColPic = getSlice()->getRefPic( eRefPicList, refidx);
6150  TComDataCU *pColCU = pColPic->getCU( uiCUAddr );
6151  iColViewIdx = pColCU->getSlice()->getViewIndex();
6152  if (pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==SIZE_NONE||pColCU->isIntra(uiPartUnitIdx))
6153  {
6154    return false;
6155  }
6156  for (Int ilist = 0; ilist < (pColCU->getSlice()->isInterB()? 2:1); ilist++) 
6157  {
6158    if(pColCU->getSlice()->isInterB())
6159    {
6160      eColRefPicList = RefPicList(ilist);
6161    }
6162
6163    Int iColRefIdx = pColCU->getCUMvField(eColRefPicList)->getRefIdx(uiPartUnitIdx);
6164
6165    if (iColRefIdx < 0)
6166    {
6167      continue;
6168    }
6169
6170    iColRefViewIdx = pColCU->getSlice()->getRefPic(eColRefPicList, iColRefIdx)->getViewIndex();
6171
6172    if ( iColViewIdx    == iColRefViewIdx ) // temporal vector
6173    {
6174      continue;
6175    }
6176    else 
6177    {
6178      if(getPic()->isTempIVRefValid(currCandPic, ilist,  iColRefIdx))
6179      {
6180        rcMv = pColCU->getCUMvField(eColRefPicList)->getMv(uiPartUnitIdx);
6181        rcMv.setIDVFlag(0);
6182        iTargetViewIdx  = iColRefViewIdx ;
6183        iStartViewIdx   = iColViewIdx   ;
6184        return true;   
6185      }
6186    }
6187  }
6188
6189  return false;
6190}
6191#endif
6192#if  H_3D_FAST_TEXTURE_ENCODING
6193Void
6194TComDataCU::getIVNStatus       ( UInt uiPartIdx,  DisInfo* pDInfo, Bool& bIVFMerge, Int& iIVFMaxD)
6195{
6196  TComSlice*    pcSlice         = getSlice (); 
6197  Int iViewIndex = pDInfo->m_aVIdxCan;
6198  //--- get base CU/PU and check prediction mode ---
6199  TComPic*    pcBasePic   = pcSlice->getIvPic( false, iViewIndex );
6200  TComPicYuv* pcBaseRec   = pcBasePic->getPicYuvRec   ();
6201
6202  UInt          uiPartAddr;
6203  Int           iWidth;
6204  Int           iHeight;
6205  getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
6206
6207  Int  iCurrPosX, iCurrPosY;
6208  pcBaseRec->getTopLeftSamplePos( getAddr(), getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
6209
6210  iCurrPosX  += ( ( iWidth  - 1 ) >> 1 );
6211  iCurrPosY  += ( ( iHeight - 1 ) >> 1 );
6212
6213  Bool depthRefineFlag = false; 
6214#if H_3D_NBDV_REF
6215  depthRefineFlag = m_pcSlice->getDepthRefinementFlag( ); 
6216#endif // H_3D_NBDV_REF
6217
6218  TComMv      cDv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
6219  if( depthRefineFlag )
6220  {
6221    cDv.setVer(0);
6222  }
6223
6224  Int         iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6225  Int         iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
6226  Int         iBaseLPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX - (iWidth >> 1) + ( (cDv.getHor() + 2 ) >> 2 ) );
6227  Int         iBaseLPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
6228  Int         iBaseRPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + (iWidth >> 1) + 1 + ( (cDv.getHor() + 2 ) >> 2 ) );
6229  Int         iBaseRPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
6230  Int         iBaseUPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6231  Int         iBaseUPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY - (iHeight >> 1) + ( (cDv.getVer() + 2 ) >> 2 )); 
6232  Int         iBaseDPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6233  Int         iBaseDPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + (iHeight >> 1) + 1 + ( (cDv.getVer() + 2 ) >> 2 )); 
6234
6235  Int         iBaseCUAddr;
6236  Int         iBaseAbsPartIdx;
6237  Int         iBaseLCUAddr;
6238  Int         iBaseLAbsPartIdx;
6239  Int         iBaseRCUAddr;
6240  Int         iBaseRAbsPartIdx;
6241  Int         iBaseUCUAddr;
6242  Int         iBaseUAbsPartIdx;
6243  Int         iBaseDCUAddr;
6244  Int         iBaseDAbsPartIdx;
6245  pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY , iBaseCUAddr, iBaseAbsPartIdx );
6246  pcBaseRec->getCUAddrAndPartIdx( iBaseLPosX , iBaseLPosY , iBaseLCUAddr, iBaseLAbsPartIdx );
6247  pcBaseRec->getCUAddrAndPartIdx( iBaseRPosX , iBaseRPosY , iBaseRCUAddr, iBaseRAbsPartIdx );
6248  pcBaseRec->getCUAddrAndPartIdx( iBaseUPosX , iBaseUPosY , iBaseUCUAddr, iBaseUAbsPartIdx );
6249  pcBaseRec->getCUAddrAndPartIdx( iBaseDPosX , iBaseDPosY , iBaseDCUAddr, iBaseDAbsPartIdx );
6250  TComDataCU* pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
6251  TComDataCU* pcBaseLCU    = pcBasePic->getCU( iBaseLCUAddr );
6252  TComDataCU* pcBaseRCU    = pcBasePic->getCU( iBaseRCUAddr );
6253  TComDataCU* pcBaseUCU    = pcBasePic->getCU( iBaseUCUAddr );
6254  TComDataCU* pcBaseDCU    = pcBasePic->getCU( iBaseDCUAddr );
6255  bIVFMerge = pcBaseLCU->getMergeFlag( iBaseLAbsPartIdx ) && pcBaseCU->getMergeFlag( iBaseAbsPartIdx ) && pcBaseRCU->getMergeFlag( iBaseRAbsPartIdx ) && pcBaseUCU->getMergeFlag( iBaseUAbsPartIdx ) && pcBaseDCU->getMergeFlag( iBaseDAbsPartIdx );
6256  Int aiDepthL[5]; //depth level
6257  aiDepthL[0] = pcBaseCU->getDepth(iBaseAbsPartIdx);
6258  aiDepthL[1] = pcBaseLCU->getDepth(iBaseLAbsPartIdx);
6259  aiDepthL[2] = pcBaseRCU->getDepth(iBaseRAbsPartIdx);
6260  aiDepthL[3] = pcBaseUCU->getDepth(iBaseUAbsPartIdx);
6261  aiDepthL[4] = pcBaseDCU->getDepth(iBaseDAbsPartIdx);
6262  for (Int i = 0; i < 5; i++)
6263  {
6264    if (iIVFMaxD < aiDepthL[i])
6265      iIVFMaxD = aiDepthL[i];
6266  }
6267}
6268#endif
6269
6270#if H_3D_SPIVMP
6271Void TComDataCU::getSPPara(Int iPUWidth, Int iPUHeight, Int& iNumSP, Int& iNumSPInOneLine, Int& iSPWidth, Int& iSPHeight)
6272{
6273  Int iSubPUSize = ( getSlice()->getIsDepth() ? getSlice()->getMpiSubPbSize() : getSlice()->getSubPbSize() );
6274
6275  iNumSPInOneLine = iPUWidth/iSubPUSize;
6276  Int iNumSPInOneColumn = iPUHeight/iSubPUSize;
6277  iNumSPInOneLine = (iPUHeight % iSubPUSize != 0 || iPUWidth % iSubPUSize != 0 ) ? 1 : iNumSPInOneLine;
6278  iNumSPInOneColumn = (iPUHeight % iSubPUSize != 0  || iPUWidth % iSubPUSize != 0 ) ? 1 : iNumSPInOneColumn;
6279  iNumSP = iNumSPInOneLine * iNumSPInOneColumn;
6280
6281  iSPWidth = iNumSPInOneLine == 1 ? iPUWidth: iSubPUSize; 
6282  iSPHeight = iNumSPInOneColumn == 1 ? iPUHeight: iSubPUSize; 
6283}
6284
6285Void TComDataCU::getSPAbsPartIdx(UInt uiBaseAbsPartIdx, Int iWidth, Int iHeight, Int iPartIdx, Int iNumPartLine, UInt& ruiPartAddr )
6286{
6287  uiBaseAbsPartIdx += m_uiAbsIdxInLCU;
6288  Int iBasePelX = g_auiRasterToPelX[g_auiZscanToRaster[uiBaseAbsPartIdx]];
6289  Int iBasePelY = g_auiRasterToPelY[g_auiZscanToRaster[uiBaseAbsPartIdx]];
6290  Int iCurrPelX = iBasePelX + iPartIdx%iNumPartLine * iWidth;
6291  Int iCurrPelY = iBasePelY + iPartIdx/iNumPartLine * iHeight;
6292  Int iCurrRaster = iCurrPelY / getPic()->getMinCUHeight() * getPic()->getNumPartInWidth() + iCurrPelX/getPic()->getMinCUWidth();
6293  ruiPartAddr = g_auiRasterToZscan[iCurrRaster];
6294  ruiPartAddr -= m_uiAbsIdxInLCU; 
6295}
6296
6297Void TComDataCU::setInterDirSP( UInt uiDir, UInt uiAbsPartIdx, Int iWidth, Int iHeight )
6298{
6299  uiAbsPartIdx += getZorderIdxInCU();
6300  Int iStartPelX = g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]];
6301  Int iStartPelY = g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
6302  Int iEndPelX = iStartPelX + iWidth;
6303  Int iEndPelY = iStartPelY + iHeight;
6304
6305  Int iCurrRaster, uiPartAddr;
6306
6307  for (Int i=iStartPelY; i<iEndPelY; i+=getPic()->getMinCUHeight())
6308  {
6309    for (Int j=iStartPelX; j < iEndPelX; j += getPic()->getMinCUWidth())
6310    {
6311      iCurrRaster = i / getPic()->getMinCUHeight() * getPic()->getNumPartInWidth() + j/getPic()->getMinCUWidth();
6312      uiPartAddr = g_auiRasterToZscan[iCurrRaster];
6313      uiPartAddr -= getZorderIdxInCU(); 
6314
6315      m_puhInterDir[uiPartAddr] = uiDir;
6316    }
6317  }
6318}
6319#endif
6320
6321#if H_3D_IV_MERGE
6322Bool
6323TComDataCU::getInterViewMergeCands(UInt uiPartIdx, Int* paiPdmRefIdx, TComMv* pacPdmMv, DisInfo* pDInfo, Int* availableMcDc , Bool bIsDepth           
6324#if H_3D_SPIVMP
6325, TComMvField* pcMvFieldSP, UChar* puhInterDirSP
6326#endif
6327, Bool bICFlag
6328)
6329{
6330  TComSlice*    pcSlice = getSlice (); 
6331  Int iViewIndex        = pDInfo->m_aVIdxCan;
6332
6333  //--- get base CU/PU and check prediction mode ---
6334  TComPic*    pcBasePic   = pcSlice->getIvPic( bIsDepth, iViewIndex );
6335  TComPicYuv* pcBaseRec   = pcBasePic->getPicYuvRec   ();
6336
6337  UInt          uiPartAddr;
6338  Int           iWidth;
6339  Int           iHeight;
6340  getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
6341
6342  Int  iCurrPosX, iCurrPosY;
6343  pcBaseRec->getTopLeftSamplePos( getAddr(), getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
6344
6345#if !H_3D_SPIVMP
6346  iCurrPosX  += ( iWidth  >> 1 );
6347  iCurrPosY  += ( iHeight >> 1 );
6348#endif
6349
6350  Bool depthRefineFlag = false; 
6351#if H_3D_NBDV_REF
6352  depthRefineFlag = m_pcSlice->getDepthRefinementFlag( ); 
6353#endif // H_3D_NBDV_REF
6354
6355  TComMv      cDv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
6356  if( depthRefineFlag )
6357  {
6358    cDv.setVer(0);
6359  }
6360
6361  Bool abPdmAvailable[8] =  {false, false, false, false, false, false, false, false};
6362#if H_3D_NBDV
6363  for( Int i = 0; i < 8; i++)
6364  {
6365    pacPdmMv[i].setIDVFlag   (false);
6366  }
6367#endif
6368
6369  if(!bICFlag)
6370  {
6371
6372#if H_3D_SPIVMP
6373    ////////////////////////////////
6374    //////////sub-PU IvMC///////////
6375    ////////////////////////////////
6376    if(!m_pcSlice->getIsDepth())
6377    {
6378      if (!getDBBPFlag(0))
6379      {
6380        Int iNumSPInOneLine, iNumSP, iSPWidth, iSPHeight;
6381        getSPPara(iWidth, iHeight, iNumSP, iNumSPInOneLine, iSPWidth, iSPHeight);
6382
6383        for (Int i=0; i<iNumSP; i++)
6384        {
6385          puhInterDirSP[i] = 0;
6386          pcMvFieldSP[2*i].getMv().set(0, 0);
6387          pcMvFieldSP[2*i+1].getMv().set(0,0);
6388          pcMvFieldSP[2*i].setRefIdx(-1);
6389          pcMvFieldSP[2*i+1].setRefIdx(-1);
6390        }
6391
6392        Int         iBaseCUAddr;
6393        Int         iBaseAbsPartIdx;
6394        TComDataCU* pcBaseCU;
6395        Int iPartition = 0;
6396
6397        Int iDelX = iSPWidth/2;
6398        Int iDelY = iSPHeight/2;
6399
6400        Int         iCenterPosX = iCurrPosX + ( ( iWidth /  iSPWidth ) >> 1 )  * iSPWidth + ( iSPWidth >> 1 );
6401        Int         iCenterPosY = iCurrPosY + ( ( iHeight /  iSPHeight ) >> 1 )  * iSPHeight + (iSPHeight >> 1);
6402        Int         iRefCenterCUAddr, iRefCenterAbsPartIdx;
6403
6404        if(iWidth == iSPWidth && iHeight == iSPHeight)
6405        {
6406          iCenterPosX = iCurrPosX + (iWidth >> 1);
6407          iCenterPosY = iCurrPosY + (iHeight >> 1);
6408        }
6409
6410        Int iRefCenterPosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCenterPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
6411        Int iRefCenterPosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCenterPosY + ( (cDv.getVer() + 2 ) >> 2 ) ); 
6412
6413        pcBaseRec->getCUAddrAndPartIdx( iRefCenterPosX , iRefCenterPosY , iRefCenterCUAddr, iRefCenterAbsPartIdx );
6414        TComDataCU* pcDefaultCU    = pcBasePic->getCU( iRefCenterCUAddr );
6415        if(!( pcDefaultCU->getPredictionMode( iRefCenterAbsPartIdx ) == MODE_INTRA ))
6416        {
6417          for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )       
6418          {
6419            RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
6420            Bool stopLoop = false;
6421            for(Int iLoop = 0; iLoop < 2 && !stopLoop; ++iLoop)
6422            {
6423              RefPicList eDefaultRefPicList = (iLoop ==1)? RefPicList( 1 -  uiCurrRefListId ) : RefPicList( uiCurrRefListId );
6424              TComMvField cDefaultMvField;
6425              pcDefaultCU->getMvField( pcDefaultCU, iRefCenterAbsPartIdx, eDefaultRefPicList, cDefaultMvField );
6426              Int         iDefaultRefIdx     = cDefaultMvField.getRefIdx();
6427              if (iDefaultRefIdx >= 0)
6428              {
6429                Int iDefaultRefPOC = pcDefaultCU->getSlice()->getRefPOC(eDefaultRefPicList, iDefaultRefIdx);
6430                if (iDefaultRefPOC != pcSlice->getPOC())   
6431                {
6432                  for (Int iPdmRefIdx = 0; iPdmRefIdx < pcSlice->getNumRefIdx( eCurrRefPicList ); iPdmRefIdx++)
6433                  {
6434                    if (iDefaultRefPOC == pcSlice->getRefPOC(eCurrRefPicList, iPdmRefIdx))
6435                    {
6436                      abPdmAvailable[ uiCurrRefListId ] = true;
6437                      TComMv cMv(cDefaultMvField.getHor(), cDefaultMvField.getVer());
6438#if H_3D_NBDV
6439#if H_3D_IV_MERGE
6440                      if( !bIsDepth )
6441                      {
6442#endif
6443                        cMv.setIDVFlag   (true);
6444                        cMv.setIDVHor    (cDv.getHor());                 
6445                        cMv.setIDVVer    (cDv.getVer()); 
6446                        cMv.setIDVVId    (iViewIndex); 
6447#if H_3D_IV_MERGE
6448                      }
6449#endif
6450#endif
6451                      paiPdmRefIdx  [ uiCurrRefListId ] = iPdmRefIdx;
6452                      pacPdmMv      [ uiCurrRefListId ] = cMv;
6453                      stopLoop = true;
6454                      break;
6455                    }
6456                  }
6457                }
6458              }
6459            }
6460          }
6461        }
6462        availableMcDc[0] = ( abPdmAvailable[0]? 1 : 0) + (abPdmAvailable[1]? 2 : 0);
6463
6464        if(availableMcDc[0])
6465        {
6466
6467          Int         iBasePosX, iBasePosY;
6468          for (Int i=iCurrPosY; i < iCurrPosY + iHeight; i += iSPHeight)
6469          {
6470            for (Int j = iCurrPosX; j < iCurrPosX + iWidth; j += iSPWidth)
6471            {
6472              iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, j + iDelX + ( (cDv.getHor() + 2 ) >> 2 ));
6473              iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, i + iDelY + ( (cDv.getVer() + 2 ) >> 2 )); 
6474
6475              pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY, iBaseCUAddr, iBaseAbsPartIdx );
6476              pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
6477              if(!( pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) == MODE_INTRA ))
6478              {
6479                for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )
6480                {
6481                  RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
6482                  Bool bLoopStop = false;
6483                  for(Int iLoop = 0; iLoop < 2 && !bLoopStop; ++iLoop)
6484                  {
6485                    RefPicList eBaseRefPicList = (iLoop ==1)? RefPicList( 1 -  uiCurrRefListId ) : RefPicList( uiCurrRefListId );
6486                    TComMvField cBaseMvField;
6487                    pcBaseCU->getMvField( pcBaseCU, iBaseAbsPartIdx, eBaseRefPicList, cBaseMvField );
6488                    Int         iBaseRefIdx     = cBaseMvField.getRefIdx();
6489                    if (iBaseRefIdx >= 0)
6490                    {
6491                      Int iBaseRefPOC = pcBaseCU->getSlice()->getRefPOC(eBaseRefPicList, iBaseRefIdx);
6492                      if (iBaseRefPOC != pcSlice->getPOC())   
6493                      {
6494                        for (Int iPdmRefIdx = 0; iPdmRefIdx < pcSlice->getNumRefIdx( eCurrRefPicList ); iPdmRefIdx++)
6495                        {
6496                          if (iBaseRefPOC == pcSlice->getRefPOC(eCurrRefPicList, iPdmRefIdx))
6497                          {
6498                            abPdmAvailable[ uiCurrRefListId ] = true;
6499                            TComMv cMv(cBaseMvField.getHor(), cBaseMvField.getVer());
6500
6501                            if( !bIsDepth )
6502                            {
6503                              cMv.setIDVFlag   (true);
6504                              cMv.setIDVHor    (cDv.getHor());                 
6505                              cMv.setIDVVer    (cDv.getVer()); 
6506                              cMv.setIDVVId    (iViewIndex); 
6507                            }
6508
6509                            bLoopStop = true;
6510
6511                            pcMvFieldSP[2*iPartition + uiCurrRefListId].setMvField(cMv, iPdmRefIdx);
6512                            break;
6513                          }
6514                        }
6515                      }
6516                    }
6517                  }
6518                }
6519              }
6520
6521              puhInterDirSP[iPartition] = (pcMvFieldSP[2*iPartition].getRefIdx()!=-1 ? 1: 0) + (pcMvFieldSP[2*iPartition+1].getRefIdx()!=-1 ? 2: 0);
6522              if (puhInterDirSP[iPartition] == 0)
6523              {
6524                puhInterDirSP[iPartition] = availableMcDc[0];
6525                pcMvFieldSP[2*iPartition].setMvField(pacPdmMv[0], paiPdmRefIdx[0]);
6526                pcMvFieldSP[2*iPartition + 1].setMvField(pacPdmMv[1], paiPdmRefIdx[1]);
6527
6528              }
6529              iPartition ++;
6530            }
6531          }
6532        }
6533      }
6534
6535      iCurrPosX  += ( iWidth  >> 1 );
6536      iCurrPosY  += ( iHeight >> 1 );
6537    }
6538#endif
6539
6540    ////////////////////////////////
6541    /////// IvMC + IvMCShift ///////
6542    ////////////////////////////////
6543
6544#if H_3D_SPIVMP
6545    if(m_pcSlice->getIsDepth())
6546    {
6547      iCurrPosX  += ( iWidth  >> 1 );
6548      iCurrPosY  += ( iHeight >> 1 );
6549    }
6550    for(Int iLoopCan = ( (m_pcSlice->getIsDepth() || getDBBPFlag(0)) ? 0 : 1 ); iLoopCan < ( 2 - m_pcSlice->getIsDepth() ); iLoopCan ++) 
6551#else
6552    for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6553#endif
6554    {
6555      // iLoopCan == 0 --> IvMC
6556      // iLoopCan == 1 --> IvMCShift
6557
6558      Int         iBaseCUAddr;
6559      Int         iBaseAbsPartIdx;
6560
6561      Int offsetW = (iLoopCan == 0) ? 0 : ( iWidth  * 2 );
6562      Int offsetH = (iLoopCan == 0) ? 0 : ( iHeight * 2 );
6563
6564      Int         iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + offsetW + 2 ) >> 2 ) );
6565      Int         iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + offsetH + 2 ) >> 2 ) ); 
6566      pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY , iBaseCUAddr, iBaseAbsPartIdx );
6567
6568      TComDataCU* pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
6569      if(!( pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) == MODE_INTRA ))
6570      {
6571        // Loop reference picture list of current slice (X in spec).
6572        for( UInt uiCurrRefListId = 0; uiCurrRefListId < 2; uiCurrRefListId++ )       
6573        {
6574          RefPicList  eCurrRefPicList = RefPicList( uiCurrRefListId );
6575
6576          Bool stopLoop = false;
6577          // Loop reference picture list of candidate slice (Y in spec)
6578          for(Int iLoop = 0; iLoop < 2 && !stopLoop; ++iLoop)
6579          {
6580            RefPicList eBaseRefPicList = (iLoop ==1)? RefPicList( 1 -  uiCurrRefListId ) : RefPicList( uiCurrRefListId );
6581            TComMvField cBaseMvField;
6582            pcBaseCU->getMvField( pcBaseCU, iBaseAbsPartIdx, eBaseRefPicList, cBaseMvField );
6583            Int         iBaseRefIdx     = cBaseMvField.getRefIdx();
6584            if (iBaseRefIdx >= 0)
6585            {
6586              Int iBaseRefPOC = pcBaseCU->getSlice()->getRefPOC(eBaseRefPicList, iBaseRefIdx);
6587              if (iBaseRefPOC != pcSlice->getPOC())   
6588              {
6589                for (Int iPdmRefIdx = 0; iPdmRefIdx < pcSlice->getNumRefIdx( eCurrRefPicList ); iPdmRefIdx++)
6590                {
6591                  if (iBaseRefPOC == pcSlice->getRefPOC(eCurrRefPicList, iPdmRefIdx))
6592                  {
6593                    abPdmAvailable[ (uiCurrRefListId + (iLoopCan<<2)) ] = true;
6594                    TComMv cMv(cBaseMvField.getHor(), cBaseMvField.getVer());
6595#if H_3D_NBDV
6596#if H_3D_IV_MERGE
6597                    if( !bIsDepth )
6598                    {
6599#endif
6600                      cMv.setIDVFlag   (true);
6601                      cMv.setIDVHor    (cDv.getHor());                 
6602                      cMv.setIDVVer    (cDv.getVer()); 
6603                      cMv.setIDVVId    (iViewIndex); 
6604#if H_3D_IV_MERGE
6605                    }
6606#endif
6607#endif
6608                    paiPdmRefIdx  [ (uiCurrRefListId + (iLoopCan<<2)) ] = iPdmRefIdx;
6609                    pacPdmMv      [ (uiCurrRefListId + (iLoopCan<<2)) ] = cMv;
6610                    stopLoop = true;
6611                    break;
6612                  }
6613                }
6614              }
6615            }
6616          }
6617        }
6618      }
6619    }
6620#if H_3D_SPIVMP
6621    for(Int iLoopCan = ( (m_pcSlice->getIsDepth() || getDBBPFlag(0)) ? 0 : 1 ); iLoopCan < ( 2 - m_pcSlice->getIsDepth() ); iLoopCan ++)
6622#else
6623    for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6624#endif
6625    {
6626      availableMcDc[(iLoopCan << 1)] = ( abPdmAvailable[(iLoopCan<<2)] ? 1 : 0 ) + ( abPdmAvailable[1 + (iLoopCan<<2)] ? 2 : 0);
6627    }
6628
6629  }
6630
6631  ////////////////////////////////
6632  /////// IvDC + IvDCShift ///////
6633  ////////////////////////////////
6634
6635  if( !getSlice()->getIsDepth() )
6636  {
6637    for( Int iRefListId = 0; iRefListId < 2 ; iRefListId++ )
6638    {
6639      RefPicList  eRefPicListDMV       = RefPicList( iRefListId );
6640      Int         iNumRefPics       = pcSlice->getNumRefIdx( eRefPicListDMV );
6641      for( Int iPdmRefIdx = 0; iPdmRefIdx < iNumRefPics; iPdmRefIdx++ )
6642      {
6643        if(( pcSlice->getRefPOC( eRefPicListDMV, iPdmRefIdx ) == pcSlice->getPOC()) && (pcSlice->getRefPic( eRefPicListDMV, iPdmRefIdx )->getViewIndex() == pDInfo->m_aVIdxCan))
6644        {
6645          for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6646          {
6647            Int ioffsetDV = (iLoopCan == 0) ? 0 : 4;
6648            abPdmAvailable[ iRefListId + 2 + (iLoopCan<<2) ] = true;
6649            paiPdmRefIdx  [ iRefListId + 2 + (iLoopCan<<2) ] = iPdmRefIdx;
6650#if H_3D_NBDV_REF
6651            TComMv cMv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
6652#endif
6653            cMv.setHor( cMv.getHor() + ioffsetDV );
6654#if H_3D_IV_MERGE
6655            if( bIsDepth )
6656            {
6657              cMv.setHor((cMv.getHor()+2)>>2); 
6658            }
6659#endif
6660            cMv.setVer( 0 );
6661            pacPdmMv      [iRefListId + 2 + (iLoopCan<<2)] = cMv;
6662          }
6663          break;
6664        }
6665      }
6666    }
6667    for(Int iLoopCan = 0; iLoopCan < 2; iLoopCan ++)
6668    {
6669      availableMcDc[1 + (iLoopCan << 1)] = ( abPdmAvailable[2 + (iLoopCan<<2)] ? 1 : 0 ) + ( abPdmAvailable[3 + (iLoopCan<<2)] ? 2 : 0 );
6670    }
6671  }
6672  return false;
6673}
6674#endif
6675#if H_3D_ARP
6676Void TComDataCU::setARPWSubParts ( UChar w, UInt uiAbsPartIdx, UInt uiDepth )
6677{
6678  assert( sizeof( *m_puhARPW) == 1 );
6679  memset( m_puhARPW + uiAbsPartIdx, w, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
6680}
6681#endif
6682
6683#if H_3D_IC
6684Void TComDataCU::setICFlagSubParts( Bool bICFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
6685{
6686  memset( m_pbICFlag + uiAbsPartIdx, bICFlag, (m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ))*sizeof(Bool) );
6687}
6688
6689Bool TComDataCU::isICFlagRequired( UInt uiAbsPartIdx )
6690{
6691  UInt uiPartAddr;
6692  UInt iNumbPart;
6693
6694  if( !( getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ) )
6695  {
6696    return false;
6697  }
6698
6699  if( getSlice()->getIcSkipParseFlag() )
6700  {
6701    if( getMergeFlag( uiAbsPartIdx ) && getMergeIndex( uiAbsPartIdx ) == 0 )
6702    {
6703      return false;
6704    }
6705  }
6706
6707  if( getMergeFlag( uiAbsPartIdx ) )
6708  {
6709    return true;
6710  }
6711
6712
6713  Int iWidth, iHeight;
6714
6715  iNumbPart = ( getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ? 1 : ( getPartitionSize( uiAbsPartIdx ) == SIZE_NxN ? 4 : 2 ) );
6716
6717  for(UInt i = 0; i < iNumbPart; i++)
6718  {
6719    getPartIndexAndSize( i, uiPartAddr, iWidth, iHeight, uiAbsPartIdx, true );
6720    uiPartAddr += uiAbsPartIdx;
6721
6722    for(UInt uiRefIdx = 0; uiRefIdx < 2; uiRefIdx++)
6723    {
6724      RefPicList eRefList = uiRefIdx ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
6725      Int iBestRefIdx = getCUMvField(eRefList)->getRefIdx(uiPartAddr);
6726
6727      if( ( getInterDir( uiPartAddr ) & ( uiRefIdx+1 ) ) && iBestRefIdx >= 0 && getSlice()->getViewIndex() != getSlice()->getRefPic( eRefList, iBestRefIdx )->getViewIndex() )
6728      {
6729        return true;
6730      }
6731    }
6732  }
6733
6734  return false;
6735}
6736#endif
6737#if H_3D_DIM_DMM
6738Void TComDataCU::setDmmWedgeTabIdxSubParts( UInt tabIdx, UInt dmmType, UInt uiAbsPartIdx, UInt uiDepth )
6739{
6740  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
6741  for( UInt ui = 0; ui < uiCurrPartNumb; ui++ )
6742  { 
6743    m_dmmWedgeTabIdx[dmmType][uiAbsPartIdx+ui] = tabIdx; 
6744  }
6745}
6746#endif
6747
6748#if H_3D_VSP
6749Void TComDataCU::setMvFieldPUForVSP( TComDataCU* pcCU, UInt partAddr, Int width, Int height, RefPicList eRefPicList, Int iRefIdx, Int &vspSize )
6750{
6751  // Get depth reference
6752  Int depthRefViewIdx = pcCU->getDvInfo(partAddr).m_aVIdxCan;
6753 
6754#if H_3D_FCO_VSP_DONBDV_E0163
6755  TComPic* pRefPicBaseDepth = 0;
6756  Bool     bIsCurrDepthCoded = false;
6757  pRefPicBaseDepth  = pcCU->getSlice()->getIvPic( true, pcCU->getSlice()->getViewIndex() );
6758  if ( pRefPicBaseDepth->getPicYuvRec() != NULL  ) 
6759  {
6760    bIsCurrDepthCoded = true;
6761  }
6762  else 
6763  {
6764    pRefPicBaseDepth = pcCU->getSlice()->getIvPic (true, depthRefViewIdx );
6765  }
6766#else
6767  TComPic* pRefPicBaseDepth = pcCU->getSlice()->getIvPic (true, depthRefViewIdx );
6768#endif
6769  assert(pRefPicBaseDepth != NULL);
6770  TComPicYuv* pcBaseViewDepthPicYuv = pRefPicBaseDepth->getPicYuvRec();
6771  assert(pcBaseViewDepthPicYuv != NULL);
6772  pcBaseViewDepthPicYuv->extendPicBorder();
6773
6774  // Get texture reference
6775  assert(iRefIdx >= 0);
6776  TComPic* pRefPicBaseTxt = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx );
6777  TComPicYuv* pcBaseViewTxtPicYuv = pRefPicBaseTxt->getPicYuvRec();
6778  assert(pcBaseViewTxtPicYuv != NULL);
6779
6780  // Initialize LUT according to the reference viewIdx
6781  Int txtRefViewIdx = pRefPicBaseTxt->getViewIndex();
6782  Int* pShiftLUT    = pcCU->getSlice()->getDepthToDisparityB( txtRefViewIdx );
6783  assert( txtRefViewIdx < pcCU->getSlice()->getViewIndex() );
6784
6785  // prepare Dv to access depth map or reference view
6786  TComMv cDv  = pcCU->getDvInfo(partAddr).m_acNBDV;
6787  pcCU->clipMv(cDv);
6788
6789#if H_3D_FCO_VSP_DONBDV_E0163
6790  if ( bIsCurrDepthCoded )
6791  {
6792      cDv.setZero();
6793  }
6794#endif
6795
6796  // fetch virtual depth map & convert depth to motion vector, which are stored in the motion memory
6797  xSetMvFieldForVSP( pcCU, pcBaseViewDepthPicYuv, &cDv, partAddr, width, height, pShiftLUT, eRefPicList, iRefIdx, pcCU->getSlice()->getIsDepth(), vspSize );
6798}
6799
6800Void TComDataCU::xSetMvFieldForVSP( TComDataCU *cu, TComPicYuv *picRefDepth, TComMv *dv, UInt partAddr, Int width, Int height, Int *shiftLUT, RefPicList refPicList, Int refIdx, Bool isDepth, Int &vspSize )
6801{
6802  TComCUMvField *cuMvField = cu->getCUMvField( refPicList );
6803  Int partAddrRasterSubPULine  = g_auiZscanToRaster[ partAddr ];
6804  Int numPartsLine    = cu->getPic()->getNumPartInWidth();
6805
6806  Int nTxtPerMvInfoX = 4; // cu->getPic()->getMinCUWidth();
6807  Int nTxtPerMvInfoY = 4; // cu->getPic()->getMinCUHeight();
6808
6809  Int refDepStride = picRefDepth->getStride();
6810
6811  TComMv tmpMv(0, 0);
6812  tmpMv.setIDVFlag(false);
6813
6814  Int refDepOffset  = ( (dv->getHor()+2) >> 2 ) + ( (dv->getVer()+2) >> 2 ) * refDepStride;
6815  Pel *refDepth     = picRefDepth->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refDepOffset;
6816
6817  if ((height % 8))
6818  {
6819    vspSize = 1; // 8x4
6820  }
6821  else if ((width % 8))
6822  {
6823    vspSize = 0; // 4x8
6824  }
6825  else
6826  {
6827    Bool ULvsBR, URvsBL;
6828    ULvsBR = refDepth[0]       < refDepth[refDepStride * (height-1) + width-1];
6829    URvsBL = refDepth[width-1] < refDepth[refDepStride * (height-1)];
6830    vspSize = ( ULvsBR ^ URvsBL ) ? 0 : 1;
6831  }
6832 
6833  Int subBlockW, subBlockH;
6834  if (vspSize)
6835  {
6836    subBlockW = 8;
6837    subBlockH = 4;
6838  }
6839  else
6840  {
6841    subBlockW = 4;
6842    subBlockH = 8;
6843  }
6844 
6845  Int numPartsInSubPUW = subBlockW / nTxtPerMvInfoX;
6846  Int numPartsInSubPUH = subBlockH / nTxtPerMvInfoY * numPartsLine;
6847
6848  for( Int y=0; y<height; y+=subBlockH, partAddrRasterSubPULine+=numPartsInSubPUH )
6849  {
6850    Pel *refDepthTmp[4];
6851    refDepthTmp[0] = refDepth + refDepStride * y;
6852    refDepthTmp[1] = refDepthTmp[0] + subBlockW - 1;
6853    refDepthTmp[2] = refDepthTmp[0] + refDepStride * (subBlockH - 1);
6854    refDepthTmp[3] = refDepthTmp[2] + subBlockW - 1;
6855
6856    Int partAddrRasterSubPU = partAddrRasterSubPULine;
6857    for( Int x=0; x<width; x+=subBlockW, partAddrRasterSubPU+=numPartsInSubPUW )
6858    {
6859      Pel  maxDepthVal;
6860      maxDepthVal = refDepthTmp[0][x];
6861      maxDepthVal = std::max( maxDepthVal, refDepthTmp[1][x]);
6862      maxDepthVal = std::max( maxDepthVal, refDepthTmp[2][x]);
6863      maxDepthVal = std::max( maxDepthVal, refDepthTmp[3][x]);
6864      tmpMv.setHor( (Short) shiftLUT[ maxDepthVal ] );
6865
6866      Int partAddrRasterPartLine = partAddrRasterSubPU;
6867      for( Int sY=0; sY<numPartsInSubPUH; sY+=numPartsLine, partAddrRasterPartLine += numPartsLine )
6868      {
6869        Int partAddrRasterPart = partAddrRasterPartLine;
6870        for( Int sX=0; sX<numPartsInSubPUW; sX+=1, partAddrRasterPart++ )
6871        {
6872          cuMvField->setMv    ( g_auiRasterToZscan[ partAddrRasterPart ], tmpMv );
6873          cuMvField->setRefIdx( g_auiRasterToZscan[ partAddrRasterPart ], refIdx );
6874        }
6875      }
6876    }
6877  }
6878
6879  vspSize = (vspSize<<2)+1;
6880
6881}
6882#endif
6883
6884//! \}
Note: See TracBrowser for help on using the repository browser.