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

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

-VSP remaining stuff wrapped up.
-4x4 VSP in effect.

  • Property svn:eol-style set to native
File size: 186.6 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#endif
2192
2193Void TComDataCU::setChromIntraDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiDepth )
2194{
2195  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2196 
2197  memset( m_puhChromaIntraDir + uiAbsPartIdx, uiDir, sizeof(UChar)*uiCurrPartNumb );
2198}
2199
2200Void TComDataCU::setInterDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2201{
2202  setSubPart<UChar>( uiDir, m_puhInterDir, uiAbsPartIdx, uiDepth, uiPartIdx );
2203}
2204
2205Void TComDataCU::setMVPIdxSubParts( Int iMVPIdx, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2206{
2207  setSubPart<Char>( iMVPIdx, m_apiMVPIdx[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2208}
2209
2210Void TComDataCU::setMVPNumSubParts( Int iMVPNum, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2211{
2212  setSubPart<Char>( iMVPNum, m_apiMVPNum[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2213}
2214
2215
2216Void TComDataCU::setTrIdxSubParts( UInt uiTrIdx, UInt uiAbsPartIdx, UInt uiDepth )
2217{
2218  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2219 
2220  memset( m_puhTrIdx + uiAbsPartIdx, uiTrIdx, sizeof(UChar)*uiCurrPartNumb );
2221}
2222
2223Void TComDataCU::setTransformSkipSubParts( UInt useTransformSkipY, UInt useTransformSkipU, UInt useTransformSkipV, UInt uiAbsPartIdx, UInt uiDepth )
2224{
2225  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2226
2227  memset( m_puhTransformSkip[0] + uiAbsPartIdx, useTransformSkipY, sizeof( UChar ) * uiCurrPartNumb );
2228  memset( m_puhTransformSkip[1] + uiAbsPartIdx, useTransformSkipU, sizeof( UChar ) * uiCurrPartNumb );
2229  memset( m_puhTransformSkip[2] + uiAbsPartIdx, useTransformSkipV, sizeof( UChar ) * uiCurrPartNumb );
2230}
2231
2232Void TComDataCU::setTransformSkipSubParts( UInt useTransformSkip, TextType eType, UInt uiAbsPartIdx, UInt uiDepth)
2233{
2234  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2235
2236  memset( m_puhTransformSkip[g_aucConvertTxtTypeToIdx[eType]] + uiAbsPartIdx, useTransformSkip, sizeof( UChar ) * uiCurrPartNumb );
2237}
2238
2239Void TComDataCU::setSizeSubParts( UInt uiWidth, UInt uiHeight, UInt uiAbsPartIdx, UInt uiDepth )
2240{
2241  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2242 
2243  memset( m_puhWidth  + uiAbsPartIdx, uiWidth,  sizeof(UChar)*uiCurrPartNumb );
2244  memset( m_puhHeight + uiAbsPartIdx, uiHeight, sizeof(UChar)*uiCurrPartNumb );
2245}
2246
2247UChar TComDataCU::getNumPartInter()
2248{
2249  UChar iNumPart = 0;
2250 
2251  switch ( m_pePartSize[0] )
2252  {
2253    case SIZE_2Nx2N:    iNumPart = 1; break;
2254    case SIZE_2NxN:     iNumPart = 2; break;
2255    case SIZE_Nx2N:     iNumPart = 2; break;
2256    case SIZE_NxN:      iNumPart = 4; break;
2257    case SIZE_2NxnU:    iNumPart = 2; break;
2258    case SIZE_2NxnD:    iNumPart = 2; break;
2259    case SIZE_nLx2N:    iNumPart = 2; break;
2260    case SIZE_nRx2N:    iNumPart = 2; break;
2261    default:            assert (0);   break;
2262  }
2263 
2264  return  iNumPart;
2265}
2266
2267#if H_3D_IC
2268Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight, UInt uiAbsPartIdx, Bool bLCU)
2269{
2270  UInt uiNumPartition  = bLCU ? (getWidth(uiAbsPartIdx)*getHeight(uiAbsPartIdx) >> 4) : m_uiNumPartition;
2271  UInt  uiTmpAbsPartIdx  = bLCU ? uiAbsPartIdx : 0;
2272
2273  switch ( m_pePartSize[uiTmpAbsPartIdx] )
2274  {
2275  case SIZE_2NxN:
2276    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 1;
2277    break;
2278  case SIZE_Nx2N:
2279    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 2;
2280    break;
2281  case SIZE_NxN:
2282    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiNumPartition >> 2 ) * uiPartIdx;
2283    break;
2284  case SIZE_2NxnU:
2285    riWidth     = getWidth( uiTmpAbsPartIdx );
2286    riHeight    = ( uiPartIdx == 0 ) ?  getHeight( uiTmpAbsPartIdx ) >> 2 : ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 );
2287    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 3;
2288    break;
2289  case SIZE_2NxnD:
2290    riWidth     = getWidth( uiTmpAbsPartIdx );
2291    riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 ) : getHeight( uiTmpAbsPartIdx ) >> 2;
2292    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 1) + (uiNumPartition >> 3);
2293    break;
2294  case SIZE_nLx2N:
2295    riWidth     = ( uiPartIdx == 0 ) ? getWidth( uiTmpAbsPartIdx ) >> 2 : ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 );
2296    riHeight    = getHeight( uiTmpAbsPartIdx );
2297    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 4;
2298    break;
2299  case SIZE_nRx2N:
2300    riWidth     = ( uiPartIdx == 0 ) ? ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 ) : getWidth( uiTmpAbsPartIdx ) >> 2;
2301    riHeight    = getHeight( uiTmpAbsPartIdx );
2302    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 2) + (uiNumPartition >> 4);
2303    break;
2304  default:
2305    assert ( m_pePartSize[uiTmpAbsPartIdx] == SIZE_2Nx2N ); 
2306    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = 0;
2307    break;
2308  }
2309}
2310#else
2311Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight )
2312{
2313  switch ( m_pePartSize[0] )
2314  {
2315    case SIZE_2NxN:
2316      riWidth = getWidth(0);      riHeight = getHeight(0) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2317      break;
2318    case SIZE_Nx2N:
2319      riWidth = getWidth(0) >> 1; riHeight = getHeight(0);      ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2;
2320      break;
2321    case SIZE_NxN:
2322      riWidth = getWidth(0) >> 1; riHeight = getHeight(0) >> 1; ruiPartAddr = ( m_uiNumPartition >> 2 ) * uiPartIdx;
2323      break;
2324    case SIZE_2NxnU:
2325      riWidth     = getWidth(0);
2326      riHeight    = ( uiPartIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
2327      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 3;
2328      break;
2329    case SIZE_2NxnD:
2330      riWidth     = getWidth(0);
2331      riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
2332      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 3);
2333      break;
2334    case SIZE_nLx2N:
2335      riWidth     = ( uiPartIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
2336      riHeight    = getHeight(0);
2337      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 4;
2338      break;
2339    case SIZE_nRx2N:
2340      riWidth     = ( uiPartIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
2341      riHeight    = getHeight(0);
2342      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2343      break;
2344    default:
2345      assert ( m_pePartSize[0] == SIZE_2Nx2N );
2346      riWidth = getWidth(0);      riHeight = getHeight(0);      ruiPartAddr = 0;
2347      break;
2348  }
2349}
2350#endif
2351
2352
2353Void TComDataCU::getMvField ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, TComMvField& rcMvField )
2354{
2355  if ( pcCU == NULL )  // OUT OF BOUNDARY
2356  {
2357    TComMv  cZeroMv;
2358    rcMvField.setMvField( cZeroMv, NOT_VALID );
2359    return;
2360  }
2361 
2362  TComCUMvField*  pcCUMvField = pcCU->getCUMvField( eRefPicList );
2363  rcMvField.setMvField( pcCUMvField->getMv( uiAbsPartIdx ), pcCUMvField->getRefIdx( uiAbsPartIdx ) );
2364}
2365
2366Void TComDataCU::deriveLeftRightTopIdxGeneral ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT )
2367{
2368  ruiPartIdxLT = m_uiAbsIdxInLCU + uiAbsPartIdx;
2369  UInt uiPUWidth = 0;
2370 
2371  switch ( m_pePartSize[uiAbsPartIdx] )
2372  {
2373    case SIZE_2Nx2N: uiPUWidth = m_puhWidth[uiAbsPartIdx];  break;
2374    case SIZE_2NxN:  uiPUWidth = m_puhWidth[uiAbsPartIdx];   break;
2375    case SIZE_Nx2N:  uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1;  break;
2376    case SIZE_NxN:   uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1; break;
2377    case SIZE_2NxnU:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2378    case SIZE_2NxnD:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2379    case SIZE_nLx2N:   
2380      if ( uiPartIdx == 0 )
2381      {
2382        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2; 
2383      }
2384      else if ( uiPartIdx == 1 )
2385      {
2386        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2); 
2387      }
2388      else
2389      {
2390        assert(0);
2391      }
2392      break;
2393    case SIZE_nRx2N:   
2394      if ( uiPartIdx == 0 )
2395      {
2396        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2); 
2397      }
2398      else if ( uiPartIdx == 1 )
2399      {
2400        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2; 
2401      }
2402      else
2403      {
2404        assert(0);
2405      }
2406      break;
2407    default:
2408      assert (0);
2409      break;
2410  }
2411 
2412  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + uiPUWidth / m_pcPic->getMinCUWidth() - 1 ];
2413}
2414
2415Void TComDataCU::deriveLeftBottomIdxGeneral( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLB )
2416{
2417  UInt uiPUHeight = 0;
2418  switch ( m_pePartSize[uiAbsPartIdx] )
2419  {
2420    case SIZE_2Nx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];    break;
2421    case SIZE_2NxN:  uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2422    case SIZE_Nx2N:  uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2423    case SIZE_NxN:   uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2424    case SIZE_2NxnU: 
2425      if ( uiPartIdx == 0 )
2426      {
2427        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;   
2428      }
2429      else if ( uiPartIdx == 1 )
2430      {
2431        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);   
2432      }
2433      else
2434      {
2435        assert(0);
2436      }
2437      break;
2438    case SIZE_2NxnD: 
2439      if ( uiPartIdx == 0 )
2440      {
2441        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);   
2442      }
2443      else if ( uiPartIdx == 1 )
2444      {
2445        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;   
2446      }
2447      else
2448      {
2449        assert(0);
2450      }
2451      break;
2452    case SIZE_nLx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2453    case SIZE_nRx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2454    default:
2455      assert (0);
2456      break;
2457  }
2458 
2459  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_uiAbsIdxInLCU + uiAbsPartIdx ] + ((uiPUHeight / m_pcPic->getMinCUHeight()) - 1)*m_pcPic->getNumPartInWidth()];
2460}
2461
2462Void TComDataCU::deriveLeftRightTopIdx ( UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT )
2463{
2464  ruiPartIdxLT = m_uiAbsIdxInLCU;
2465  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + m_puhWidth[0] / m_pcPic->getMinCUWidth() - 1 ];
2466 
2467  switch ( m_pePartSize[0] )
2468  {
2469    case SIZE_2Nx2N:                                                                                                                                break;
2470    case SIZE_2NxN:
2471      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1; ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2472      break;
2473    case SIZE_Nx2N:
2474      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2; ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 2;
2475      break;
2476    case SIZE_NxN:
2477      ruiPartIdxLT += ( m_uiNumPartition >> 2 ) * uiPartIdx;         ruiPartIdxRT +=  ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );
2478      break;
2479    case SIZE_2NxnU:
2480      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2481      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2482      break;
2483    case SIZE_2NxnD:
2484      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2485      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2486      break;
2487    case SIZE_nLx2N:
2488      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 4;
2489      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2490      break;
2491    case SIZE_nRx2N:
2492      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2493      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 4;
2494      break;
2495    default:
2496      assert (0);
2497      break;
2498  }
2499 
2500}
2501
2502Void TComDataCU::deriveLeftBottomIdx( UInt  uiPartIdx,      UInt&      ruiPartIdxLB )
2503{
2504  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_uiAbsIdxInLCU ] + ( ((m_puhHeight[0] / m_pcPic->getMinCUHeight())>>1) - 1)*m_pcPic->getNumPartInWidth()];
2505 
2506  switch ( m_pePartSize[0] )
2507  {
2508    case SIZE_2Nx2N:
2509      ruiPartIdxLB += m_uiNumPartition >> 1;
2510      break;
2511    case SIZE_2NxN:
2512      ruiPartIdxLB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2513      break;
2514    case SIZE_Nx2N:
2515      ruiPartIdxLB += ( uiPartIdx == 0 )? m_uiNumPartition >> 1 : (m_uiNumPartition >> 2)*3;
2516      break;
2517    case SIZE_NxN:
2518      ruiPartIdxLB += ( m_uiNumPartition >> 2 ) * uiPartIdx;
2519      break;
2520    case SIZE_2NxnU:
2521      ruiPartIdxLB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2522      break;
2523    case SIZE_2NxnD:
2524      ruiPartIdxLB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2525      break;
2526    case SIZE_nLx2N:
2527      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 4);
2528      break;
2529    case SIZE_nRx2N:
2530      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2531      break;
2532    default:
2533      assert (0);
2534      break;
2535  }
2536}
2537
2538/** Derives the partition index of neighbouring bottom right block
2539 * \param [in]  eCUMode
2540 * \param [in]  uiPartIdx
2541 * \param [out] ruiPartIdxRB
2542 */
2543Void TComDataCU::deriveRightBottomIdx( UInt  uiPartIdx,      UInt&      ruiPartIdxRB )
2544{
2545  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];
2546
2547  switch ( m_pePartSize[0] )
2548  {
2549    case SIZE_2Nx2N: 
2550      ruiPartIdxRB += m_uiNumPartition >> 1;   
2551      break;
2552    case SIZE_2NxN: 
2553      ruiPartIdxRB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;   
2554      break;
2555    case SIZE_Nx2N: 
2556      ruiPartIdxRB += ( uiPartIdx == 0 )? m_uiNumPartition >> 2 : (m_uiNumPartition >> 1);   
2557      break;
2558    case SIZE_NxN:   
2559      ruiPartIdxRB += ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );   
2560      break;
2561    case SIZE_2NxnU:
2562      ruiPartIdxRB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2563      break;
2564    case SIZE_2NxnD:
2565      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2566      break;
2567    case SIZE_nLx2N:
2568      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4): m_uiNumPartition >> 1;
2569      break;
2570    case SIZE_nRx2N:
2571      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4) : m_uiNumPartition >> 1;
2572      break;
2573    default:
2574      assert (0);
2575      break;
2576  }
2577}
2578
2579Void TComDataCU::deriveLeftRightTopIdxAdi ( UInt& ruiPartIdxLT, UInt& ruiPartIdxRT, UInt uiPartOffset, UInt uiPartDepth )
2580{
2581  UInt uiNumPartInWidth = (m_puhWidth[0]/m_pcPic->getMinCUWidth())>>uiPartDepth;
2582  ruiPartIdxLT = m_uiAbsIdxInLCU + uiPartOffset;
2583  ruiPartIdxRT = g_auiRasterToZscan[ g_auiZscanToRaster[ ruiPartIdxLT ] + uiNumPartInWidth - 1 ];
2584}
2585
2586Void TComDataCU::deriveLeftBottomIdxAdi( UInt& ruiPartIdxLB, UInt uiPartOffset, UInt uiPartDepth )
2587{
2588  UInt uiAbsIdx;
2589  UInt uiMinCuWidth, uiWidthInMinCus;
2590 
2591  uiMinCuWidth    = getPic()->getMinCUWidth();
2592  uiWidthInMinCus = (getWidth(0)/uiMinCuWidth)>>uiPartDepth;
2593  uiAbsIdx        = getZorderIdxInCU()+uiPartOffset+(m_uiNumPartition>>(uiPartDepth<<1))-1;
2594  uiAbsIdx        = g_auiZscanToRaster[uiAbsIdx]-(uiWidthInMinCus-1);
2595  ruiPartIdxLB    = g_auiRasterToZscan[uiAbsIdx];
2596}
2597
2598Bool TComDataCU::hasEqualMotion( UInt uiAbsPartIdx, TComDataCU* pcCandCU, UInt uiCandAbsPartIdx )
2599{
2600
2601  if ( getInterDir( uiAbsPartIdx ) != pcCandCU->getInterDir( uiCandAbsPartIdx ) )
2602  {
2603    return false;
2604  }
2605
2606  for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
2607  {
2608    if ( getInterDir( uiAbsPartIdx ) & ( 1 << uiRefListIdx ) )
2609    {
2610      if ( getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiAbsPartIdx )     != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiCandAbsPartIdx ) || 
2611        getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiAbsPartIdx ) != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiCandAbsPartIdx ) )
2612      {
2613        return false;
2614      }
2615    }
2616  }
2617
2618  return true;
2619}
2620
2621#if H_3D_VSP
2622
2623/** Add a VSP merging candidate
2624 * \Inputs
2625 * \param uiPUIdx: PU index within a CU
2626 * \param ucVspMergePos: Specify the VSP merge candidate position
2627 * \param mrgCandIdx: Target merge candidate index. At encoder, it is set equal to -1, such that the whole merge candidate list will be constructed.
2628 * \param pDinfo: The "disparity information" derived from neighboring blocks. Type 1 MV.
2629 * \param uiCount: The next position to add VSP merge candidate
2630 *
2631 * \Outputs
2632 * \param uiCount: The next position to add merge candidate. Will be updated if VSP is successfully added
2633 * \param abCandIsInter: abCandIsInter[iCount] tells that VSP candidate is an Inter candidate, if VSP is successfully added
2634 * \param pcMvFieldNeighbours:   Return combined motion information, then stored to a global buffer
2635 *                                    1) the "disparity vector". Type 1 MV. To be used to fetch a depth block.
2636 *                                    2) the ref index /list.    Type 2 reference picture pointer, typically for texture
2637 * \param puhInterDirNeighbours: Indicate the VSP prediction direction.
2638 * \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
2639 *
2640 * \Return
2641 *   true:  if the VSP candidate is added at the target position
2642 *   false: otherwise
2643 */
2644inline Bool TComDataCU::xAddVspCand( UChar ucVspMergePos, Int mrgCandIdx, DisInfo* pDInfo, Int& iCount,
2645                                     Bool* abCandIsInter, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int* vspFlag )
2646{
2647  if ( ucVspMergePos != H_3D_VSP_POSITION || 0 == m_pcSlice->getViewIndex() || !m_pcSlice->getVPS()->getViewSynthesisPredFlag( m_pcSlice->getLayerIdInVps() ) || m_pcSlice->getIsDepth() )
2648    return false;
2649
2650  Int refViewIdx = pDInfo->m_aVIdxCan;
2651  TComPic* picDepth = getSlice()->getIvPic( true, refViewIdx );
2652  if( picDepth == NULL ) // No depth reference avail
2653    return false;
2654 
2655  Bool refViewAvailFlag = false;
2656  UChar predFlag[2] = {0, 0};
2657  Int  iRefListIdX = 0;
2658  Int  iRefListIdY = 0;
2659  Int  i;
2660
2661  for( iRefListIdX = 0; iRefListIdX < 2 && !refViewAvailFlag; iRefListIdX++ )
2662  {
2663    RefPicList eRefPicList = RefPicList( iRefListIdX );
2664    for ( i = 0; i < m_pcSlice->getNumRefIdx(eRefPicList) && !refViewAvailFlag; i++ )
2665    {
2666      Int viewIdxRefInList = m_pcSlice->getRefPic(eRefPicList, i)->getViewIndex();
2667      if ( viewIdxRefInList == refViewIdx )
2668      {
2669        refViewAvailFlag = true;
2670        predFlag[iRefListIdX] = 1;
2671        iRefListIdY = 1 - iRefListIdX;
2672        pcMvFieldNeighbours[(iCount<<1)+iRefListIdX].setMvField( pDInfo->m_acDoNBDV, i );
2673#if H_3D_NBDV
2674        pcMvFieldNeighbours[(iCount<<1)+iRefListIdX].getMv().setIDVFlag (false);
2675#endif
2676      }
2677    }
2678  }
2679
2680  if (m_pcSlice->isInterB() && refViewAvailFlag)
2681  {
2682    RefPicList eRefPicList = RefPicList( iRefListIdY );
2683    refViewAvailFlag = false;
2684    for ( i = 0; i < m_pcSlice->getNumRefIdx(eRefPicList) && !refViewAvailFlag; i++ )
2685    {
2686      Int viewIdxRefInList = m_pcSlice->getRefPic(eRefPicList, i)->getViewIndex();
2687      if ( viewIdxRefInList != refViewIdx && viewIdxRefInList != m_pcSlice->getViewIndex() )
2688      {
2689        refViewAvailFlag = true;
2690        predFlag[iRefListIdY] = 1;
2691        pcMvFieldNeighbours[(iCount<<1)+iRefListIdY].setMvField( pDInfo->m_acDoNBDV, i );
2692#if H_3D_NBDV
2693        pcMvFieldNeighbours[(iCount<<1)+iRefListIdY].getMv().setIDVFlag (false);
2694#endif
2695      }
2696    }
2697  }
2698
2699  // Set values to be returned
2700  abCandIsInter[iCount] = true;
2701  puhInterDirNeighbours[iCount] = (predFlag[0] | (predFlag[1] << 1));
2702  vspFlag[iCount] = 1;
2703
2704  if ( mrgCandIdx == iCount )
2705    return true;
2706
2707  iCount++;
2708
2709  return false;
2710}
2711
2712#endif
2713
2714/** Constructs a list of merging candidates
2715 * \param uiAbsPartIdx
2716 * \param uiPUIdx
2717 * \param uiDepth
2718 * \param pcMvFieldNeighbours
2719 * \param puhInterDirNeighbours
2720 * \param numValidMergeCand
2721 */
2722Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours
2723#if H_3D_VSP
2724      , Int* vspFlag
2725#endif
2726      , Int& numValidMergeCand, Int mrgCandIdx
2727)
2728{
2729  UInt uiAbsPartAddr = m_uiAbsIdxInLCU + uiAbsPartIdx;
2730#if H_3D_IV_MERGE
2731  TComMv cZeroMv;
2732  Bool abCandIsInter[ MRG_MAX_NUM_CANDS_MEM ];
2733#else
2734  Bool abCandIsInter[ MRG_MAX_NUM_CANDS ];
2735#endif
2736  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
2737  {
2738    abCandIsInter[ui] = false;
2739#if H_3D_IV_MERGE
2740    pcMvFieldNeighbours[ ( ui << 1 )     ].setMvField(cZeroMv, NOT_VALID);
2741    pcMvFieldNeighbours[ ( ui << 1 ) + 1 ].setMvField(cZeroMv, NOT_VALID);
2742#else
2743    pcMvFieldNeighbours[ ( ui << 1 )     ].setRefIdx(NOT_VALID);
2744    pcMvFieldNeighbours[ ( ui << 1 ) + 1 ].setRefIdx(NOT_VALID);
2745#endif
2746  }
2747  numValidMergeCand = getSlice()->getMaxNumMergeCand();
2748  // compute the location of the current PU
2749  Int xP, yP, nPSW, nPSH;
2750  this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
2751
2752  Int iCount = 0;
2753
2754  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
2755  PartSize cCurPS = getPartitionSize( uiAbsPartIdx );
2756  deriveLeftRightTopIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLT, uiPartIdxRT );
2757  deriveLeftBottomIdxGeneral  ( uiAbsPartIdx, uiPUIdx, uiPartIdxLB );
2758#if H_3D_IV_MERGE
2759  Bool ivMvPredFlag   = getSlice()->getVPS()->getIvMvPredFlag( getSlice()->getLayerIdInVps() );
2760
2761  //===== add merge with predicted depth maps =====
2762  TComMv  acPdmMv       [4];
2763  Int     aiPdmRefIdx   [4] = {-1, -1, -1, -1};
2764  Bool    bLeftAvai         = false;
2765  Int     iPosLeftAbove[2]  = {-1, -1};
2766
2767
2768  DisInfo cDisInfo;
2769
2770  cDisInfo.bDV = getDvInfo(uiAbsPartIdx).bDV;
2771#if H_3D_NBDV_REF
2772  cDisInfo.m_acDoNBDV = getDvInfo(uiAbsPartIdx).m_acDoNBDV;
2773#endif //H_3D_NBDV_REF
2774  cDisInfo.m_acNBDV = getDvInfo(uiAbsPartIdx).m_acNBDV;
2775  cDisInfo.m_aVIdxCan = getDvInfo(uiAbsPartIdx).m_aVIdxCan;
2776
2777  if( m_pcSlice->getIsDepth())
2778  {
2779    UInt uiPartIdxCenter;
2780    xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );   
2781    TComDataCU *pcTextureCU = m_pcSlice->getTexturePic()->getCU( getAddr() );
2782 
2783    if ( pcTextureCU && !pcTextureCU->isIntra( uiPartIdxCenter ) )
2784    {
2785      abCandIsInter[iCount] = true;     
2786      puhInterDirNeighbours[iCount] = pcTextureCU->getInterDir( uiPartIdxCenter );
2787      if( ( puhInterDirNeighbours[iCount] & 1 ) == 1 )
2788      {
2789        pcTextureCU->getMvField( pcTextureCU, uiPartIdxCenter, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
2790        TComMv cMvPred = pcMvFieldNeighbours[iCount<<1].getMv();
2791
2792#if H_3D_IC
2793        const TComMv cAdd( 1 << ( 2 - 1 ), 1 << ( 2 - 1 ) );
2794        cMvPred+=cAdd;
2795        cMvPred>>=2;
2796        clipMv(cMvPred);
2797#endif
2798        //pcMvFieldNeighbours[iCount<<1].setMvField(cMvPred,pcMvFieldNeighbours[iCount<<1].getRefIdx());
2799#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
2800        pcMvFieldNeighbours[iCount<<1].setMvField(cMvPred,pcMvFieldNeighbours[iCount<<1].getRefIdx());
2801#else
2802        if (pcMvFieldNeighbours[iCount<<1].getRefIdx()<0)
2803        {
2804          for (Int i=0; i<getSlice()->getNumRefIdx(REF_PIC_LIST_0); i++)
2805          {
2806            if (getSlice()->getRefPOC(REF_PIC_LIST_0, i) == getSlice()->getPOC())
2807            {
2808              pcMvFieldNeighbours[iCount<<1].setMvField(cMvPred,i);
2809              break;
2810            }
2811          }
2812        }
2813#endif
2814      }
2815     
2816      if ( getSlice()->isInterB() )
2817      {
2818        if( ( puhInterDirNeighbours[iCount] & 2 ) == 2 )
2819        {
2820          pcTextureCU->getMvField( pcTextureCU, uiPartIdxCenter, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
2821          TComMv cMvPred = pcMvFieldNeighbours[(iCount<<1)+1].getMv();
2822
2823#if H_3D_IC
2824          const TComMv cAdd( 1 << ( 2 - 1 ), 1 << ( 2 - 1 ) );
2825          cMvPred+=cAdd;
2826          cMvPred>>=2;
2827          clipMv(cMvPred);
2828#endif
2829          //pcMvFieldNeighbours[(iCount<<1)+1].setMvField(cMvPred,pcMvFieldNeighbours[(iCount<<1)+1].getRefIdx());
2830#if H_3D_CLEANUPS
2831          pcMvFieldNeighbours[(iCount<<1)+1].setMvField(cMvPred,pcMvFieldNeighbours[(iCount<<1)+1].getRefIdx());
2832#else
2833          if (pcMvFieldNeighbours[(iCount<<1)+1].getRefIdx()<0)
2834          {
2835            for (Int i=0; i<getSlice()->getNumRefIdx(REF_PIC_LIST_1); i++)
2836            {
2837              if (getSlice()->getRefPOC(REF_PIC_LIST_1, i) == getSlice()->getPOC())
2838              {
2839                pcMvFieldNeighbours[(iCount<<1)+1].setMvField(cMvPred,i);
2840                break;
2841              }
2842            }
2843          }
2844#endif
2845        }
2846      }
2847#if !H_3D_CLEANUPS
2848      if (!((pcMvFieldNeighbours[iCount<<1].getRefIdx()<0 && !getSlice()->isInterB())
2849        || (pcMvFieldNeighbours[iCount<<1].getRefIdx()<0 && pcMvFieldNeighbours[(iCount<<1)+1].getRefIdx()<0 && getSlice()->isInterB())))
2850      {
2851#endif
2852#if H_3D_NBDV
2853      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
2854      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
2855#endif
2856      if ( mrgCandIdx == iCount )
2857      {
2858        return;
2859      }
2860      iCount ++;
2861#if !H_3D_CLEANUPS
2862      }
2863      else
2864      {
2865        assert(0);
2866      }
2867#endif
2868    }
2869  }
2870
2871  Int iPdmDir[2] = {0, 0};
2872 
2873  if ( ivMvPredFlag )
2874  {
2875    getInterViewMergeCands(uiPUIdx, aiPdmRefIdx, acPdmMv, &cDisInfo, iPdmDir );
2876  } 
2877   
2878  Int iPdmInterDir;
2879#if H_3D_CLEANUPS
2880  if( iPdmDir[0] )
2881#else
2882  if( iPdmDir[0] && ivMvPredFlag )
2883#endif
2884  {
2885    abCandIsInter        [ iCount ] = true;
2886    puhInterDirNeighbours[ iCount ] = iPdmDir[0];
2887    iPdmInterDir                    = iPdmDir[0];
2888
2889    if( ( iPdmInterDir & 1 ) == 1 )
2890    {
2891      pcMvFieldNeighbours[ iCount<<1    ].setMvField( acPdmMv[ 0 ], aiPdmRefIdx[ 0 ] );
2892    }
2893    if( ( iPdmInterDir & 2 ) == 2 )
2894    {
2895      pcMvFieldNeighbours[(iCount<<1)+1 ].setMvField( acPdmMv[ 1 ], aiPdmRefIdx[ 1 ] );
2896    }
2897
2898    if ( mrgCandIdx == iCount )
2899    {
2900      return;
2901    }
2902    iCount ++;
2903  } 
2904#if H_3D_CLEANUPS
2905  // early termination
2906  if (iCount == getSlice()->getMaxNumMergeCand()) 
2907  {
2908    return;
2909  }
2910#endif
2911#endif
2912
2913#if !H_3D_IV_MERGE
2914#if H_3D_NBDV //Notes from QC: DvMCP related variables. 
2915  //acPdmMv[0].m_bDvMcp = acPdmMv[1].m_bDvMcp = acPdmMv[2].m_bDvMcp = acPdmMv[3].m_bDvMcp = false;
2916#endif
2917
2918#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
2919  DisInfo cDisInfo;
2920  cDisInfo.bDV = false; 
2921  //if(!bNoPdmMerge)
2922  //{
2923    //cDisInfo.bDV = getDvInfo(uiAbsPartIdx).bDV;
2924    //cDisInfo.m_aVIdxCan = getDvInfo(uiAbsPartIdx).m_aVIdxCan;
2925    //cDisInfo.m_acNBDV = getDvInfo(uiAbsPartIdx).m_acNBDV;
2926//#if H_3D_NBDV_REF
2927    //cDisInfo.m_acDoNBDV = getDvInfo(uiAbsPartIdx).m_acDoNBDV;
2928//#endif
2929  //}
2930#endif
2931#endif
2932  //left
2933  UInt uiLeftPartIdx = 0;
2934  TComDataCU* pcCULeft = 0;
2935  pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB );
2936  Bool isAvailableA1 = pcCULeft &&
2937  pcCULeft->isDiffMER(xP -1, yP+nPSH-1, xP, yP) &&
2938  !( uiPUIdx == 1 && (cCurPS == SIZE_Nx2N || cCurPS == SIZE_nLx2N || cCurPS == SIZE_nRx2N) ) &&
2939  !pcCULeft->isIntra( uiLeftPartIdx ) ;
2940  if ( isAvailableA1 )
2941  {
2942    abCandIsInter[iCount] = true;
2943    // get Inter Dir
2944    puhInterDirNeighbours[iCount] = pcCULeft->getInterDir( uiLeftPartIdx );
2945    // get Mv from Left
2946    pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
2947    if ( getSlice()->isInterB() )
2948    {
2949      pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
2950    }
2951#if H_3D_IV_MERGE
2952    Bool bRemoveSpa = false; //pruning to inter-view candidates
2953    Int  iCnloop    = iCount - 1;
2954    for(; iCnloop >= 0; iCnloop --)
2955    {
2956      if(puhInterDirNeighbours[iCount] == puhInterDirNeighbours[iCnloop] && pcMvFieldNeighbours[iCnloop<<1]==pcMvFieldNeighbours[(iCount<<1)] && pcMvFieldNeighbours[(iCnloop<<1)+1]==pcMvFieldNeighbours[(iCount<<1)+1])
2957      {
2958        bRemoveSpa                      = true;
2959        abCandIsInter        [ iCount ] = false;
2960
2961        //reset to the default value for MC
2962        puhInterDirNeighbours[iCount]   = 0;
2963        pcMvFieldNeighbours[iCount<<1].setMvField( cZeroMv, NOT_VALID );
2964        pcMvFieldNeighbours[(iCount<<1)+1].setMvField( cZeroMv, NOT_VALID );
2965        break;
2966      }
2967    }
2968    if(!bRemoveSpa)
2969    {
2970      bLeftAvai = true;
2971      iPosLeftAbove[0] = iCount;
2972#if H_3D_NBDV
2973      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
2974      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
2975#endif
2976#if H_3D_VSP
2977      if (pcCULeft->getVSPFlag(uiLeftPartIdx) == 1)
2978        vspFlag[iCount] = 1;
2979#endif
2980      if ( mrgCandIdx == iCount )
2981      {
2982        return;
2983      }
2984      iCount ++;
2985    }
2986#else
2987    if ( mrgCandIdx == iCount )
2988    {
2989      return;
2990    }
2991    iCount ++;
2992#endif
2993  }
2994 
2995  // early termination
2996  if (iCount == getSlice()->getMaxNumMergeCand()) 
2997  {
2998    return;
2999  }
3000  // above
3001  UInt uiAbovePartIdx = 0;
3002  TComDataCU* pcCUAbove = 0;
3003  pcCUAbove = getPUAbove( uiAbovePartIdx, uiPartIdxRT );
3004  Bool isAvailableB1 = pcCUAbove &&
3005  pcCUAbove->isDiffMER(xP+nPSW-1, yP-1, xP, yP) &&
3006  !( uiPUIdx == 1 && (cCurPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD) ) &&
3007  !pcCUAbove->isIntra( uiAbovePartIdx );
3008  if ( isAvailableB1 && (!isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
3009  {
3010    abCandIsInter[iCount] = true;
3011    // get Inter Dir
3012    puhInterDirNeighbours[iCount] = pcCUAbove->getInterDir( uiAbovePartIdx );
3013    // get Mv from Left
3014    pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3015    if ( getSlice()->isInterB() )
3016    {
3017      pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3018    }
3019#if H_3D_IV_MERGE
3020    Bool bRemoveSpa = false; //pruning to inter-view candidates
3021    Int  iCnloop    = bLeftAvai? (iCount-2): (iCount-1);
3022    for(; iCnloop >= 0; iCnloop --)
3023    {
3024      if(puhInterDirNeighbours[iCount] == puhInterDirNeighbours[iCnloop] && pcMvFieldNeighbours[iCnloop<<1]==pcMvFieldNeighbours[(iCount<<1)] && pcMvFieldNeighbours[(iCnloop<<1)+1]==pcMvFieldNeighbours[(iCount<<1)+1])
3025      {
3026        bRemoveSpa                      = true;
3027        abCandIsInter        [ iCount ] = false;
3028
3029        //reset to the default value for MC
3030        puhInterDirNeighbours[iCount]   = 0;
3031
3032        pcMvFieldNeighbours[iCount<<1].setMvField( cZeroMv, NOT_VALID );
3033        pcMvFieldNeighbours[(iCount<<1)+1].setMvField( cZeroMv, NOT_VALID );
3034        break;
3035      }
3036    }
3037    if(!bRemoveSpa)
3038    {
3039      iPosLeftAbove[1] = iCount;
3040#if H_3D_NBDV
3041      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
3042      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
3043#endif
3044#if H_3D_VSP
3045      if (pcCUAbove->getVSPFlag(uiAbovePartIdx) == 1)
3046        vspFlag[iCount] = 1;
3047#endif
3048      if ( mrgCandIdx == iCount )
3049      {
3050        return;
3051      }
3052      iCount ++;
3053    }
3054#else
3055    if ( mrgCandIdx == iCount )
3056    {
3057      return;
3058    }
3059    iCount ++;
3060#endif
3061  }
3062  // early termination
3063  if (iCount == getSlice()->getMaxNumMergeCand()) 
3064  {
3065    return;
3066  }
3067
3068  // above right
3069  UInt uiAboveRightPartIdx = 0;
3070  TComDataCU* pcCUAboveRight = 0;
3071  pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT );
3072  Bool isAvailableB0 = pcCUAboveRight &&
3073  pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP) &&
3074  !pcCUAboveRight->isIntra( uiAboveRightPartIdx );
3075  if ( isAvailableB0 && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
3076  {
3077    abCandIsInter[iCount] = true;
3078    // get Inter Dir
3079    puhInterDirNeighbours[iCount] = pcCUAboveRight->getInterDir( uiAboveRightPartIdx );
3080    // get Mv from Left
3081    pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3082    if ( getSlice()->isInterB() )
3083    {
3084      pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3085    }
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 (pcCUAboveRight->getVSPFlag(uiAboveRightPartIdx) == 1)
3092      vspFlag[iCount] = 1;
3093#endif
3094    if ( mrgCandIdx == iCount )
3095    {
3096      return;
3097    }
3098    iCount ++;
3099  }
3100  // early termination
3101  if (iCount == getSlice()->getMaxNumMergeCand()) 
3102  {
3103    return;
3104  }
3105
3106#if H_3D_IV_MERGE
3107#if H_3D_CLEANUPS
3108  if( iPdmDir[1] )
3109#else
3110  if(ivMvPredFlag && iPdmDir[1] )
3111#endif
3112  {
3113    assert(iCount < getSlice()->getMaxNumMergeCand());
3114    abCandIsInter        [ iCount ] = true;
3115    puhInterDirNeighbours[ iCount ] = iPdmDir[1];
3116    if( ( iPdmDir[1] & 1 ) == 1 )
3117    {
3118      pcMvFieldNeighbours[ iCount<<1    ].setMvField( acPdmMv[ 2 ], aiPdmRefIdx[ 2 ] );
3119    }
3120    if( ( iPdmDir[1] & 2 ) == 2 )
3121    {
3122      pcMvFieldNeighbours[(iCount<<1)+1 ].setMvField( acPdmMv[ 3 ], aiPdmRefIdx[ 3 ] );
3123    }
3124
3125    Bool bRemoveSpa = false; //pruning to A1, B1
3126    for(Int i = 0; i < 2; i ++)
3127    {
3128      Int iCnloop = iPosLeftAbove[i];
3129      if(iCnloop == -1) 
3130        continue;
3131      if(puhInterDirNeighbours[iCount] == puhInterDirNeighbours[iCnloop] && pcMvFieldNeighbours[iCnloop<<1]==pcMvFieldNeighbours[(iCount<<1)] && pcMvFieldNeighbours[(iCnloop<<1)+1]==pcMvFieldNeighbours[(iCount<<1)+1])
3132      {
3133        bRemoveSpa                      = true;
3134        abCandIsInter        [ iCount ] = false;
3135        //reset to the default value for MC
3136        puhInterDirNeighbours[iCount]   = 0;
3137        pcMvFieldNeighbours[iCount<<1].setMvField( cZeroMv, NOT_VALID );
3138        pcMvFieldNeighbours[(iCount<<1)+1].setMvField( cZeroMv, NOT_VALID );
3139        break;
3140      }     
3141    }
3142    if(!bRemoveSpa)
3143    {
3144#if H_3D_NBDV
3145      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
3146      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
3147#endif
3148      if ( mrgCandIdx == iCount )
3149        return;
3150      iCount ++;
3151
3152      // early termination
3153      if (iCount == getSlice()->getMaxNumMergeCand()) 
3154      {
3155        return;
3156      }
3157    }
3158  } 
3159#endif
3160
3161#if H_3D_VSP
3162  if ( xAddVspCand( H_3D_VSP_POSITION, mrgCandIdx, &cDisInfo, iCount, abCandIsInter, pcMvFieldNeighbours, puhInterDirNeighbours, vspFlag ) )
3163    return;
3164  // early termination
3165  if (iCount == getSlice()->getMaxNumMergeCand())
3166    return;
3167#endif
3168
3169  //left bottom
3170  UInt uiLeftBottomPartIdx = 0;
3171  TComDataCU* pcCULeftBottom = 0;
3172  pcCULeftBottom = this->getPUBelowLeft( uiLeftBottomPartIdx, uiPartIdxLB );
3173  Bool isAvailableA0 = pcCULeftBottom &&
3174  pcCULeftBottom->isDiffMER(xP-1, yP+nPSH, xP, yP) &&
3175  !pcCULeftBottom->isIntra( uiLeftBottomPartIdx ) ;
3176  if ( isAvailableA0 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCULeftBottom, uiLeftBottomPartIdx ) ) )
3177  {
3178    abCandIsInter[iCount] = true;
3179    // get Inter Dir
3180    puhInterDirNeighbours[iCount] = pcCULeftBottom->getInterDir( uiLeftBottomPartIdx );
3181    // get Mv from Left
3182    pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3183    if ( getSlice()->isInterB() )
3184    {
3185      pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3186    }
3187#if H_3D_NBDV
3188    pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
3189    pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
3190#endif
3191#if H_3D_VSP
3192    if (pcCULeftBottom->getVSPFlag(uiLeftBottomPartIdx) == 1)
3193      vspFlag[iCount] = 1;
3194#endif
3195    if ( mrgCandIdx == iCount )
3196    {
3197      return;
3198    }
3199    iCount ++;
3200  }
3201  // early termination
3202  if (iCount == getSlice()->getMaxNumMergeCand()) 
3203  {
3204    return;
3205  }
3206  // above left
3207  if( iCount < 4 )
3208  {
3209    UInt uiAboveLeftPartIdx = 0;
3210    TComDataCU* pcCUAboveLeft = 0;
3211    pcCUAboveLeft = getPUAboveLeft( uiAboveLeftPartIdx, uiAbsPartAddr );
3212    Bool isAvailableB2 = pcCUAboveLeft &&
3213    pcCUAboveLeft->isDiffMER(xP-1, yP-1, xP, yP) &&
3214    !pcCUAboveLeft->isIntra( uiAboveLeftPartIdx );
3215    if ( isAvailableB2 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) )
3216        && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) ) )
3217    {
3218      abCandIsInter[iCount] = true;
3219      // get Inter Dir
3220      puhInterDirNeighbours[iCount] = pcCUAboveLeft->getInterDir( uiAboveLeftPartIdx );
3221      // get Mv from Left
3222      pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
3223      if ( getSlice()->isInterB() )
3224      {
3225        pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
3226      }
3227#if H_3D_NBDV
3228      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
3229      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
3230#endif
3231#if H_3D_VSP
3232      if (pcCUAboveLeft->getVSPFlag(uiAboveLeftPartIdx) == 1)
3233        vspFlag[iCount] = 1;
3234#endif
3235      if ( mrgCandIdx == iCount )
3236      {
3237        return;
3238      }
3239      iCount ++;
3240    }
3241  }
3242  // early termination
3243  if (iCount == getSlice()->getMaxNumMergeCand()) 
3244  {
3245    return;
3246  }
3247  if ( getSlice()->getEnableTMVPFlag())
3248  {
3249    //>> MTK colocated-RightBottom
3250    UInt uiPartIdxRB;
3251    Int uiLCUIdx = getAddr();
3252
3253    deriveRightBottomIdx( uiPUIdx, uiPartIdxRB ); 
3254
3255    UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
3256    UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
3257
3258    TComMv cColMv;
3259    Int iRefIdx;
3260
3261    if      ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )  // image boundary check
3262    {
3263      uiLCUIdx = -1;
3264    }
3265    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
3266    {
3267      uiLCUIdx = -1;
3268    }
3269    else
3270    {
3271      if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
3272        ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
3273      {
3274        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
3275        uiLCUIdx = getAddr();
3276      }
3277      else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
3278      {
3279        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdxTmp + uiNumPartInCUWidth + 1) % m_pcPic->getNumPartInCU() ];
3280        uiLCUIdx = -1 ; 
3281      }
3282      else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
3283      {
3284        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
3285        uiLCUIdx = getAddr() + 1;
3286      }
3287      else //is the right bottom corner of LCU                       
3288      {
3289        uiAbsPartAddr = 0;
3290        uiLCUIdx = -1 ; 
3291      }
3292    }
3293   
3294   
3295    iRefIdx = 0;
3296    Bool bExistMV = false;
3297    UInt uiPartIdxCenter;
3298    UInt uiCurLCUIdx = getAddr();
3299    Int dir = 0;
3300    UInt uiArrayAddr = iCount;
3301    xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );
3302    bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_0, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx );
3303    if( bExistMV == false )
3304    {
3305      bExistMV = xGetColMVP( REF_PIC_LIST_0, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
3306    }
3307    if( bExistMV )
3308    {
3309      dir |= 1;
3310      pcMvFieldNeighbours[ 2 * uiArrayAddr ].setMvField( cColMv, iRefIdx );
3311    }
3312
3313    if ( getSlice()->isInterB() )
3314    {
3315#if H_3D_TMVP
3316      iRefIdx = 0;
3317#endif
3318      bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_1, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx);
3319      if( bExistMV == false )
3320      {
3321        bExistMV = xGetColMVP( REF_PIC_LIST_1, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
3322      }
3323      if( bExistMV )
3324      {
3325        dir |= 2;
3326        pcMvFieldNeighbours[ 2 * uiArrayAddr + 1 ].setMvField( cColMv, iRefIdx );
3327      }
3328    }
3329   
3330    if (dir != 0)
3331    {
3332      puhInterDirNeighbours[uiArrayAddr] = dir;
3333      abCandIsInter[uiArrayAddr] = true;
3334#if H_3D_NBDV
3335      pcMvFieldNeighbours[iCount<<1    ].getMv().setIDVFlag (false);
3336      pcMvFieldNeighbours[(iCount<<1)+1].getMv().setIDVFlag (false);
3337#endif
3338      if ( mrgCandIdx == iCount )
3339      {
3340        return;
3341      }
3342      iCount++;
3343    }
3344  }
3345  // early termination
3346  if (iCount == getSlice()->getMaxNumMergeCand()) 
3347  {
3348    return;
3349  }
3350  UInt uiArrayAddr = iCount;
3351  UInt uiCutoff = uiArrayAddr;
3352   
3353  if ( getSlice()->isInterB())
3354  {
3355#if H_3D_IV_MERGE
3356    UInt uiPriorityList0[20] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3,    0, 4, 1, 4, 2, 4, 3, 4 };
3357    UInt uiPriorityList1[20] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2,    4, 0, 4, 1, 4, 2, 4, 3 };
3358#else
3359    UInt uiPriorityList0[12] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3};
3360    UInt uiPriorityList1[12] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2};
3361#endif
3362
3363    for (Int idx=0; idx<uiCutoff*(uiCutoff-1) && uiArrayAddr!= getSlice()->getMaxNumMergeCand(); idx++)
3364    {
3365      Int i = uiPriorityList0[idx]; Int j = uiPriorityList1[idx];
3366#if H_3D_VSP
3367      Bool bValid = true;
3368      if ( vspFlag[i] == 1 || vspFlag[j] == 1 )
3369        bValid = false;
3370      if( !m_pcSlice->getVPS()->getViewSynthesisPredFlag( m_pcSlice->getLayerIdInVps() ) )
3371        assert(bValid == true);
3372#endif
3373#if H_3D_VSP
3374      if (abCandIsInter[i] && abCandIsInter[j] && (puhInterDirNeighbours[i]&0x1) && (puhInterDirNeighbours[j]&0x2) && bValid)
3375#else
3376      if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
3377#endif
3378      {
3379        abCandIsInter[uiArrayAddr] = true;
3380        puhInterDirNeighbours[uiArrayAddr] = 3;
3381
3382        // get Mv from cand[i] and cand[j]
3383        pcMvFieldNeighbours[uiArrayAddr << 1].setMvField(pcMvFieldNeighbours[i<<1].getMv(), pcMvFieldNeighbours[i<<1].getRefIdx());
3384        pcMvFieldNeighbours[( uiArrayAddr << 1 ) + 1].setMvField(pcMvFieldNeighbours[(j<<1)+1].getMv(), pcMvFieldNeighbours[(j<<1)+1].getRefIdx());
3385
3386        Int iRefPOCL0 = m_pcSlice->getRefPOC( REF_PIC_LIST_0, pcMvFieldNeighbours[(uiArrayAddr<<1)].getRefIdx() );
3387        Int iRefPOCL1 = m_pcSlice->getRefPOC( REF_PIC_LIST_1, pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getRefIdx() );
3388        if (iRefPOCL0 == iRefPOCL1 && pcMvFieldNeighbours[(uiArrayAddr<<1)].getMv() == pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getMv())
3389        {
3390          abCandIsInter[uiArrayAddr] = false;
3391        }
3392        else
3393        {
3394          uiArrayAddr++;
3395        }
3396      }
3397    }
3398  }
3399  // early termination
3400  if (uiArrayAddr == getSlice()->getMaxNumMergeCand()) 
3401  {
3402    return;
3403  }
3404  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);
3405  Int r = 0;
3406  Int refcnt = 0;
3407  while (uiArrayAddr < getSlice()->getMaxNumMergeCand())
3408  {
3409    abCandIsInter[uiArrayAddr] = true;
3410    puhInterDirNeighbours[uiArrayAddr] = 1;
3411    pcMvFieldNeighbours[uiArrayAddr << 1].setMvField( TComMv(0, 0), r);
3412
3413    if ( getSlice()->isInterB() )
3414    {
3415      puhInterDirNeighbours[uiArrayAddr] = 3;
3416      pcMvFieldNeighbours[(uiArrayAddr << 1) + 1].setMvField(TComMv(0, 0), r);
3417    }
3418    uiArrayAddr++;
3419    if ( refcnt == iNumRefIdx - 1 )
3420    {
3421      r = 0;
3422    }
3423    else
3424    {
3425      ++r;
3426      ++refcnt;
3427    }
3428  }
3429
3430  numValidMergeCand = uiArrayAddr;
3431}
3432
3433/** Check whether the current PU and a spatial neighboring PU are in a same ME region.
3434 * \param xN, xN   location of the upper-left corner pixel of a neighboring PU
3435 * \param xP, yP   location of the upper-left corner pixel of the current PU
3436 * \returns Bool
3437 */
3438Bool TComDataCU::isDiffMER(Int xN, Int yN, Int xP, Int yP)
3439{
3440
3441  UInt plevel = this->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() + 2;
3442  if ((xN>>plevel)!= (xP>>plevel))
3443  {
3444    return true;
3445  }
3446  if ((yN>>plevel)!= (yP>>plevel))
3447  {
3448    return true;
3449  }
3450  return false;
3451}
3452/** calculate the location of upper-left corner pixel and size of the current PU.
3453 * \param partIdx  PU index within a CU
3454 * \param xP, yP   location of the upper-left corner pixel of the current PU
3455 * \param PSW, nPSH    size of the curren PU
3456 * \returns Void
3457 */
3458Void TComDataCU::getPartPosition( UInt partIdx, Int& xP, Int& yP, Int& nPSW, Int& nPSH)
3459{
3460  UInt col = m_uiCUPelX;
3461  UInt row = m_uiCUPelY;
3462
3463  switch ( m_pePartSize[0] )
3464  {
3465  case SIZE_2NxN:
3466    nPSW = getWidth(0);     
3467    nPSH = getHeight(0) >> 1; 
3468    xP   = col;
3469    yP   = (partIdx ==0)? row: row + nPSH;
3470    break;
3471  case SIZE_Nx2N:
3472    nPSW = getWidth(0) >> 1; 
3473    nPSH = getHeight(0);     
3474    xP   = (partIdx ==0)? col: col + nPSW;
3475    yP   = row;
3476    break;
3477  case SIZE_NxN:
3478    nPSW = getWidth(0) >> 1; 
3479    nPSH = getHeight(0) >> 1; 
3480    xP   = col + (partIdx&0x1)*nPSW;
3481    yP   = row + (partIdx>>1)*nPSH;
3482    break;
3483  case SIZE_2NxnU:
3484    nPSW = getWidth(0);
3485    nPSH = ( partIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
3486    xP   = col;
3487    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
3488
3489    break;
3490  case SIZE_2NxnD:
3491    nPSW = getWidth(0);
3492    nPSH = ( partIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
3493    xP   = col;
3494    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
3495    break;
3496  case SIZE_nLx2N:
3497    nPSW = ( partIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
3498    nPSH = getHeight(0);
3499    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
3500    yP   = row;
3501    break;
3502  case SIZE_nRx2N:
3503    nPSW = ( partIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
3504    nPSH = getHeight(0);
3505    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
3506    yP   = row;
3507    break;
3508  default:
3509    assert ( m_pePartSize[0] == SIZE_2Nx2N );
3510    nPSW = getWidth(0);     
3511    nPSH = getHeight(0);     
3512    xP   = col ;
3513    yP   = row ;
3514
3515    break;
3516  }
3517}
3518
3519/** Constructs a list of candidates for AMVP
3520 * \param uiPartIdx
3521 * \param uiPartAddr
3522 * \param eRefPicList
3523 * \param iRefIdx
3524 * \param pInfo
3525 */
3526Void TComDataCU::fillMvpCand ( UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, AMVPInfo* pInfo )
3527{
3528  TComMv cMvPred;
3529  Bool bAddedSmvp = false;
3530
3531  pInfo->iN = 0; 
3532  if (iRefIdx < 0)
3533  {
3534    return;
3535  }
3536 
3537  //-- Get Spatial MV
3538  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
3539  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
3540  Bool bAdded = false;
3541 
3542  deriveLeftRightTopIdx( uiPartIdx, uiPartIdxLT, uiPartIdxRT );
3543  deriveLeftBottomIdx( uiPartIdx, uiPartIdxLB );
3544 
3545  TComDataCU* tmpCU = NULL;
3546  UInt idx;
3547  tmpCU = getPUBelowLeft(idx, uiPartIdxLB);
3548  bAddedSmvp = (tmpCU != NULL) && (tmpCU->getPredictionMode(idx) != MODE_INTRA);
3549
3550  if (!bAddedSmvp)
3551  {
3552    tmpCU = getPULeft(idx, uiPartIdxLB);
3553    bAddedSmvp = (tmpCU != NULL) && (tmpCU->getPredictionMode(idx) != MODE_INTRA);
3554  }
3555
3556  // Left predictor search
3557  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
3558  if (!bAdded) 
3559  {
3560    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
3561  }
3562 
3563  if(!bAdded)
3564  {
3565    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
3566    if (!bAdded) 
3567    {
3568      bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
3569    }
3570  }
3571  // Above predictor search
3572  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
3573
3574  if (!bAdded) 
3575  {
3576    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
3577  }
3578
3579  if(!bAdded)
3580  {
3581    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
3582  }
3583  bAdded = bAddedSmvp;
3584  if (pInfo->iN==2) bAdded = true;
3585
3586  if(!bAdded)
3587  {
3588    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
3589    if (!bAdded) 
3590    {
3591      bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
3592    }
3593
3594    if(!bAdded)
3595    {
3596      bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
3597    }
3598  }
3599 
3600  if ( pInfo->iN == 2 )
3601  {
3602    if ( pInfo->m_acMvCand[ 0 ] == pInfo->m_acMvCand[ 1 ] )
3603    {
3604      pInfo->iN = 1;
3605    }
3606  }
3607
3608  if ( getSlice()->getEnableTMVPFlag() )
3609  {
3610    // Get Temporal Motion Predictor
3611    Int iRefIdx_Col = iRefIdx;
3612    TComMv cColMv;
3613    UInt uiPartIdxRB;
3614    UInt uiAbsPartIdx; 
3615    UInt uiAbsPartAddr;
3616    Int uiLCUIdx = getAddr();
3617
3618    deriveRightBottomIdx( uiPartIdx, uiPartIdxRB );
3619    uiAbsPartAddr = m_uiAbsIdxInLCU + uiPartAddr;
3620
3621    //----  co-located RightBottom Temporal Predictor (H) ---//
3622    uiAbsPartIdx = g_auiZscanToRaster[uiPartIdxRB];
3623    if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdx] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )  // image boundary check
3624    {
3625      uiLCUIdx = -1;
3626    }
3627    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdx] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
3628    {
3629      uiLCUIdx = -1;
3630    }
3631    else
3632    {
3633      if ( ( uiAbsPartIdx % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
3634        ( uiAbsPartIdx / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
3635      {
3636        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + uiNumPartInCUWidth + 1 ];
3637        uiLCUIdx = getAddr();
3638      }
3639      else if ( uiAbsPartIdx % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
3640      {
3641        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdx + uiNumPartInCUWidth + 1) % m_pcPic->getNumPartInCU() ];
3642        uiLCUIdx      = -1 ; 
3643      }
3644      else if ( uiAbsPartIdx / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
3645      {
3646        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + 1 ];
3647        uiLCUIdx = getAddr() + 1;
3648      }
3649      else //is the right bottom corner of LCU                       
3650      {
3651        uiAbsPartAddr = 0;
3652        uiLCUIdx      = -1 ; 
3653      }
3654    }
3655    if ( uiLCUIdx >= 0 && xGetColMVP( eRefPicList, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx_Col
3656#if H_3D_TMVP
3657         , 0
3658#endif
3659    ) )
3660    {
3661      pInfo->m_acMvCand[pInfo->iN++] = cColMv;
3662    }
3663    else 
3664    {
3665      UInt uiPartIdxCenter;
3666      UInt uiCurLCUIdx = getAddr();
3667      xDeriveCenterIdx( uiPartIdx, uiPartIdxCenter );
3668      if (xGetColMVP( eRefPicList, uiCurLCUIdx, uiPartIdxCenter,  cColMv, iRefIdx_Col
3669#if H_3D_TMVP
3670         , 0
3671#endif
3672      ))
3673      {
3674        pInfo->m_acMvCand[pInfo->iN++] = cColMv;
3675      }
3676    }
3677    //----  co-located RightBottom Temporal Predictor  ---//
3678  }
3679
3680  if (pInfo->iN > AMVP_MAX_NUM_CANDS)
3681  {
3682    pInfo->iN = AMVP_MAX_NUM_CANDS;
3683  }
3684  while (pInfo->iN < AMVP_MAX_NUM_CANDS)
3685  {
3686      pInfo->m_acMvCand[pInfo->iN].set(0,0);
3687      pInfo->iN++;
3688  }
3689  return ;
3690}
3691
3692Bool TComDataCU::isBipredRestriction(UInt puIdx)
3693{
3694  Int width = 0;
3695  Int height = 0;
3696  UInt partAddr;
3697
3698  getPartIndexAndSize( puIdx, partAddr, width, height );
3699  if ( getWidth(0) == 8 && (width < 8 || height < 8) )
3700  {
3701    return true;
3702  }
3703  return false;
3704}
3705
3706Void TComDataCU::clipMv    (TComMv&  rcMv)
3707{
3708  Int  iMvShift = 2;
3709#if H_3D_IC
3710  if( getSlice()->getIsDepth() )
3711    iMvShift = 0;
3712#endif
3713  Int iOffset = 8;
3714  Int iHorMax = ( m_pcSlice->getSPS()->getPicWidthInLumaSamples() + iOffset - m_uiCUPelX - 1 ) << iMvShift;
3715  Int iHorMin = (       -(Int)g_uiMaxCUWidth - iOffset - (Int)m_uiCUPelX + 1 ) << iMvShift;
3716 
3717  Int iVerMax = ( m_pcSlice->getSPS()->getPicHeightInLumaSamples() + iOffset - m_uiCUPelY - 1 ) << iMvShift;
3718  Int iVerMin = (       -(Int)g_uiMaxCUHeight - iOffset - (Int)m_uiCUPelY + 1 ) << iMvShift;
3719 
3720  rcMv.setHor( min (iHorMax, max (iHorMin, rcMv.getHor())) );
3721  rcMv.setVer( min (iVerMax, max (iVerMin, rcMv.getVer())) );
3722}
3723
3724UInt TComDataCU::getIntraSizeIdx(UInt uiAbsPartIdx)
3725{
3726  UInt uiShift = ( (m_puhTrIdx[uiAbsPartIdx]==0) && (m_pePartSize[uiAbsPartIdx]==SIZE_NxN) ) ? m_puhTrIdx[uiAbsPartIdx]+1 : m_puhTrIdx[uiAbsPartIdx];
3727  uiShift = ( m_pePartSize[uiAbsPartIdx]==SIZE_NxN ? 1 : 0 );
3728 
3729  UChar uiWidth = m_puhWidth[uiAbsPartIdx]>>uiShift;
3730  UInt  uiCnt = 0;
3731  while( uiWidth )
3732  {
3733    uiCnt++;
3734    uiWidth>>=1;
3735  }
3736  uiCnt-=2;
3737  return uiCnt > 6 ? 6 : uiCnt;
3738}
3739
3740Void TComDataCU::clearCbf( UInt uiIdx, TextType eType, UInt uiNumParts )
3741{
3742  ::memset( &m_puhCbf[g_aucConvertTxtTypeToIdx[eType]][uiIdx], 0, sizeof(UChar)*uiNumParts);
3743}
3744
3745/** Set a I_PCM flag for all sub-partitions of a partition.
3746 * \param bIpcmFlag I_PCM flag
3747 * \param uiAbsPartIdx patition index
3748 * \param uiDepth CU depth
3749 * \returns Void
3750 */
3751Void TComDataCU::setIPCMFlagSubParts  (Bool bIpcmFlag, UInt uiAbsPartIdx, UInt uiDepth)
3752{
3753  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
3754
3755  memset(m_pbIPCMFlag + uiAbsPartIdx, bIpcmFlag, sizeof(Bool)*uiCurrPartNumb );
3756}
3757
3758/** Test whether the current block is skipped
3759 * \param uiPartIdx Block index
3760 * \returns Flag indicating whether the block is skipped
3761 */
3762Bool TComDataCU::isSkipped( UInt uiPartIdx )
3763{
3764  return ( getSkipFlag( uiPartIdx ) );
3765}
3766
3767// ====================================================================================================================
3768// Protected member functions
3769// ====================================================================================================================
3770
3771Bool TComDataCU::xAddMVPCand( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
3772{
3773  TComDataCU* pcTmpCU = NULL;
3774  UInt uiIdx;
3775  switch( eDir )
3776  {
3777    case MD_LEFT:
3778    {
3779      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
3780      break;
3781    }
3782    case MD_ABOVE:
3783    {
3784      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx );
3785      break;
3786    }
3787    case MD_ABOVE_RIGHT:
3788    {
3789      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
3790      break;
3791    }
3792    case MD_BELOW_LEFT:
3793    {
3794      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
3795      break;
3796    }
3797    case MD_ABOVE_LEFT:
3798    {
3799      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
3800      break;
3801    }
3802    default:
3803    {
3804      break;
3805    }
3806  }
3807
3808  if ( pcTmpCU == NULL )
3809  {
3810    return false;
3811  }
3812 
3813#if L0363_MVP_POC
3814  if ( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0 && m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC() == pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ))
3815#else
3816  if ( m_pcSlice->isEqualRef(eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx), iRefIdx) )
3817#endif
3818  {
3819    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
3820   
3821    pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
3822    return true;
3823  }
3824
3825  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
3826  if(       eRefPicList == REF_PIC_LIST_0 )
3827  {
3828    eRefPicList2nd = REF_PIC_LIST_1;
3829  }
3830  else if ( eRefPicList == REF_PIC_LIST_1)
3831  {
3832    eRefPicList2nd = REF_PIC_LIST_0;
3833  }
3834
3835
3836  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
3837  Int iNeibRefPOC;
3838
3839
3840  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0 )
3841  {
3842    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
3843    if( iNeibRefPOC == iCurrRefPOC ) // Same Reference Frame But Diff List//
3844    {
3845      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
3846      pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
3847      return true;
3848    }
3849  }
3850  return false;
3851}
3852
3853/**
3854 * \param pInfo
3855 * \param eRefPicList
3856 * \param iRefIdx
3857 * \param uiPartUnitIdx
3858 * \param eDir
3859 * \returns Bool
3860 */
3861Bool TComDataCU::xAddMVPCandOrder( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
3862{
3863  TComDataCU* pcTmpCU = NULL;
3864  UInt uiIdx;
3865  switch( eDir )
3866  {
3867  case MD_LEFT:
3868    {
3869      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
3870      break;
3871    }
3872  case MD_ABOVE:
3873    {
3874      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx);
3875      break;
3876    }
3877  case MD_ABOVE_RIGHT:
3878    {
3879      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
3880      break;
3881    }
3882  case MD_BELOW_LEFT:
3883    {
3884      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
3885      break;
3886    }
3887  case MD_ABOVE_LEFT:
3888    {
3889      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
3890      break;
3891    }
3892  default:
3893    {
3894      break;
3895    }
3896  }
3897
3898  if ( pcTmpCU == NULL ) 
3899  {
3900    return false;
3901  }
3902 
3903  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
3904  if(       eRefPicList == REF_PIC_LIST_0 )
3905  {
3906    eRefPicList2nd = REF_PIC_LIST_1;
3907  }
3908  else if ( eRefPicList == REF_PIC_LIST_1)
3909  {
3910    eRefPicList2nd = REF_PIC_LIST_0;
3911  }
3912
3913  Int iCurrPOC = m_pcSlice->getPOC();
3914  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
3915  Int iNeibPOC = iCurrPOC;
3916  Int iNeibRefPOC;
3917
3918  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getIsLongTerm();
3919  Bool bIsNeibRefLongTerm = false;
3920  //---------------  V1 (END) ------------------//
3921  if( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0)
3922  {
3923    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) );
3924    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
3925    TComMv rcMv;
3926
3927    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) )->getIsLongTerm();
3928    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm ) 
3929    {
3930    if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
3931    {
3932      rcMv = cMvPred;
3933    }
3934    else
3935    {
3936      Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
3937      if ( iScale == 4096 )
3938      {
3939        rcMv = cMvPred;
3940      }
3941      else
3942      {
3943        rcMv = cMvPred.scaleMv( iScale );
3944      }
3945    }
3946    pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
3947    return true;
3948    }
3949  }
3950  //---------------------- V2(END) --------------------//
3951  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0)
3952  {
3953    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
3954    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
3955    TComMv rcMv;
3956
3957    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) )->getIsLongTerm();
3958    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm ) 
3959    {
3960    if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
3961    {
3962      rcMv = cMvPred;
3963    }
3964    else
3965    {
3966      Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
3967      if ( iScale == 4096 )
3968      {
3969        rcMv = cMvPred;
3970      }
3971      else
3972      {
3973        rcMv = cMvPred.scaleMv( iScale );
3974      }
3975    }
3976    pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
3977    return true;
3978    }
3979  }
3980  //---------------------- V3(END) --------------------//
3981  return false;
3982}
3983
3984/**
3985 * \param eRefPicList
3986 * \param uiCUAddr
3987 * \param uiPartUnitIdx
3988 * \param riRefIdx
3989 * \returns Bool
3990 */
3991Bool TComDataCU::xGetColMVP( RefPicList eRefPicList, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv, Int& riRefIdx
3992#if H_3D_TMVP
3993  , Bool bMRG
3994#endif
3995  )
3996{
3997  UInt uiAbsPartAddr = uiPartUnitIdx;
3998
3999  RefPicList  eColRefPicList;
4000  Int iColPOC, iColRefPOC, iCurrPOC, iCurrRefPOC, iScale;
4001  TComMv cColMv;
4002
4003  // use coldir.
4004  TComPic *pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());
4005  TComDataCU *pColCU = pColPic->getCU( uiCUAddr );
4006  if(pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==SIZE_NONE)
4007  {
4008    return false;
4009  }
4010  iCurrPOC = m_pcSlice->getPOC();   
4011  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
4012  iColPOC = pColCU->getSlice()->getPOC(); 
4013
4014  if (pColCU->isIntra(uiAbsPartAddr))
4015  {
4016    return false;
4017  }
4018  eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());
4019
4020  Int iColRefIdx = pColCU->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
4021
4022  if (iColRefIdx < 0 )
4023  {
4024    eColRefPicList = RefPicList(1 - eColRefPicList);
4025    iColRefIdx = pColCU->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
4026
4027    if (iColRefIdx < 0 )
4028    {
4029      return false;
4030    }
4031  }
4032
4033  // Scale the vector.
4034  iColRefPOC = pColCU->getSlice()->getRefPOC(eColRefPicList, iColRefIdx);
4035  cColMv = pColCU->getCUMvField(eColRefPicList)->getMv(uiAbsPartAddr);
4036
4037  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
4038  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();
4039  Bool bIsColRefLongTerm = pColCU->getSlice()->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
4040
4041  if ( bIsCurrRefLongTerm != bIsColRefLongTerm ) 
4042  {
4043#if H_3D_TMVP
4044    Int iAlterRefIdx  = m_pcSlice->getAlterRefIdx(eRefPicList);
4045    if(bMRG && iAlterRefIdx > 0)
4046    {
4047      riRefIdx = iAlterRefIdx;
4048      bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();
4049      iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
4050      assert(bIsCurrRefLongTerm == bIsColRefLongTerm);
4051    }
4052    else
4053    {
4054#endif
4055      return false;
4056#if H_3D_TMVP
4057    }
4058#endif
4059  }
4060
4061  if ( bIsCurrRefLongTerm || bIsColRefLongTerm )
4062  {
4063#if H_3D_TMVP
4064     Int iCurrViewId    = m_pcSlice->getViewIndex (); 
4065     Int iCurrRefViewId = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getViewIndex (); 
4066     Int iColViewId     = pColCU->getSlice()->getViewIndex(); 
4067     Int iColRefViewId  = pColCU->getSlice()->getRefPic( eColRefPicList, pColCU->getCUMvField(eColRefPicList)->getRefIdx(uiAbsPartAddr))->getViewIndex(); 
4068     iScale = xGetDistScaleFactor( iCurrViewId, iCurrRefViewId, iColViewId, iColRefViewId );
4069     if ( iScale != 4096 )
4070     {
4071        rcMv = cColMv.scaleMv( iScale );
4072     }
4073     else
4074     {
4075#endif
4076       rcMv = cColMv;
4077#if H_3D_TMVP
4078    }
4079#endif
4080  }
4081  else
4082  {
4083    iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iColPOC, iColRefPOC);
4084    if ( iScale == 4096 )
4085    {
4086      rcMv = cColMv;
4087    }
4088    else
4089    {
4090      rcMv = cColMv.scaleMv( iScale );
4091    }
4092  }
4093  return true;
4094}
4095
4096UInt TComDataCU::xGetMvdBits(TComMv cMvd)
4097{
4098  return ( xGetComponentBits(cMvd.getHor()) + xGetComponentBits(cMvd.getVer()) );
4099}
4100
4101UInt TComDataCU::xGetComponentBits(Int iVal)
4102{
4103  UInt uiLength = 1;
4104  UInt uiTemp   = ( iVal <= 0) ? (-iVal<<1)+1: (iVal<<1);
4105 
4106  assert ( uiTemp );
4107 
4108  while ( 1 != uiTemp )
4109  {
4110    uiTemp >>= 1;
4111    uiLength += 2;
4112  }
4113 
4114  return uiLength;
4115}
4116
4117
4118Int TComDataCU::xGetDistScaleFactor(Int iCurrPOC, Int iCurrRefPOC, Int iColPOC, Int iColRefPOC)
4119{
4120  Int iDiffPocD = iColPOC - iColRefPOC;
4121  Int iDiffPocB = iCurrPOC - iCurrRefPOC;
4122 
4123  if( iDiffPocD == iDiffPocB )
4124  {
4125    return 4096;
4126  }
4127  else
4128  {
4129    Int iTDB      = Clip3( -128, 127, iDiffPocB );
4130    Int iTDD      = Clip3( -128, 127, iDiffPocD );
4131    Int iX        = (0x4000 + abs(iTDD/2)) / iTDD;
4132    Int iScale    = Clip3( -4096, 4095, (iTDB * iX + 32) >> 6 );
4133    return iScale;
4134  }
4135}
4136
4137/**
4138 * \param eCUMode
4139 * \param uiPartIdx
4140 * \param ruiPartIdxCenter
4141 * \returns Void
4142 */
4143Void TComDataCU::xDeriveCenterIdx( UInt uiPartIdx, UInt& ruiPartIdxCenter )
4144{
4145  UInt uiPartAddr;
4146  Int  iPartWidth;
4147  Int  iPartHeight;
4148  getPartIndexAndSize( uiPartIdx, uiPartAddr, iPartWidth, iPartHeight);
4149 
4150  ruiPartIdxCenter = m_uiAbsIdxInLCU+uiPartAddr; // partition origin.
4151  ruiPartIdxCenter = g_auiRasterToZscan[ g_auiZscanToRaster[ ruiPartIdxCenter ]
4152                                        + ( iPartHeight/m_pcPic->getMinCUHeight()  )/2*m_pcPic->getNumPartInWidth()
4153                                        + ( iPartWidth/m_pcPic->getMinCUWidth()  )/2];
4154}
4155
4156Void TComDataCU::compressMV()
4157{
4158  Int scaleFactor = 4 * AMVP_DECIMATION_FACTOR / m_unitSize;
4159  if (scaleFactor > 0)
4160  {
4161    m_acCUMvField[0].compress(m_pePredMode, scaleFactor);
4162    m_acCUMvField[1].compress(m_pePredMode, scaleFactor);   
4163  }
4164}
4165
4166UInt TComDataCU::getCoefScanIdx(UInt uiAbsPartIdx, UInt uiWidth, Bool bIsLuma, Bool bIsIntra)
4167{
4168  UInt uiCTXIdx;
4169  UInt uiScanIdx;
4170  UInt uiDirMode;
4171
4172  if ( !bIsIntra ) 
4173  {
4174    uiScanIdx = SCAN_DIAG;
4175    return uiScanIdx;
4176  }
4177
4178  switch(uiWidth)
4179  {
4180    case  2: uiCTXIdx = 6; break;
4181    case  4: uiCTXIdx = 5; break;
4182    case  8: uiCTXIdx = 4; break;
4183    case 16: uiCTXIdx = 3; break;
4184    case 32: uiCTXIdx = 2; break;
4185    case 64: uiCTXIdx = 1; break;
4186    default: uiCTXIdx = 0; break;
4187  }
4188
4189  if ( bIsLuma )
4190  {
4191    uiDirMode = getLumaIntraDir(uiAbsPartIdx);
4192    uiScanIdx = SCAN_DIAG;
4193    if (uiCTXIdx >3 && uiCTXIdx < 6) //if multiple scans supported for transform size
4194    {
4195      uiScanIdx = abs((Int) uiDirMode - VER_IDX) < 5 ? SCAN_HOR : (abs((Int)uiDirMode - HOR_IDX) < 5 ? SCAN_VER : SCAN_DIAG);
4196    }
4197  }
4198  else
4199  {
4200    uiDirMode = getChromaIntraDir(uiAbsPartIdx);
4201    if( uiDirMode == DM_CHROMA_IDX )
4202    {
4203      // get number of partitions in current CU
4204      UInt depth = getDepth(uiAbsPartIdx);
4205      UInt numParts = getPic()->getNumPartInCU() >> (2 * depth);
4206     
4207      // get luma mode from upper-left corner of current CU
4208      uiDirMode = getLumaIntraDir((uiAbsPartIdx/numParts)*numParts);
4209    }
4210    uiScanIdx = SCAN_DIAG;
4211    if (uiCTXIdx >4 && uiCTXIdx < 7) //if multiple scans supported for transform size
4212    {
4213      uiScanIdx = abs((Int) uiDirMode - VER_IDX) < 5 ? SCAN_HOR : (abs((Int)uiDirMode - HOR_IDX) < 5 ? SCAN_VER : SCAN_DIAG);
4214    }
4215  }
4216
4217  return uiScanIdx;
4218}
4219
4220UInt TComDataCU::getSCUAddr()
4221{ 
4222  return getPic()->getPicSym()->getInverseCUOrderMap(m_uiCUAddr)*(1<<(m_pcSlice->getSPS()->getMaxCUDepth()<<1))+m_uiAbsIdxInLCU; 
4223}
4224
4225/** Set neighboring blocks availabilities for non-deblocked filtering
4226 * \param numLCUInPicWidth number of LCUs in picture width
4227 * \param numLCUInPicHeight number of LCUs in picture height
4228 * \param numSUInLCUWidth number of SUs in LCU width
4229 * \param numSUInLCUHeight number of SUs in LCU height
4230 * \param picWidth picture width
4231 * \param picHeight picture height
4232 * \param bIndependentSliceBoundaryEnabled true for independent slice boundary enabled
4233 * \param bTopTileBoundary true means that top boundary coincides tile boundary
4234 * \param bDownTileBoundary true means that bottom boundary coincides tile boundary
4235 * \param bLeftTileBoundary true means that left boundary coincides tile boundary
4236 * \param bRightTileBoundary true means that right boundary coincides tile boundary
4237 * \param bIndependentTileBoundaryEnabled true for independent tile boundary enabled
4238 */
4239Void TComDataCU::setNDBFilterBlockBorderAvailability(UInt numLCUInPicWidth, UInt /*numLCUInPicHeight*/, UInt numSUInLCUWidth, UInt numSUInLCUHeight, UInt picWidth, UInt picHeight
4240                                                    ,std::vector<Bool>& LFCrossSliceBoundary
4241                                                    ,Bool bTopTileBoundary, Bool bDownTileBoundary, Bool bLeftTileBoundary, Bool bRightTileBoundary
4242                                                    ,Bool bIndependentTileBoundaryEnabled)
4243{
4244  UInt numSUInLCU = numSUInLCUWidth*numSUInLCUHeight;
4245  Int* pSliceIDMapLCU = m_piSliceSUMap;
4246  Bool onlyOneSliceInPic = ((Int)LFCrossSliceBoundary.size() == 1);
4247  UInt uiLPelX, uiTPelY;
4248  UInt width, height;
4249  Bool bPicRBoundary, bPicBBoundary, bPicTBoundary, bPicLBoundary;
4250  Bool bLCURBoundary= false, bLCUBBoundary= false, bLCUTBoundary= false, bLCULBoundary= false;
4251  Bool* pbAvailBorder;
4252  Bool* pbAvail;
4253  UInt rTLSU, rBRSU, widthSU, heightSU;
4254  UInt zRefSU;
4255  Int* pRefID;
4256  Int* pRefMapLCU;
4257  UInt rTRefSU= 0, rBRefSU= 0, rLRefSU= 0, rRRefSU= 0;
4258  Int* pRRefMapLCU= NULL;
4259  Int* pLRefMapLCU= NULL;
4260  Int* pTRefMapLCU= NULL;
4261  Int* pBRefMapLCU= NULL;
4262  Int  sliceID;
4263  UInt numSGU = (UInt)m_vNDFBlock.size();
4264
4265  for(Int i=0; i< numSGU; i++)
4266  {
4267    NDBFBlockInfo& rSGU = m_vNDFBlock[i];
4268
4269    sliceID = rSGU.sliceID;
4270    uiLPelX = rSGU.posX;
4271    uiTPelY = rSGU.posY;
4272    width   = rSGU.width;
4273    height  = rSGU.height;
4274    rTLSU     = g_auiZscanToRaster[ rSGU.startSU ];
4275    rBRSU     = g_auiZscanToRaster[ rSGU.endSU   ];
4276    widthSU   = rSGU.widthSU;
4277    heightSU  = rSGU.heightSU;
4278
4279    pbAvailBorder = rSGU.isBorderAvailable;
4280
4281    bPicTBoundary= (uiTPelY == 0                       )?(true):(false);
4282    bPicLBoundary= (uiLPelX == 0                       )?(true):(false);
4283    bPicRBoundary= (!(uiLPelX+ width < picWidth )  )?(true):(false);
4284    bPicBBoundary= (!(uiTPelY + height < picHeight))?(true):(false);
4285
4286    bLCULBoundary = (rTLSU % numSUInLCUWidth == 0)?(true):(false);
4287    bLCURBoundary = ( (rTLSU+ widthSU) % numSUInLCUWidth == 0)?(true):(false);
4288    bLCUTBoundary = ( (UInt)(rTLSU / numSUInLCUWidth)== 0)?(true):(false);
4289    bLCUBBoundary = ( (UInt)(rBRSU / numSUInLCUWidth) == (numSUInLCUHeight-1) )?(true):(false);
4290
4291    //       SGU_L
4292    pbAvail = &(pbAvailBorder[SGU_L]);
4293    if(bPicLBoundary)
4294    {
4295      *pbAvail = false;
4296    }
4297    else if (onlyOneSliceInPic)
4298    {
4299      *pbAvail = true;
4300    }
4301    else
4302    {
4303      //      bLCULBoundary = (rTLSU % uiNumSUInLCUWidth == 0)?(true):(false);
4304      if(bLCULBoundary)
4305      {
4306        rLRefSU     = rTLSU + numSUInLCUWidth -1;
4307        zRefSU      = g_auiRasterToZscan[rLRefSU];
4308        pRefMapLCU = pLRefMapLCU= (pSliceIDMapLCU - numSUInLCU);
4309      }
4310      else
4311      {
4312        zRefSU   = g_auiRasterToZscan[rTLSU - 1];
4313        pRefMapLCU  = pSliceIDMapLCU;
4314      }
4315      pRefID = pRefMapLCU + zRefSU;
4316      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4317    }
4318
4319    //       SGU_R
4320    pbAvail = &(pbAvailBorder[SGU_R]);
4321    if(bPicRBoundary)
4322    {
4323      *pbAvail = false;
4324    }
4325    else if (onlyOneSliceInPic)
4326    {
4327      *pbAvail = true;
4328    }
4329    else
4330    {
4331      //       bLCURBoundary = ( (rTLSU+ uiWidthSU) % uiNumSUInLCUWidth == 0)?(true):(false);
4332      if(bLCURBoundary)
4333      {
4334        rRRefSU      = rTLSU + widthSU - numSUInLCUWidth;
4335        zRefSU       = g_auiRasterToZscan[rRRefSU];
4336        pRefMapLCU  = pRRefMapLCU= (pSliceIDMapLCU + numSUInLCU);
4337      }
4338      else
4339      {
4340        zRefSU       = g_auiRasterToZscan[rTLSU + widthSU];
4341        pRefMapLCU  = pSliceIDMapLCU;
4342      }
4343      pRefID = pRefMapLCU + zRefSU;
4344      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4345    }
4346
4347    //       SGU_T
4348    pbAvail = &(pbAvailBorder[SGU_T]);
4349    if(bPicTBoundary)
4350    {
4351      *pbAvail = false;
4352    }
4353    else if (onlyOneSliceInPic)
4354    {
4355      *pbAvail = true;
4356    }
4357    else
4358    {
4359      //      bLCUTBoundary = ( (UInt)(rTLSU / uiNumSUInLCUWidth)== 0)?(true):(false);
4360      if(bLCUTBoundary)
4361      {
4362        rTRefSU      = numSUInLCU - (numSUInLCUWidth - rTLSU);
4363        zRefSU       = g_auiRasterToZscan[rTRefSU];
4364        pRefMapLCU  = pTRefMapLCU= (pSliceIDMapLCU - (numLCUInPicWidth*numSUInLCU));
4365      }
4366      else
4367      {
4368        zRefSU       = g_auiRasterToZscan[rTLSU - numSUInLCUWidth];
4369        pRefMapLCU  = pSliceIDMapLCU;
4370      }
4371      pRefID = pRefMapLCU + zRefSU;
4372      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4373    }
4374
4375    //       SGU_B
4376    pbAvail = &(pbAvailBorder[SGU_B]);
4377    if(bPicBBoundary)
4378    {
4379      *pbAvail = false;
4380    }
4381    else if (onlyOneSliceInPic)
4382    {
4383      *pbAvail = true;
4384    }
4385    else
4386    {
4387      //      bLCUBBoundary = ( (UInt)(rBRSU / uiNumSUInLCUWidth) == (uiNumSUInLCUHeight-1) )?(true):(false);
4388      if(bLCUBBoundary)
4389      {
4390        rBRefSU      = rTLSU % numSUInLCUWidth;
4391        zRefSU       = g_auiRasterToZscan[rBRefSU];
4392        pRefMapLCU  = pBRefMapLCU= (pSliceIDMapLCU + (numLCUInPicWidth*numSUInLCU));
4393      }
4394      else
4395      {
4396        zRefSU       = g_auiRasterToZscan[rTLSU + (heightSU*numSUInLCUWidth)];
4397        pRefMapLCU  = pSliceIDMapLCU;
4398      }
4399      pRefID = pRefMapLCU + zRefSU;
4400      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4401    }
4402
4403    //       SGU_TL
4404    pbAvail = &(pbAvailBorder[SGU_TL]);
4405    if(bPicTBoundary || bPicLBoundary)
4406    {
4407      *pbAvail = false;
4408    }
4409    else if (onlyOneSliceInPic)
4410    {
4411      *pbAvail = true;
4412    }
4413    else
4414    {
4415      if(bLCUTBoundary && bLCULBoundary)
4416      {
4417        zRefSU       = numSUInLCU -1;
4418        pRefMapLCU  = pSliceIDMapLCU - ( (numLCUInPicWidth+1)*numSUInLCU);
4419      }
4420      else if(bLCUTBoundary)
4421      {
4422        zRefSU       = g_auiRasterToZscan[ rTRefSU- 1];
4423        pRefMapLCU  = pTRefMapLCU;
4424      }
4425      else if(bLCULBoundary)
4426      {
4427        zRefSU       = g_auiRasterToZscan[ rLRefSU- numSUInLCUWidth ];
4428        pRefMapLCU  = pLRefMapLCU;
4429      }
4430      else //inside LCU
4431      {
4432        zRefSU       = g_auiRasterToZscan[ rTLSU - numSUInLCUWidth -1];
4433        pRefMapLCU  = pSliceIDMapLCU;
4434      }
4435      pRefID = pRefMapLCU + zRefSU;
4436      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4437    }
4438
4439    //       SGU_TR
4440    pbAvail = &(pbAvailBorder[SGU_TR]);
4441    if(bPicTBoundary || bPicRBoundary)
4442    {
4443      *pbAvail = false;
4444    }
4445    else if (onlyOneSliceInPic)
4446    {
4447      *pbAvail = true;
4448    }
4449    else
4450    {
4451      if(bLCUTBoundary && bLCURBoundary)
4452      {
4453        zRefSU      = g_auiRasterToZscan[numSUInLCU - numSUInLCUWidth];
4454        pRefMapLCU  = pSliceIDMapLCU - ( (numLCUInPicWidth-1)*numSUInLCU);       
4455      }
4456      else if(bLCUTBoundary)
4457      {
4458        zRefSU       = g_auiRasterToZscan[ rTRefSU+ widthSU];
4459        pRefMapLCU  = pTRefMapLCU;
4460      }
4461      else if(bLCURBoundary)
4462      {
4463        zRefSU       = g_auiRasterToZscan[ rRRefSU- numSUInLCUWidth ];
4464        pRefMapLCU  = pRRefMapLCU;
4465      }
4466      else //inside LCU
4467      {
4468        zRefSU       = g_auiRasterToZscan[ rTLSU - numSUInLCUWidth +widthSU];
4469        pRefMapLCU  = pSliceIDMapLCU;
4470      }
4471      pRefID = pRefMapLCU + zRefSU;
4472      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4473    }
4474
4475    //       SGU_BL
4476    pbAvail = &(pbAvailBorder[SGU_BL]);
4477    if(bPicBBoundary || bPicLBoundary)
4478    {
4479      *pbAvail = false;
4480    }
4481    else if (onlyOneSliceInPic)
4482    {
4483      *pbAvail = true;
4484    }
4485    else
4486    {
4487      if(bLCUBBoundary && bLCULBoundary)
4488      {
4489        zRefSU      = g_auiRasterToZscan[numSUInLCUWidth - 1];
4490        pRefMapLCU  = pSliceIDMapLCU + ( (numLCUInPicWidth-1)*numSUInLCU);       
4491      }
4492      else if(bLCUBBoundary)
4493      {
4494        zRefSU       = g_auiRasterToZscan[ rBRefSU - 1];
4495        pRefMapLCU  = pBRefMapLCU;
4496      }
4497      else if(bLCULBoundary)
4498      {
4499        zRefSU       = g_auiRasterToZscan[ rLRefSU+ heightSU*numSUInLCUWidth ];
4500        pRefMapLCU  = pLRefMapLCU;
4501      }
4502      else //inside LCU
4503      {
4504        zRefSU       = g_auiRasterToZscan[ rTLSU + heightSU*numSUInLCUWidth -1];
4505        pRefMapLCU  = pSliceIDMapLCU;
4506      }
4507      pRefID = pRefMapLCU + zRefSU;
4508      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4509    }
4510
4511    //       SGU_BR
4512    pbAvail = &(pbAvailBorder[SGU_BR]);
4513    if(bPicBBoundary || bPicRBoundary)
4514    {
4515      *pbAvail = false;
4516    }
4517    else if (onlyOneSliceInPic)
4518    {
4519      *pbAvail = true;
4520    }
4521    else
4522    {
4523      if(bLCUBBoundary && bLCURBoundary)
4524      {
4525        zRefSU = 0;
4526        pRefMapLCU = pSliceIDMapLCU+ ( (numLCUInPicWidth+1)*numSUInLCU);
4527      }
4528      else if(bLCUBBoundary)
4529      {
4530        zRefSU      = g_auiRasterToZscan[ rBRefSU + widthSU];
4531        pRefMapLCU = pBRefMapLCU;
4532      }
4533      else if(bLCURBoundary)
4534      {
4535        zRefSU      = g_auiRasterToZscan[ rRRefSU + (heightSU*numSUInLCUWidth)];
4536        pRefMapLCU = pRRefMapLCU;
4537      }
4538      else //inside LCU
4539      {
4540        zRefSU      = g_auiRasterToZscan[ rTLSU + (heightSU*numSUInLCUWidth)+ widthSU];
4541        pRefMapLCU = pSliceIDMapLCU;
4542      }
4543      pRefID = pRefMapLCU + zRefSU;
4544      *pbAvail = (*pRefID == sliceID)?(true):((*pRefID > sliceID)?(LFCrossSliceBoundary[*pRefID]):(LFCrossSliceBoundary[sliceID]));
4545    }
4546
4547    if(bIndependentTileBoundaryEnabled)
4548    {
4549      //left LCU boundary
4550      if(!bPicLBoundary && bLCULBoundary)
4551      {
4552        if(bLeftTileBoundary)
4553        {
4554          pbAvailBorder[SGU_L] = pbAvailBorder[SGU_TL] = pbAvailBorder[SGU_BL] = false;
4555        }
4556      }
4557      //right LCU boundary
4558      if(!bPicRBoundary && bLCURBoundary)
4559      {
4560        if(bRightTileBoundary)
4561        {
4562          pbAvailBorder[SGU_R] = pbAvailBorder[SGU_TR] = pbAvailBorder[SGU_BR] = false;
4563        }
4564      }
4565      //top LCU boundary
4566      if(!bPicTBoundary && bLCUTBoundary)
4567      {
4568        if(bTopTileBoundary)
4569        {
4570          pbAvailBorder[SGU_T] = pbAvailBorder[SGU_TL] = pbAvailBorder[SGU_TR] = false;
4571        }
4572      }
4573      //down LCU boundary
4574      if(!bPicBBoundary && bLCUBBoundary)
4575      {
4576        if(bDownTileBoundary)
4577        {
4578          pbAvailBorder[SGU_B] = pbAvailBorder[SGU_BL] = pbAvailBorder[SGU_BR] = false;
4579        }
4580      }
4581    }
4582    rSGU.allBordersAvailable = true;
4583    for(Int b=0; b< NUM_SGU_BORDER; b++)
4584    {
4585      if(pbAvailBorder[b] == false)
4586      {
4587        rSGU.allBordersAvailable = false;
4588        break;
4589      }
4590    }
4591  }
4592}
4593
4594#if H_3D
4595Void TComDataCU::getPosInPic( UInt uiAbsPartIndex, Int& riPosX, Int& riPosY )
4596{
4597  riPosX = g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelX();
4598  riPosY = g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIndex]] + getCUPelY(); 
4599}
4600#endif
4601#if H_3D_NBDV
4602//Notes from QC:
4603//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
4604//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
4605//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
4606Bool TComDataCU::getDisMvpCandNBDV( DisInfo* pDInfo
4607#if H_3D_NBDV_REF
4608, Bool bDepthRefine
4609#endif
4610)
4611{
4612  //// ******* Init variables ******* /////
4613  // Init disparity struct for results
4614  pDInfo->bDV = false;   
4615  // Init struct for disparities from MCP neighboring blocks
4616  IDVInfo cIDVInfo;
4617  cIDVInfo.m_bFound = false; 
4618  UInt uiPartIdx = 0;
4619  UInt uiPartAddr = 0;
4620  for (UInt iCurDvMcpCand = 0; iCurDvMcpCand < IDV_CANDS; iCurDvMcpCand++)
4621  {
4622    for (UInt iList = 0; iList < 2; iList++)
4623    {
4624      cIDVInfo.m_acMvCand[iList][iCurDvMcpCand].setZero();
4625      cIDVInfo.m_aVIdxCan[iList][iCurDvMcpCand] = 0; 
4626      cIDVInfo.m_bAvailab[iList][iCurDvMcpCand] = false; 
4627    }
4628  }
4629#if H_3D_NBDV_REF
4630  if( !m_pcSlice->getVPS()->getDepthRefinementFlag( m_pcSlice->getLayerIdInVps() ) )
4631  {
4632    bDepthRefine = false;
4633  }
4634#endif
4635  // Get Positions 
4636  PartSize eCUMode    = getPartitionSize( uiPartAddr );   
4637  assert(eCUMode == SIZE_2Nx2N);
4638  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB; 
4639
4640  deriveLeftRightTopIdxGeneral(uiPartAddr, uiPartIdx, uiPartIdxLT, uiPartIdxRT );
4641  deriveLeftBottomIdxGeneral  (uiPartAddr, uiPartIdx, uiPartIdxLB );
4642
4643  //// ******* Get disparity from temporal neighboring blocks ******* /////
4644  if ( getSlice()->getEnableTMVPFlag() )
4645  {
4646    TComMv cColMv;
4647    Int iTargetViewIdx = 0;
4648    Int iTStartViewIdx = 0;   
4649
4650    ///*** Derive center position ***
4651    UInt uiPartIdxCenter;
4652    Int  uiLCUIdx   = getAddr();
4653    xDeriveCenterIdx(uiPartIdx, uiPartIdxCenter );
4654
4655    ///*** Derive bottom right neighbour position ***
4656    Int iLCUIdxRBNb  = -1;   
4657    Int iPartIdxRBNb = -1;
4658    xDeriveRightBottomNbIdx(iLCUIdxRBNb, iPartIdxRBNb );
4659
4660    ///*** Search temporal candidate pictures for disparity vector ***
4661    const Int iNumCandPics = getPic()->getNumDdvCandPics();
4662    for(Int curCandPic = 0; curCandPic < iNumCandPics; curCandPic++)
4663    {
4664      RefPicList eCurRefPicList   = REF_PIC_LIST_0 ;
4665      Int        curCandPicRefIdx = 0;
4666      if( curCandPic == 0 ) 
4667      { 
4668        eCurRefPicList   = RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0);
4669        curCandPicRefIdx = getSlice()->getColRefIdx();
4670      }
4671      else                 
4672      {
4673        eCurRefPicList   = getPic()->getRapRefList();
4674        curCandPicRefIdx = getPic()->getRapRefIdx();
4675      }
4676
4677      // Check BR and Center       
4678      for(Int curPosition = 0; curPosition < 2; curPosition++) 
4679      {
4680        Bool bCheck = false; 
4681        if ( curPosition == 0 && iLCUIdxRBNb >= 0 )
4682          bCheck = xGetColDisMV( eCurRefPicList, curCandPicRefIdx, iLCUIdxRBNb, iPartIdxRBNb,  cColMv, iTargetViewIdx, iTStartViewIdx);
4683
4684        if (curPosition == 1 )
4685          bCheck = xGetColDisMV( eCurRefPicList, curCandPicRefIdx, uiLCUIdx,   uiPartIdxCenter,  cColMv, iTargetViewIdx, iTStartViewIdx );
4686
4687        if( bCheck )
4688        {
4689          clipMv(cColMv);
4690          pDInfo->m_acNBDV = cColMv;
4691          pDInfo->m_aVIdxCan  = iTargetViewIdx;
4692
4693#if H_3D_NBDV_REF
4694          TComPic* picDepth = NULL;         
4695          picDepth = getSlice()->getIvPic( true, iTargetViewIdx );
4696          assert(picDepth != NULL);
4697          if (picDepth && bDepthRefine)
4698            estimateDVFromDM(iTargetViewIdx, uiPartIdx, picDepth, uiPartAddr, &cColMv );
4699
4700          pDInfo->m_acDoNBDV  = cColMv;
4701#endif //H_3D_NBDV_REF
4702          return true;
4703        }
4704      } 
4705    }
4706  } 
4707
4708  UInt uiIdx = 0;
4709  Bool        bCheckMcpDv = false;   
4710  TComDataCU* pcTmpCU     = NULL;
4711
4712  //// ******* Get disparity from left block ******* /////
4713  pcTmpCU = getPULeft(uiIdx, uiPartIdxLB, true, false);
4714  bCheckMcpDv = true; 
4715  if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_LEFT
4716#if H_3D_NBDV_REF
4717  , bDepthRefine
4718#endif
4719    ) )
4720    return true;
4721
4722  //// ******* Get disparity from above block ******* /////
4723  pcTmpCU = getPUAbove(uiIdx, uiPartIdxRT, true, false, true);
4724  if(pcTmpCU != NULL )
4725  {
4726    bCheckMcpDv = ( ( getAddr() - pcTmpCU->getAddr() ) == 0);
4727    if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_ABOVE
4728#if H_3D_NBDV_REF
4729  , bDepthRefine
4730#endif
4731    ) )
4732      return true;
4733  }
4734
4735  //// ******* Get disparity from above right block ******* /////
4736  pcTmpCU = getPUAboveRight(uiIdx, uiPartIdxRT, true);
4737  if(pcTmpCU != NULL )
4738  {
4739    bCheckMcpDv = ( ( getAddr() - pcTmpCU->getAddr() ) == 0);
4740    if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_ABOVERIGHT
4741#if H_3D_NBDV_REF
4742  , bDepthRefine
4743#endif
4744    ) )
4745      return true;
4746  }
4747
4748  //// ******* Get disparity from below left block ******* /////
4749  pcTmpCU = getPUBelowLeft(uiIdx, uiPartIdxLB, true);
4750  if( pcTmpCU != NULL )
4751  {
4752    bCheckMcpDv = true; 
4753    if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_LEFTBELOW
4754#if H_3D_NBDV_REF
4755  , bDepthRefine
4756#endif
4757    ) )
4758      return true;
4759  }
4760
4761  //// ******* Get disparity from above left block ******* /////
4762  pcTmpCU = getPUAboveLeft(uiIdx, (m_uiAbsIdxInLCU + uiPartAddr), true);
4763  assert(uiPartIdxLT == (m_uiAbsIdxInLCU + uiPartAddr));
4764
4765  if( pcTmpCU != NULL )
4766  {
4767    bCheckMcpDv = (( getAddr() - pcTmpCU->getAddr() ) <= 1); 
4768    if ( xCheckSpatialNBDV( pcTmpCU, uiIdx, pDInfo, bCheckMcpDv, &cIDVInfo, DVFROM_ABOVELEFT
4769#if H_3D_NBDV_REF
4770  , bDepthRefine
4771#endif
4772    ) )
4773      return true;
4774  }
4775
4776  //// ******* Search MCP blocks ******* /////
4777  if( cIDVInfo.m_bFound ) 
4778  {
4779    for( Int curPos = 0 ; curPos < IDV_CANDS ; curPos++ ) 
4780    {
4781      for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
4782      {
4783        if( cIDVInfo.m_bAvailab[iList][curPos] )
4784        {
4785          TComMv cDispVec = cIDVInfo.m_acMvCand[iList][ curPos ];
4786          clipMv( cDispVec );
4787          pDInfo->m_acNBDV = cDispVec;
4788#if H_3D_CLEANUPS
4789          pDInfo->m_aVIdxCan = cIDVInfo.m_aVIdxCan[iList][ curPos ];
4790          assert(pDInfo->m_aVIdxCan == 0); //Notes from QC: only works for CTC
4791#else
4792          pDInfo->m_aVIdxCan = 0;
4793#endif
4794#if H_3D_NBDV_REF
4795#if H_3D_CLEANUPS
4796          TComPic* picDepth = getSlice()->getIvPic( true, pDInfo->m_aVIdxCan );
4797#else
4798          TComPic* picDepth = getSlice()->getIvPic( true, 0 );
4799#endif
4800          assert(picDepth!=NULL);
4801
4802          if (picDepth && bDepthRefine)
4803#if H_3D_CLEANUPS
4804            estimateDVFromDM (pDInfo->m_aVIdxCan, uiPartIdx, picDepth, uiPartAddr, &cDispVec);
4805#else
4806            estimateDVFromDM(0, uiPartIdx, picDepth, uiPartAddr, &cDispVec ); // from base view
4807#endif
4808          pDInfo->m_acDoNBDV = cDispVec;
4809#endif
4810          return true;
4811        }
4812      }
4813    }
4814  }
4815
4816  TComMv defaultDV(0, 0);
4817  pDInfo->m_acNBDV = defaultDV;
4818  pDInfo->m_aVIdxCan = 0;
4819#if H_3D_NBDV_REF
4820  TComPic* picDepth = NULL;
4821  picDepth = getSlice()->getIvPic( true, 0 );
4822  assert(picDepth!=NULL);
4823
4824  if (picDepth && bDepthRefine)
4825  {
4826    estimateDVFromDM(0, uiPartIdx, picDepth, uiPartAddr, &defaultDV ); // from base view
4827  }
4828  pDInfo->m_acDoNBDV = defaultDV;
4829#endif
4830
4831  return false; 
4832}
4833
4834#if H_3D_NBDV_REF
4835Pel TComDataCU::getMcpFromDM(TComPicYuv* pcBaseViewDepthPicYuv, TComMv* mv, Int iBlkX, Int iBlkY, Int iBlkWidth, Int iBlkHeight, Int* aiShiftLUT )
4836{
4837  Int iPictureWidth  = pcBaseViewDepthPicYuv->getWidth();
4838  Int iPictureHeight = pcBaseViewDepthPicYuv->getHeight();
4839
4840  Int depthStartPosX = Clip3(0,   iPictureWidth - iBlkWidth,  iBlkX + ((mv->getHor()+2)>>2));
4841  Int depthStartPosY = Clip3(0,   iPictureHeight- iBlkHeight,  iBlkY + ((mv->getVer()+2)>>2));
4842  Int depthEndPosX   = Clip3(0,   iPictureWidth - 1,  iBlkX + iBlkWidth - 1 + ((mv->getHor()+2)>>2));
4843  Int depthEndPosY   = Clip3(0,   iPictureHeight - 1,  iBlkY + iBlkHeight - 1 + ((mv->getVer()+2)>>2));
4844
4845  Pel* depthTL  = pcBaseViewDepthPicYuv->getLumaAddr();
4846  Int depStride =  pcBaseViewDepthPicYuv->getStride();
4847
4848  Pel  maxDepthVal = 0;
4849  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthStartPosX ]);      // Left Top
4850  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthStartPosX ]);      // Left Bottom
4851  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthStartPosY) * depStride + depthEndPosX   ]);      // Right Top
4852  maxDepthVal = std::max( maxDepthVal, depthTL[ (depthEndPosY)   * depStride + depthEndPosX   ]);      // Right Bottom
4853
4854  return aiShiftLUT[ maxDepthVal ];
4855}
4856
4857Void TComDataCU::estimateDVFromDM(Int refViewIdx, UInt uiPartIdx, TComPic* picDepth, UInt uiPartAddr, TComMv* cMvPred )
4858{
4859  if (picDepth)
4860  {
4861    UInt uiAbsPartAddrCurrCU = m_uiAbsIdxInLCU + uiPartAddr;
4862    Int iWidth, iHeight;
4863    getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight ); // The modified value of uiPartAddr won't be used any more
4864
4865    TComPicYuv* pcBaseViewDepthPicYuv = picDepth->getPicYuvRec();
4866    Int iBlkX = ( getAddr() % picDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
4867    Int iBlkY = ( getAddr() / picDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartAddrCurrCU ] ];
4868
4869    Int* aiShiftLUT = getSlice()->getDepthToDisparityB(refViewIdx );
4870
4871    Pel iDisp = getMcpFromDM( pcBaseViewDepthPicYuv, cMvPred, iBlkX, iBlkY, iWidth, iHeight, aiShiftLUT );
4872    cMvPred->setHor( iDisp );
4873    clipMv(*cMvPred);
4874  }
4875}
4876#endif //H_3D_NBDV_REF
4877
4878
4879Bool TComDataCU::xCheckSpatialNBDV( TComDataCU* pcTmpCU, UInt uiIdx, DisInfo* pNbDvInfo, Bool bSearchForMvpDv, IDVInfo* paIDVInfo, UInt uiMvpDvPos
4880#if H_3D_NBDV_REF
4881, Bool bDepthRefine
4882#endif
4883)
4884{
4885  if( pcTmpCU != NULL && !pcTmpCU->isIntra( uiIdx ) )
4886  {
4887    Bool bTmpIsSkipped = pcTmpCU->isSkipped( uiIdx );
4888    for(Int iList = 0; iList < (getSlice()->isInterB() ? 2: 1); iList ++)
4889    {
4890      RefPicList eRefPicList = RefPicList(iList);
4891      Int      refId = pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ;
4892      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
4893
4894      if( refId >= 0)
4895      {
4896        Int refViewIdx  = pcTmpCU->getSlice()->getRefPic(eRefPicList, refId)->getViewIndex();
4897        if (refViewIdx != m_pcSlice->getViewIndex()) 
4898        {
4899          clipMv(cMvPred);
4900          pNbDvInfo->m_acNBDV = cMvPred;
4901          pNbDvInfo->m_aVIdxCan = refViewIdx;
4902#if H_3D_NBDV_REF
4903          TComPic* picDepth = NULL;
4904          assert(getSlice()->getRefPic(eRefPicList, refId)->getPOC() == getSlice()->getPOC());         
4905          picDepth   = getSlice()->getIvPic (true, refViewIdx );
4906          assert(picDepth != NULL);
4907
4908          UInt uiPartIdx = 0;   //Notes from MTK: Please confirm that using 0 as partition index and partition address is correct for CU-level DoNBDV
4909          UInt uiPartAddr = 0;  //QC: confirmed
4910
4911          if (picDepth && bDepthRefine)
4912            estimateDVFromDM(refViewIdx, uiPartIdx, picDepth, uiPartAddr, &cMvPred );
4913
4914          pNbDvInfo->m_acDoNBDV = cMvPred;
4915#endif
4916          return true;
4917        }
4918        else if ( bSearchForMvpDv && cMvPred.getIDVFlag() && bTmpIsSkipped )
4919        {
4920          assert( uiMvpDvPos < IDV_CANDS );
4921          paIDVInfo->m_acMvCand[iList][ uiMvpDvPos ] = TComMv( cMvPred.getIDVHor(), cMvPred.getIDVVer() );
4922          //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.
4923          paIDVInfo->m_aVIdxCan[iList][ uiMvpDvPos ] = 0; 
4924          paIDVInfo->m_bAvailab[iList][ uiMvpDvPos ] = true;
4925          paIDVInfo->m_bFound                        = true; 
4926        }
4927      }
4928    }
4929  }
4930  return false; 
4931}
4932 
4933Void TComDataCU::xDeriveRightBottomNbIdx(Int &riLCUIdxRBNb, Int &riPartIdxRBNb )
4934{
4935  UInt uiPartIdx = 0;
4936  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth(); 
4937  Int uiLCUIdx = getAddr();
4938
4939  UInt uiPartIdxRB;
4940  deriveRightBottomIdx(uiPartIdx, uiPartIdxRB ); 
4941  UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
4942
4943  if (( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() )>= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
4944  {
4945    riLCUIdxRBNb  = -1;
4946    riPartIdxRBNb = -1;
4947  }
4948  else if(( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() )>= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
4949  {
4950    riLCUIdxRBNb  = -1;
4951    riPartIdxRBNb = -1;
4952  }
4953  else
4954  {
4955    if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
4956      ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
4957    {
4958      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
4959      riLCUIdxRBNb  = uiLCUIdx; 
4960    }
4961    else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
4962    {
4963      riPartIdxRBNb = -1;
4964      riLCUIdxRBNb  = -1;
4965    }
4966    else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
4967    {
4968      riPartIdxRBNb = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
4969      riLCUIdxRBNb = uiLCUIdx + 1;
4970    }
4971    else //is the right bottom corner of LCU                       
4972    {
4973      riPartIdxRBNb = -1;
4974      riLCUIdxRBNb  = -1;
4975    }
4976  }
4977}
4978
4979
4980Void TComDataCU::setDvInfoSubParts( DisInfo cDvInfo, UInt uiAbsPartIdx, UInt uiDepth )
4981{
4982  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
4983  for (UInt ui = 0; ui < uiCurrPartNumb; ui++ )
4984  {
4985    m_pDvInfo[uiAbsPartIdx + ui] = cDvInfo;
4986  }
4987}
4988
4989Bool TComDataCU::xGetColDisMV( RefPicList eRefPicList, Int refidx, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv , Int & iTargetViewIdx, Int & iStartViewIdx )
4990{
4991
4992  RefPicList  eColRefPicList = REF_PIC_LIST_0;
4993  Int iColViewIdx, iColRefViewIdx;
4994  TComPic *pColPic = getSlice()->getRefPic( eRefPicList, refidx);
4995  TComDataCU *pColCU = pColPic->getCU( uiCUAddr );
4996  iColViewIdx = pColCU->getSlice()->getViewIndex();
4997  if (pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==SIZE_NONE||pColCU->isIntra(uiPartUnitIdx))
4998  {
4999    return false;
5000  }
5001  for (Int ilist = 0; ilist < (pColCU->getSlice()->isInterB()? 2:1); ilist++) 
5002  {
5003    if(pColCU->getSlice()->isInterB())
5004    {
5005        eColRefPicList = RefPicList(ilist);
5006    }
5007
5008    Int iColRefIdx = pColCU->getCUMvField(eColRefPicList)->getRefIdx(uiPartUnitIdx);
5009
5010    if (iColRefIdx < 0)
5011    {
5012      continue;
5013    }
5014
5015    iColRefViewIdx = pColCU->getSlice()->getRefPic(eColRefPicList, iColRefIdx)->getViewIndex();
5016
5017    if ( iColViewIdx    == iColRefViewIdx ) // temporal vector
5018    {
5019      continue;
5020    }
5021    else 
5022    {
5023      rcMv = pColCU->getCUMvField(eColRefPicList)->getMv(uiPartUnitIdx);
5024      rcMv.setIDVFlag(0);
5025      iTargetViewIdx  = iColRefViewIdx ;
5026      iStartViewIdx   = iColViewIdx   ;
5027      return true;   
5028    }
5029  }
5030
5031  return false;
5032}
5033#endif
5034#if H_3D_IV_MERGE
5035Bool
5036TComDataCU::getInterViewMergeCands(UInt uiPartIdx, Int* paiPdmRefIdx, TComMv* pacPdmMv, DisInfo* pDInfo, Int* availableMcDc )
5037{
5038  TComSlice*    pcSlice         = getSlice (); 
5039#if H_3D_CLEANUPS //Notes from QC: to be aligned with the spec.
5040  Int iViewIndex = pDInfo->m_aVIdxCan;
5041#else
5042  Bool valid     = false;
5043
5044  Int iViewIndex = 0;
5045
5046  for( UInt uiBIndex = 0; uiBIndex < pcSlice->getViewIndex( ) && !valid; uiBIndex++ )
5047  {
5048    UInt        uiBaseIndex = uiBIndex;   
5049    TComPic*    pcBasePic   = pcSlice->getIvPic( false, uiBaseIndex );
5050    for( Int iRefListId = 0; iRefListId < 2 && !valid; iRefListId++ )
5051    {
5052      RefPicList  eRefPicListTest = RefPicList( iRefListId );
5053      Int         iNumRefPics = pcSlice->getNumRefIdx( eRefPicListTest ) ;
5054      for( Int iRefIndex = 0; iRefIndex < iNumRefPics; iRefIndex++ )
5055      { 
5056        if(pcBasePic->getPOC() == pcSlice->getRefPic( eRefPicListTest, iRefIndex )->getPOC() 
5057          && pcBasePic->getViewIndex() == pcSlice->getRefPic( eRefPicListTest, iRefIndex )->getViewIndex())
5058        {
5059          valid = true;
5060          iViewIndex = uiBaseIndex;
5061          break;
5062        }
5063      }
5064    }
5065  }
5066
5067  if (!valid)
5068    return false;
5069#endif
5070  //--- get base CU/PU and check prediction mode ---
5071  TComPic*    pcBasePic   = pcSlice->getIvPic( false, iViewIndex );
5072  TComPicYuv* pcBaseRec   = pcBasePic->getPicYuvRec   ();
5073
5074  UInt          uiPartAddr;
5075  Int           iWidth;
5076  Int           iHeight;
5077  getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
5078
5079  Int  iCurrPosX, iCurrPosY;
5080  pcBaseRec->getTopLeftSamplePos( getAddr(), getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
5081
5082  iCurrPosX  += ( ( iWidth  - 1 ) >> 1 );
5083  iCurrPosY  += ( ( iHeight - 1 ) >> 1 );
5084
5085  Bool depthRefineFlag = false; 
5086#if H_3D_NBDV_REF
5087  depthRefineFlag = m_pcSlice->getVPS()->getDepthRefinementFlag( m_pcSlice->getLayerIdInVps() ); 
5088#endif // H_3D_NBDV_REF
5089
5090  TComMv      cDv = depthRefineFlag ? pDInfo->m_acDoNBDV : pDInfo->m_acNBDV; 
5091 
5092  Int         iBasePosX   = Clip3( 0, pcBaseRec->getWidth () - 1, iCurrPosX + ( (cDv.getHor() + 2 ) >> 2 ) );
5093  Int         iBasePosY   = Clip3( 0, pcBaseRec->getHeight() - 1, iCurrPosY + ( (cDv.getVer() + 2 ) >> 2 )); 
5094
5095  Int         iBaseCUAddr;
5096  Int         iBaseAbsPartIdx;
5097  pcBaseRec->getCUAddrAndPartIdx( iBasePosX , iBasePosY , iBaseCUAddr, iBaseAbsPartIdx );
5098
5099  TComDataCU* pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
5100
5101  Bool abPdmAvailable[4] = {false, false, false, false};
5102#if H_3D_NBDV
5103  for( Int i = 0; i < 4; i++)
5104  {
5105    pacPdmMv[i].setIDVFlag   (false);
5106  }
5107#endif