source: 3DVCSoftware/branches/HTM-15.1-dev0-Vidyo/source/Lib/TLibCommon/TComDataCU.cpp @ 1332

Last change on this file since 1332 was 1321, checked in by tech, 10 years ago

Merged 15.0-dev0@1320.

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