source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2/source/Lib/TLibCommon/TComDataCU.cpp @ 522

Last change on this file since 522 was 522, checked in by mitsubishi-htm, 12 years ago

-intermediate version. fixing issues between VSP and interview motion prediction.

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