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

Last change on this file since 487 was 487, checked in by tech, 11 years ago

Fixed bug in TComDataCU::getInterMergeCandidates.

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