source: SHVCSoftware/branches/SHM-6-dev/source/Lib/TLibCommon/TComDataCU.cpp @ 1544

Last change on this file since 1544 was 813, checked in by seregin, 11 years ago

fix the motion resampling condition, related to SHM ticket #21

  • Property svn:eol-style set to native
File size: 139.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-2014, 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}
115
116TComDataCU::~TComDataCU()
117{
118}
119
120Void TComDataCU::create(UInt uiNumPartition, UInt uiWidth, UInt uiHeight, Bool bDecSubCu, Int unitSize
121#if ADAPTIVE_QP_SELECTION
122                        , Bool bGlobalRMARLBuffer
123#endif                                             
124                        )
125{
126  m_bDecSubCu = bDecSubCu;
127 
128  m_pcPic              = NULL;
129  m_pcSlice            = NULL;
130  m_uiNumPartition     = uiNumPartition;
131  m_unitSize = unitSize;
132 
133  if ( !bDecSubCu )
134  {
135    m_phQP               = (Char*     )xMalloc(Char,     uiNumPartition);
136    m_puhDepth           = (UChar*    )xMalloc(UChar,    uiNumPartition);
137    m_puhWidth           = (UChar*    )xMalloc(UChar,    uiNumPartition);
138    m_puhHeight          = (UChar*    )xMalloc(UChar,    uiNumPartition);
139
140    m_skipFlag           = new Bool[ uiNumPartition ];
141
142    m_pePartSize         = new Char[ uiNumPartition ];
143    memset( m_pePartSize, SIZE_NONE,uiNumPartition * sizeof( *m_pePartSize ) );
144    m_pePredMode         = new Char[ uiNumPartition ];
145    m_CUTransquantBypass = new Bool[ uiNumPartition ];
146    m_pbMergeFlag        = (Bool*  )xMalloc(Bool,   uiNumPartition);
147    m_puhMergeIndex      = (UChar* )xMalloc(UChar,  uiNumPartition);
148    m_puhLumaIntraDir    = (UChar* )xMalloc(UChar,  uiNumPartition);
149    m_puhChromaIntraDir  = (UChar* )xMalloc(UChar,  uiNumPartition);
150    m_puhInterDir        = (UChar* )xMalloc(UChar,  uiNumPartition);
151   
152    m_puhTrIdx           = (UChar* )xMalloc(UChar,  uiNumPartition);
153    m_puhTransformSkip[0] = (UChar* )xMalloc(UChar,  uiNumPartition);
154    m_puhTransformSkip[1] = (UChar* )xMalloc(UChar,  uiNumPartition);
155    m_puhTransformSkip[2] = (UChar* )xMalloc(UChar,  uiNumPartition);
156
157    m_puhCbf[0]          = (UChar* )xMalloc(UChar,  uiNumPartition);
158    m_puhCbf[1]          = (UChar* )xMalloc(UChar,  uiNumPartition);
159    m_puhCbf[2]          = (UChar* )xMalloc(UChar,  uiNumPartition);
160   
161    m_apiMVPIdx[0]       = new Char[ uiNumPartition ];
162    m_apiMVPIdx[1]       = new Char[ uiNumPartition ];
163    m_apiMVPNum[0]       = new Char[ uiNumPartition ];
164    m_apiMVPNum[1]       = new Char[ uiNumPartition ];
165    memset( m_apiMVPIdx[0], -1,uiNumPartition * sizeof( Char ) );
166    memset( m_apiMVPIdx[1], -1,uiNumPartition * sizeof( Char ) );
167   
168    m_pcTrCoeffY         = (TCoeff*)xMalloc(TCoeff, uiWidth*uiHeight);
169    m_pcTrCoeffCb        = (TCoeff*)xMalloc(TCoeff, uiWidth*uiHeight/4);
170    m_pcTrCoeffCr        = (TCoeff*)xMalloc(TCoeff, uiWidth*uiHeight/4);
171    memset( m_pcTrCoeffY, 0,uiWidth*uiHeight * sizeof( TCoeff ) );
172    memset( m_pcTrCoeffCb, 0,uiWidth*uiHeight/4 * sizeof( TCoeff ) );
173    memset( m_pcTrCoeffCr, 0,uiWidth*uiHeight/4 * sizeof( TCoeff ) );
174#if ADAPTIVE_QP_SELECTION
175    if( bGlobalRMARLBuffer )
176    {
177      if( m_pcGlbArlCoeffY == NULL )
178      {
179#if LAYER_CTB
180        m_pcGlbArlCoeffY   = (Int*)xMalloc(Int, MAX_CU_SIZE * MAX_CU_SIZE);
181        m_pcGlbArlCoeffCb  = (Int*)xMalloc(Int, MAX_CU_SIZE * MAX_CU_SIZE/4);
182        m_pcGlbArlCoeffCr  = (Int*)xMalloc(Int, MAX_CU_SIZE * MAX_CU_SIZE/4);
183#else
184        m_pcGlbArlCoeffY   = (Int*)xMalloc(Int, uiWidth*uiHeight);
185        m_pcGlbArlCoeffCb  = (Int*)xMalloc(Int, uiWidth*uiHeight/4);
186        m_pcGlbArlCoeffCr  = (Int*)xMalloc(Int, uiWidth*uiHeight/4);
187#endif
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   
293    m_acCUMvField[0].destroy();
294    m_acCUMvField[1].destroy();
295   
296  }
297 
298  m_pcCUAboveLeft       = NULL;
299  m_pcCUAboveRight      = NULL;
300  m_pcCUAbove           = NULL;
301  m_pcCULeft            = NULL;
302 
303  m_apcCUColocated[0]   = NULL;
304  m_apcCUColocated[1]   = NULL;
305
306  if( m_sliceStartCU )
307  {
308    xFree(m_sliceStartCU);
309    m_sliceStartCU=NULL;
310  }
311  if(m_sliceSegmentStartCU )
312  {
313    xFree(m_sliceSegmentStartCU);
314    m_sliceSegmentStartCU=NULL;
315  }
316}
317
318// ====================================================================================================================
319// Public member functions
320// ====================================================================================================================
321
322// --------------------------------------------------------------------------------------------------------------------
323// Initialization
324// --------------------------------------------------------------------------------------------------------------------
325
326/**
327 - initialize top-level CU
328 - internal buffers are already created
329 - set values before encoding a CU
330 .
331 \param  pcPic     picture (TComPic) class pointer
332 \param  iCUAddr   CU address
333 */
334Void TComDataCU::initCU( TComPic* pcPic, UInt iCUAddr )
335{
336
337  m_pcPic              = pcPic;
338  m_pcSlice            = pcPic->getSlice(pcPic->getCurrSliceIdx());
339  m_uiCUAddr           = iCUAddr;
340  m_uiCUPelX           = ( iCUAddr % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth;
341  m_uiCUPelY           = ( iCUAddr / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight;
342  m_uiAbsIdxInLCU      = 0;
343  m_dTotalCost         = MAX_DOUBLE;
344  m_uiTotalDistortion  = 0;
345  m_uiTotalBits        = 0;
346  m_uiTotalBins        = 0;
347  m_uiNumPartition     = pcPic->getNumPartInCU();
348
349#if SVC_EXTENSION
350  m_layerId           = pcPic->getLayerId();
351#endif
352 
353  for(Int i=0; i<pcPic->getNumPartInCU(); i++)
354  {
355    if(pcPic->getPicSym()->getInverseCUOrderMap(iCUAddr)*pcPic->getNumPartInCU()+i>=getSlice()->getSliceCurStartCUAddr())
356    {
357      m_sliceStartCU[i]=getSlice()->getSliceCurStartCUAddr();
358    }
359    else
360    {
361      m_sliceStartCU[i]=pcPic->getCU(getAddr())->m_sliceStartCU[i];
362    }
363  }
364  for(Int i=0; i<pcPic->getNumPartInCU(); i++)
365  {
366    if(pcPic->getPicSym()->getInverseCUOrderMap(iCUAddr)*pcPic->getNumPartInCU()+i>=getSlice()->getSliceSegmentCurStartCUAddr())
367    {
368      m_sliceSegmentStartCU[i]=getSlice()->getSliceSegmentCurStartCUAddr();
369    }
370    else
371    {
372      m_sliceSegmentStartCU[i]=pcPic->getCU(getAddr())->m_sliceSegmentStartCU[i];
373    }
374  }
375
376  Int partStartIdx = getSlice()->getSliceSegmentCurStartCUAddr() - pcPic->getPicSym()->getInverseCUOrderMap(iCUAddr) * pcPic->getNumPartInCU();
377
378  Int numElements = min<Int>( partStartIdx, m_uiNumPartition );
379  for ( Int ui = 0; ui < numElements; ui++ )
380  {
381    TComDataCU * pcFrom = pcPic->getCU(getAddr());
382    m_skipFlag[ui]   = pcFrom->getSkipFlag(ui);
383    m_pePartSize[ui] = pcFrom->getPartitionSize(ui);
384    m_pePredMode[ui] = pcFrom->getPredictionMode(ui);
385    m_CUTransquantBypass[ui] = pcFrom->getCUTransquantBypass(ui);
386    m_puhDepth[ui] = pcFrom->getDepth(ui);
387    m_puhWidth  [ui] = pcFrom->getWidth(ui);
388    m_puhHeight [ui] = pcFrom->getHeight(ui);
389    m_puhTrIdx  [ui] = pcFrom->getTransformIdx(ui);
390    m_puhTransformSkip[0][ui] = pcFrom->getTransformSkip(ui,TEXT_LUMA);
391    m_puhTransformSkip[1][ui] = pcFrom->getTransformSkip(ui,TEXT_CHROMA_U);
392    m_puhTransformSkip[2][ui] = pcFrom->getTransformSkip(ui,TEXT_CHROMA_V);
393    m_apiMVPIdx[0][ui] = pcFrom->m_apiMVPIdx[0][ui];;
394    m_apiMVPIdx[1][ui] = pcFrom->m_apiMVPIdx[1][ui];
395    m_apiMVPNum[0][ui] = pcFrom->m_apiMVPNum[0][ui];
396    m_apiMVPNum[1][ui] = pcFrom->m_apiMVPNum[1][ui];
397    m_phQP[ui]=pcFrom->m_phQP[ui];
398    m_pbMergeFlag[ui]=pcFrom->m_pbMergeFlag[ui];
399    m_puhMergeIndex[ui]=pcFrom->m_puhMergeIndex[ui];
400    m_puhLumaIntraDir[ui]=pcFrom->m_puhLumaIntraDir[ui];
401    m_puhChromaIntraDir[ui]=pcFrom->m_puhChromaIntraDir[ui];
402    m_puhInterDir[ui]=pcFrom->m_puhInterDir[ui];
403    m_puhCbf[0][ui]=pcFrom->m_puhCbf[0][ui];
404    m_puhCbf[1][ui]=pcFrom->m_puhCbf[1][ui];
405    m_puhCbf[2][ui]=pcFrom->m_puhCbf[2][ui];
406    m_pbIPCMFlag[ui] = pcFrom->m_pbIPCMFlag[ui];
407  }
408 
409  Int firstElement = max<Int>( partStartIdx, 0 );
410  numElements = m_uiNumPartition - firstElement;
411 
412  if ( numElements > 0 )
413  {
414    memset( m_skipFlag          + firstElement, false,                    numElements * sizeof( *m_skipFlag ) );
415
416    memset( m_pePartSize        + firstElement, SIZE_NONE,                numElements * sizeof( *m_pePartSize ) );
417    memset( m_pePredMode        + firstElement, MODE_NONE,                numElements * sizeof( *m_pePredMode ) );
418    memset( m_CUTransquantBypass+ firstElement, false,                    numElements * sizeof( *m_CUTransquantBypass) );
419    memset( m_puhDepth          + firstElement, 0,                        numElements * sizeof( *m_puhDepth ) );
420    memset( m_puhTrIdx          + firstElement, 0,                        numElements * sizeof( *m_puhTrIdx ) );
421    memset( m_puhTransformSkip[0] + firstElement, 0,                      numElements * sizeof( *m_puhTransformSkip[0]) );
422    memset( m_puhTransformSkip[1] + firstElement, 0,                      numElements * sizeof( *m_puhTransformSkip[1]) );
423    memset( m_puhTransformSkip[2] + firstElement, 0,                      numElements * sizeof( *m_puhTransformSkip[2]) );
424    memset( m_puhWidth          + firstElement, g_uiMaxCUWidth,           numElements * sizeof( *m_puhWidth ) );
425    memset( m_puhHeight         + firstElement, g_uiMaxCUHeight,          numElements * sizeof( *m_puhHeight ) );
426    memset( m_apiMVPIdx[0]      + firstElement, -1,                       numElements * sizeof( *m_apiMVPIdx[0] ) );
427    memset( m_apiMVPIdx[1]      + firstElement, -1,                       numElements * sizeof( *m_apiMVPIdx[1] ) );
428    memset( m_apiMVPNum[0]      + firstElement, -1,                       numElements * sizeof( *m_apiMVPNum[0] ) );
429    memset( m_apiMVPNum[1]      + firstElement, -1,                       numElements * sizeof( *m_apiMVPNum[1] ) );
430    memset( m_phQP              + firstElement, getSlice()->getSliceQp(), numElements * sizeof( *m_phQP ) );
431    memset( m_pbMergeFlag       + firstElement, false,                    numElements * sizeof( *m_pbMergeFlag ) );
432    memset( m_puhMergeIndex     + firstElement, 0,                        numElements * sizeof( *m_puhMergeIndex ) );
433    memset( m_puhLumaIntraDir   + firstElement, DC_IDX,                   numElements * sizeof( *m_puhLumaIntraDir ) );
434    memset( m_puhChromaIntraDir + firstElement, 0,                        numElements * sizeof( *m_puhChromaIntraDir ) );
435    memset( m_puhInterDir       + firstElement, 0,                        numElements * sizeof( *m_puhInterDir ) );
436    memset( m_puhCbf[0]         + firstElement, 0,                        numElements * sizeof( *m_puhCbf[0] ) );
437    memset( m_puhCbf[1]         + firstElement, 0,                        numElements * sizeof( *m_puhCbf[1] ) );
438    memset( m_puhCbf[2]         + firstElement, 0,                        numElements * sizeof( *m_puhCbf[2] ) );
439    memset( m_pbIPCMFlag        + firstElement, false,                    numElements * sizeof( *m_pbIPCMFlag ) );
440  }
441 
442  UInt uiTmp = g_uiMaxCUWidth*g_uiMaxCUHeight;
443  if ( 0 >= partStartIdx ) 
444  {
445    m_acCUMvField[0].clearMvField();
446    m_acCUMvField[1].clearMvField();
447    memset( m_pcTrCoeffY , 0, sizeof( TCoeff ) * uiTmp );
448#if ADAPTIVE_QP_SELECTION
449    memset( m_pcArlCoeffY , 0, sizeof( Int ) * uiTmp ); 
450#endif
451    memset( m_pcIPCMSampleY , 0, sizeof( Pel ) * uiTmp );
452    uiTmp  >>= 2;
453    memset( m_pcTrCoeffCb, 0, sizeof( TCoeff ) * uiTmp );
454    memset( m_pcTrCoeffCr, 0, sizeof( TCoeff ) * uiTmp );
455#if ADAPTIVE_QP_SELECTION 
456    memset( m_pcArlCoeffCb, 0, sizeof( Int ) * uiTmp );
457    memset( m_pcArlCoeffCr, 0, sizeof( Int ) * uiTmp );
458#endif
459    memset( m_pcIPCMSampleCb , 0, sizeof( Pel ) * uiTmp );
460    memset( m_pcIPCMSampleCr , 0, sizeof( Pel ) * uiTmp );
461  }
462  else 
463  {
464    TComDataCU * pcFrom = pcPic->getCU(getAddr());
465    m_acCUMvField[0].copyFrom(&pcFrom->m_acCUMvField[0],m_uiNumPartition,0);
466    m_acCUMvField[1].copyFrom(&pcFrom->m_acCUMvField[1],m_uiNumPartition,0);
467    for(Int i=0; i<uiTmp; i++)
468    {
469      m_pcTrCoeffY[i]=pcFrom->m_pcTrCoeffY[i];
470#if ADAPTIVE_QP_SELECTION
471      m_pcArlCoeffY[i]=pcFrom->m_pcArlCoeffY[i];
472#endif
473      m_pcIPCMSampleY[i]=pcFrom->m_pcIPCMSampleY[i];
474    }
475    for(Int i=0; i<(uiTmp>>2); i++)
476    {
477      m_pcTrCoeffCb[i]=pcFrom->m_pcTrCoeffCb[i];
478      m_pcTrCoeffCr[i]=pcFrom->m_pcTrCoeffCr[i];
479#if ADAPTIVE_QP_SELECTION
480      m_pcArlCoeffCb[i]=pcFrom->m_pcArlCoeffCb[i];
481      m_pcArlCoeffCr[i]=pcFrom->m_pcArlCoeffCr[i];
482#endif
483      m_pcIPCMSampleCb[i]=pcFrom->m_pcIPCMSampleCb[i];
484      m_pcIPCMSampleCr[i]=pcFrom->m_pcIPCMSampleCr[i];
485    }
486  }
487
488  // Setting neighbor CU
489  m_pcCULeft        = NULL;
490  m_pcCUAbove       = NULL;
491  m_pcCUAboveLeft   = NULL;
492  m_pcCUAboveRight  = NULL;
493
494  m_apcCUColocated[0] = NULL;
495  m_apcCUColocated[1] = NULL;
496
497  UInt uiWidthInCU = pcPic->getFrameWidthInCU();
498  if ( m_uiCUAddr % uiWidthInCU )
499  {
500    m_pcCULeft = pcPic->getCU( m_uiCUAddr - 1 );
501  }
502
503  if ( m_uiCUAddr / uiWidthInCU )
504  {
505    m_pcCUAbove = pcPic->getCU( m_uiCUAddr - uiWidthInCU );
506  }
507
508  if ( m_pcCULeft && m_pcCUAbove )
509  {
510    m_pcCUAboveLeft = pcPic->getCU( m_uiCUAddr - uiWidthInCU - 1 );
511  }
512
513  if ( m_pcCUAbove && ( (m_uiCUAddr%uiWidthInCU) < (uiWidthInCU-1) )  )
514  {
515    m_pcCUAboveRight = pcPic->getCU( m_uiCUAddr - uiWidthInCU + 1 );
516  }
517
518  if ( getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 )
519  {
520    m_apcCUColocated[0] = getSlice()->getRefPic( REF_PIC_LIST_0, 0)->getCU( m_uiCUAddr );
521  }
522
523  if ( getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 )
524  {
525    m_apcCUColocated[1] = getSlice()->getRefPic( REF_PIC_LIST_1, 0)->getCU( m_uiCUAddr );
526  }
527}
528
529/** initialize prediction data with enabling sub-LCU-level delta QP
530*\param  uiDepth  depth of the current CU
531*\param  qp     qp for the current CU
532*- set CU width and CU height according to depth
533*- set qp value according to input qp
534*- set last-coded qp value according to input last-coded qp
535*/
536Void TComDataCU::initEstData( UInt uiDepth, Int qp, Bool bTransquantBypass )
537{
538  m_dTotalCost         = MAX_DOUBLE;
539  m_uiTotalDistortion  = 0;
540  m_uiTotalBits        = 0;
541  m_uiTotalBins        = 0;
542
543  UChar uhWidth  = g_uiMaxCUWidth  >> uiDepth;
544  UChar uhHeight = g_uiMaxCUHeight >> uiDepth;
545
546  for (UInt ui = 0; ui < m_uiNumPartition; ui++)
547  {
548    if(getPic()->getPicSym()->getInverseCUOrderMap(getAddr())*m_pcPic->getNumPartInCU()+m_uiAbsIdxInLCU+ui >= getSlice()->getSliceSegmentCurStartCUAddr())
549    {
550      m_apiMVPIdx[0][ui] = -1;
551      m_apiMVPIdx[1][ui] = -1;
552      m_apiMVPNum[0][ui] = -1;
553      m_apiMVPNum[1][ui] = -1;
554      m_puhDepth  [ui] = uiDepth;
555      m_puhWidth  [ui] = uhWidth;
556      m_puhHeight [ui] = uhHeight;
557      m_puhTrIdx  [ui] = 0;
558      m_puhTransformSkip[0][ui] = 0;
559      m_puhTransformSkip[1][ui] = 0;
560      m_puhTransformSkip[2][ui] = 0;
561      m_skipFlag[ui]   = false;
562      m_pePartSize[ui] = SIZE_NONE;
563      m_pePredMode[ui] = MODE_NONE;
564      m_CUTransquantBypass[ui] = bTransquantBypass;
565      m_pbIPCMFlag[ui] = 0;
566      m_phQP[ui] = qp;
567      m_pbMergeFlag[ui] = 0;
568      m_puhMergeIndex[ui] = 0;
569      m_puhLumaIntraDir[ui] = DC_IDX;
570      m_puhChromaIntraDir[ui] = 0;
571      m_puhInterDir[ui] = 0;
572      m_puhCbf[0][ui] = 0;
573      m_puhCbf[1][ui] = 0;
574      m_puhCbf[2][ui] = 0;
575    }
576  }
577
578  if(getPic()->getPicSym()->getInverseCUOrderMap(getAddr())*m_pcPic->getNumPartInCU()+m_uiAbsIdxInLCU >= getSlice()->getSliceSegmentCurStartCUAddr())
579  {
580    m_acCUMvField[0].clearMvField();
581    m_acCUMvField[1].clearMvField();
582    UInt uiTmp = uhWidth*uhHeight;
583   
584    memset( m_pcTrCoeffY,    0, uiTmp * sizeof( *m_pcTrCoeffY    ) );
585#if ADAPTIVE_QP_SELECTION
586    memset( m_pcArlCoeffY ,  0, uiTmp * sizeof( *m_pcArlCoeffY   ) );
587#endif
588    memset( m_pcIPCMSampleY, 0, uiTmp * sizeof( *m_pcIPCMSampleY ) );
589
590    uiTmp>>=2;
591    memset( m_pcTrCoeffCb,    0, uiTmp * sizeof( *m_pcTrCoeffCb    ) );
592    memset( m_pcTrCoeffCr,    0, uiTmp * sizeof( *m_pcTrCoeffCr    ) );
593#if ADAPTIVE_QP_SELECTION 
594    memset( m_pcArlCoeffCb,   0, uiTmp * sizeof( *m_pcArlCoeffCb   ) );
595    memset( m_pcArlCoeffCr,   0, uiTmp * sizeof( *m_pcArlCoeffCr   ) );
596#endif
597    memset( m_pcIPCMSampleCb, 0, uiTmp * sizeof( *m_pcIPCMSampleCb ) );
598    memset( m_pcIPCMSampleCr, 0, uiTmp * sizeof( *m_pcIPCMSampleCr ) );
599  }
600}
601
602
603// initialize Sub partition
604Void TComDataCU::initSubCU( TComDataCU* pcCU, UInt uiPartUnitIdx, UInt uiDepth, Int qp )
605{
606  assert( uiPartUnitIdx<4 );
607
608  UInt uiPartOffset = ( pcCU->getTotalNumPart()>>2 )*uiPartUnitIdx;
609
610  m_pcPic              = pcCU->getPic();
611  m_pcSlice            = m_pcPic->getSlice(m_pcPic->getCurrSliceIdx());
612  m_uiCUAddr           = pcCU->getAddr();
613  m_uiAbsIdxInLCU      = pcCU->getZorderIdxInCU() + uiPartOffset;
614
615  m_uiCUPelX           = pcCU->getCUPelX() + ( g_uiMaxCUWidth>>uiDepth  )*( uiPartUnitIdx &  1 );
616  m_uiCUPelY           = pcCU->getCUPelY() + ( g_uiMaxCUHeight>>uiDepth  )*( uiPartUnitIdx >> 1 );
617
618  m_dTotalCost         = MAX_DOUBLE;
619  m_uiTotalDistortion  = 0;
620  m_uiTotalBits        = 0;
621  m_uiTotalBins        = 0;
622  m_uiNumPartition     = pcCU->getTotalNumPart() >> 2;
623
624  Int iSizeInUchar = sizeof( UChar  ) * m_uiNumPartition;
625  Int iSizeInBool  = sizeof( Bool   ) * m_uiNumPartition;
626
627  Int sizeInChar = sizeof( Char  ) * m_uiNumPartition;
628  memset( m_phQP,              qp,  sizeInChar );
629
630  memset( m_pbMergeFlag,        0, iSizeInBool  );
631  memset( m_puhMergeIndex,      0, iSizeInUchar );
632  memset( m_puhLumaIntraDir,    DC_IDX, iSizeInUchar );
633  memset( m_puhChromaIntraDir,  0, iSizeInUchar );
634  memset( m_puhInterDir,        0, iSizeInUchar );
635  memset( m_puhTrIdx,           0, iSizeInUchar );
636  memset( m_puhTransformSkip[0], 0, iSizeInUchar );
637  memset( m_puhTransformSkip[1], 0, iSizeInUchar );
638  memset( m_puhTransformSkip[2], 0, iSizeInUchar );
639  memset( m_puhCbf[0],          0, iSizeInUchar );
640  memset( m_puhCbf[1],          0, iSizeInUchar );
641  memset( m_puhCbf[2],          0, iSizeInUchar );
642  memset( m_puhDepth,     uiDepth, iSizeInUchar );
643
644  UChar uhWidth  = g_uiMaxCUWidth  >> uiDepth;
645  UChar uhHeight = g_uiMaxCUHeight >> uiDepth;
646  memset( m_puhWidth,          uhWidth,  iSizeInUchar );
647  memset( m_puhHeight,         uhHeight, iSizeInUchar );
648  memset( m_pbIPCMFlag,        0, iSizeInBool  );
649  for (UInt ui = 0; ui < m_uiNumPartition; ui++)
650  {
651    m_skipFlag[ui]   = false;
652    m_pePartSize[ui] = SIZE_NONE;
653    m_pePredMode[ui] = MODE_NONE;
654    m_CUTransquantBypass[ui] = false;
655    m_apiMVPIdx[0][ui] = -1;
656    m_apiMVPIdx[1][ui] = -1;
657    m_apiMVPNum[0][ui] = -1;
658    m_apiMVPNum[1][ui] = -1;
659    if(m_pcPic->getPicSym()->getInverseCUOrderMap(getAddr())*m_pcPic->getNumPartInCU()+m_uiAbsIdxInLCU+ui<getSlice()->getSliceSegmentCurStartCUAddr())
660    {
661      m_apiMVPIdx[0][ui] = pcCU->m_apiMVPIdx[0][uiPartOffset+ui];
662      m_apiMVPIdx[1][ui] = pcCU->m_apiMVPIdx[1][uiPartOffset+ui];;
663      m_apiMVPNum[0][ui] = pcCU->m_apiMVPNum[0][uiPartOffset+ui];;
664      m_apiMVPNum[1][ui] = pcCU->m_apiMVPNum[1][uiPartOffset+ui];;
665      m_puhDepth  [ui] = pcCU->getDepth(uiPartOffset+ui);
666      m_puhWidth  [ui] = pcCU->getWidth(uiPartOffset+ui);
667      m_puhHeight  [ui] = pcCU->getHeight(uiPartOffset+ui);
668      m_puhTrIdx  [ui] = pcCU->getTransformIdx(uiPartOffset+ui);
669      m_puhTransformSkip[0][ui] = pcCU->getTransformSkip(uiPartOffset+ui,TEXT_LUMA);
670      m_puhTransformSkip[1][ui] = pcCU->getTransformSkip(uiPartOffset+ui,TEXT_CHROMA_U);
671      m_puhTransformSkip[2][ui] = pcCU->getTransformSkip(uiPartOffset+ui,TEXT_CHROMA_V);
672      m_skipFlag[ui]   = pcCU->getSkipFlag(uiPartOffset+ui);
673      m_pePartSize[ui] = pcCU->getPartitionSize(uiPartOffset+ui);
674      m_pePredMode[ui] = pcCU->getPredictionMode(uiPartOffset+ui);
675      m_CUTransquantBypass[ui] = pcCU->getCUTransquantBypass(uiPartOffset+ui);
676      m_pbIPCMFlag[ui]=pcCU->m_pbIPCMFlag[uiPartOffset+ui];
677      m_phQP[ui] = pcCU->m_phQP[uiPartOffset+ui];
678      m_pbMergeFlag[ui]=pcCU->m_pbMergeFlag[uiPartOffset+ui];
679      m_puhMergeIndex[ui]=pcCU->m_puhMergeIndex[uiPartOffset+ui];
680      m_puhLumaIntraDir[ui]=pcCU->m_puhLumaIntraDir[uiPartOffset+ui];
681      m_puhChromaIntraDir[ui]=pcCU->m_puhChromaIntraDir[uiPartOffset+ui];
682      m_puhInterDir[ui]=pcCU->m_puhInterDir[uiPartOffset+ui];
683      m_puhCbf[0][ui]=pcCU->m_puhCbf[0][uiPartOffset+ui];
684      m_puhCbf[1][ui]=pcCU->m_puhCbf[1][uiPartOffset+ui];
685      m_puhCbf[2][ui]=pcCU->m_puhCbf[2][uiPartOffset+ui];
686
687    }
688  }
689  UInt uiTmp = uhWidth*uhHeight;
690  memset( m_pcTrCoeffY , 0, sizeof(TCoeff)*uiTmp );
691#if ADAPTIVE_QP_SELECTION 
692  memset( m_pcArlCoeffY , 0, sizeof(Int)*uiTmp );
693#endif
694  memset( m_pcIPCMSampleY , 0, sizeof( Pel ) * uiTmp );
695  uiTmp >>= 2;
696  memset( m_pcTrCoeffCb, 0, sizeof(TCoeff)*uiTmp );
697  memset( m_pcTrCoeffCr, 0, sizeof(TCoeff)*uiTmp );
698#if ADAPTIVE_QP_SELECTION
699  memset( m_pcArlCoeffCb, 0, sizeof(Int)*uiTmp );
700  memset( m_pcArlCoeffCr, 0, sizeof(Int)*uiTmp );
701#endif
702  memset( m_pcIPCMSampleCb , 0, sizeof( Pel ) * uiTmp );
703  memset( m_pcIPCMSampleCr , 0, sizeof( Pel ) * uiTmp );
704  m_acCUMvField[0].clearMvField();
705  m_acCUMvField[1].clearMvField();
706
707  if(m_pcPic->getPicSym()->getInverseCUOrderMap(getAddr())*m_pcPic->getNumPartInCU()+m_uiAbsIdxInLCU<getSlice()->getSliceSegmentCurStartCUAddr())
708  {
709    // Part of this CU contains data from an older slice. Now copy in that data.
710    UInt uiMaxCuWidth=pcCU->getSlice()->getSPS()->getMaxCUWidth();
711    UInt uiMaxCuHeight=pcCU->getSlice()->getSPS()->getMaxCUHeight();
712    TComDataCU * bigCU = getPic()->getCU(getAddr());
713    Int minui = uiPartOffset;
714    minui = -minui;
715    pcCU->m_acCUMvField[0].copyTo(&m_acCUMvField[0],minui,uiPartOffset,m_uiNumPartition);
716    pcCU->m_acCUMvField[1].copyTo(&m_acCUMvField[1],minui,uiPartOffset,m_uiNumPartition);
717    UInt uiCoffOffset = uiMaxCuWidth*uiMaxCuHeight*m_uiAbsIdxInLCU/pcCU->getPic()->getNumPartInCU();
718    uiTmp = uhWidth*uhHeight;
719    for(Int i=0; i<uiTmp; i++)
720    {
721      m_pcTrCoeffY[i]=bigCU->m_pcTrCoeffY[uiCoffOffset+i];
722#if ADAPTIVE_QP_SELECTION
723      m_pcArlCoeffY[i]=bigCU->m_pcArlCoeffY[uiCoffOffset+i];
724#endif
725      m_pcIPCMSampleY[i]=bigCU->m_pcIPCMSampleY[uiCoffOffset+i];
726    }
727    uiTmp>>=2;
728    uiCoffOffset>>=2;
729    for(Int i=0; i<uiTmp; i++)
730    {
731      m_pcTrCoeffCr[i]=bigCU->m_pcTrCoeffCr[uiCoffOffset+i];
732      m_pcTrCoeffCb[i]=bigCU->m_pcTrCoeffCb[uiCoffOffset+i];
733#if ADAPTIVE_QP_SELECTION
734      m_pcArlCoeffCr[i]=bigCU->m_pcArlCoeffCr[uiCoffOffset+i];
735      m_pcArlCoeffCb[i]=bigCU->m_pcArlCoeffCb[uiCoffOffset+i];
736#endif
737      m_pcIPCMSampleCb[i]=bigCU->m_pcIPCMSampleCb[uiCoffOffset+i];
738      m_pcIPCMSampleCr[i]=bigCU->m_pcIPCMSampleCr[uiCoffOffset+i];
739    }
740  }
741
742  m_pcCULeft        = pcCU->getCULeft();
743  m_pcCUAbove       = pcCU->getCUAbove();
744  m_pcCUAboveLeft   = pcCU->getCUAboveLeft();
745  m_pcCUAboveRight  = pcCU->getCUAboveRight();
746
747  m_apcCUColocated[0] = pcCU->getCUColocated(REF_PIC_LIST_0);
748  m_apcCUColocated[1] = pcCU->getCUColocated(REF_PIC_LIST_1);
749  memcpy(m_sliceStartCU,pcCU->m_sliceStartCU+uiPartOffset,sizeof(UInt)*m_uiNumPartition);
750  memcpy(m_sliceSegmentStartCU,pcCU->m_sliceSegmentStartCU+uiPartOffset,sizeof(UInt)*m_uiNumPartition);
751}
752
753Void TComDataCU::setOutsideCUPart( UInt uiAbsPartIdx, UInt uiDepth )
754{
755  UInt uiNumPartition = m_uiNumPartition >> (uiDepth << 1);
756  UInt uiSizeInUchar = sizeof( UChar  ) * uiNumPartition;
757
758  UChar uhWidth  = g_uiMaxCUWidth  >> uiDepth;
759  UChar uhHeight = g_uiMaxCUHeight >> uiDepth;
760  memset( m_puhDepth    + uiAbsPartIdx,     uiDepth,  uiSizeInUchar );
761  memset( m_puhWidth    + uiAbsPartIdx,     uhWidth,  uiSizeInUchar );
762  memset( m_puhHeight   + uiAbsPartIdx,     uhHeight, uiSizeInUchar );
763}
764
765// --------------------------------------------------------------------------------------------------------------------
766// Copy
767// --------------------------------------------------------------------------------------------------------------------
768
769Void TComDataCU::copySubCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
770{
771  UInt uiPart = uiAbsPartIdx;
772 
773  m_pcPic              = pcCU->getPic();
774  m_pcSlice            = pcCU->getSlice();
775  m_uiCUAddr           = pcCU->getAddr();
776  m_uiAbsIdxInLCU      = uiAbsPartIdx;
777 
778  m_uiCUPelX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
779  m_uiCUPelY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
780 
781  m_skipFlag=pcCU->getSkipFlag()          + uiPart;
782
783  m_phQP=pcCU->getQP()                    + uiPart;
784  m_pePartSize = pcCU->getPartitionSize() + uiPart;
785  m_pePredMode=pcCU->getPredictionMode()  + uiPart;
786  m_CUTransquantBypass  = pcCU->getCUTransquantBypass()+uiPart;
787 
788  m_pbMergeFlag         = pcCU->getMergeFlag()        + uiPart;
789  m_puhMergeIndex       = pcCU->getMergeIndex()       + uiPart;
790
791  m_puhLumaIntraDir     = pcCU->getLumaIntraDir()     + uiPart;
792  m_puhChromaIntraDir   = pcCU->getChromaIntraDir()   + uiPart;
793  m_puhInterDir         = pcCU->getInterDir()         + uiPart;
794  m_puhTrIdx            = pcCU->getTransformIdx()     + uiPart;
795  m_puhTransformSkip[0] = pcCU->getTransformSkip(TEXT_LUMA)     + uiPart;
796  m_puhTransformSkip[1] = pcCU->getTransformSkip(TEXT_CHROMA_U) + uiPart;
797  m_puhTransformSkip[2] = pcCU->getTransformSkip(TEXT_CHROMA_V) + uiPart;
798
799  m_puhCbf[0]= pcCU->getCbf(TEXT_LUMA)            + uiPart;
800  m_puhCbf[1]= pcCU->getCbf(TEXT_CHROMA_U)        + uiPart;
801  m_puhCbf[2]= pcCU->getCbf(TEXT_CHROMA_V)        + uiPart;
802 
803  m_puhDepth=pcCU->getDepth()                     + uiPart;
804  m_puhWidth=pcCU->getWidth()                     + uiPart;
805  m_puhHeight=pcCU->getHeight()                   + uiPart;
806 
807  m_apiMVPIdx[0]=pcCU->getMVPIdx(REF_PIC_LIST_0)  + uiPart;
808  m_apiMVPIdx[1]=pcCU->getMVPIdx(REF_PIC_LIST_1)  + uiPart;
809  m_apiMVPNum[0]=pcCU->getMVPNum(REF_PIC_LIST_0)  + uiPart;
810  m_apiMVPNum[1]=pcCU->getMVPNum(REF_PIC_LIST_1)  + uiPart;
811 
812  m_pbIPCMFlag         = pcCU->getIPCMFlag()        + uiPart;
813
814  m_pcCUAboveLeft      = pcCU->getCUAboveLeft();
815  m_pcCUAboveRight     = pcCU->getCUAboveRight();
816  m_pcCUAbove          = pcCU->getCUAbove();
817  m_pcCULeft           = pcCU->getCULeft();
818 
819  m_apcCUColocated[0] = pcCU->getCUColocated(REF_PIC_LIST_0);
820  m_apcCUColocated[1] = pcCU->getCUColocated(REF_PIC_LIST_1);
821 
822  UInt uiMaxCuWidth=pcCU->getSlice()->getSPS()->getMaxCUWidth();
823  UInt uiMaxCuHeight=pcCU->getSlice()->getSPS()->getMaxCUHeight();
824 
825  UInt uiCoffOffset = uiMaxCuWidth*uiMaxCuHeight*uiAbsPartIdx/pcCU->getPic()->getNumPartInCU();
826 
827  m_pcTrCoeffY = pcCU->getCoeffY() + uiCoffOffset;
828#if ADAPTIVE_QP_SELECTION
829  m_pcArlCoeffY= pcCU->getArlCoeffY() + uiCoffOffset; 
830#endif
831  m_pcIPCMSampleY = pcCU->getPCMSampleY() + uiCoffOffset;
832
833  uiCoffOffset >>=2;
834  m_pcTrCoeffCb=pcCU->getCoeffCb() + uiCoffOffset;
835  m_pcTrCoeffCr=pcCU->getCoeffCr() + uiCoffOffset;
836#if ADAPTIVE_QP_SELECTION 
837  m_pcArlCoeffCb=pcCU->getArlCoeffCb() + uiCoffOffset;
838  m_pcArlCoeffCr=pcCU->getArlCoeffCr() + uiCoffOffset;
839#endif
840  m_pcIPCMSampleCb = pcCU->getPCMSampleCb() + uiCoffOffset;
841  m_pcIPCMSampleCr = pcCU->getPCMSampleCr() + uiCoffOffset;
842
843  m_acCUMvField[0].linkToWithOffset( pcCU->getCUMvField(REF_PIC_LIST_0), uiPart );
844  m_acCUMvField[1].linkToWithOffset( pcCU->getCUMvField(REF_PIC_LIST_1), uiPart );
845  memcpy(m_sliceStartCU,pcCU->m_sliceStartCU+uiPart,sizeof(UInt)*m_uiNumPartition);
846  memcpy(m_sliceSegmentStartCU,pcCU->m_sliceSegmentStartCU+uiPart,sizeof(UInt)*m_uiNumPartition);
847}
848
849// Copy inter prediction info from the biggest CU
850Void TComDataCU::copyInterPredInfoFrom    ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList )
851{
852  m_pcPic              = pcCU->getPic();
853  m_pcSlice            = pcCU->getSlice();
854  m_uiCUAddr           = pcCU->getAddr();
855  m_uiAbsIdxInLCU      = uiAbsPartIdx;
856 
857  Int iRastPartIdx     = g_auiZscanToRaster[uiAbsPartIdx];
858  m_uiCUPelX           = pcCU->getCUPelX() + m_pcPic->getMinCUWidth ()*( iRastPartIdx % m_pcPic->getNumPartInWidth() );
859  m_uiCUPelY           = pcCU->getCUPelY() + m_pcPic->getMinCUHeight()*( iRastPartIdx / m_pcPic->getNumPartInWidth() );
860 
861  m_pcCUAboveLeft      = pcCU->getCUAboveLeft();
862  m_pcCUAboveRight     = pcCU->getCUAboveRight();
863  m_pcCUAbove          = pcCU->getCUAbove();
864  m_pcCULeft           = pcCU->getCULeft();
865 
866  m_apcCUColocated[0]  = pcCU->getCUColocated(REF_PIC_LIST_0);
867  m_apcCUColocated[1]  = pcCU->getCUColocated(REF_PIC_LIST_1);
868 
869  m_skipFlag           = pcCU->getSkipFlag ()             + uiAbsPartIdx;
870
871  m_pePartSize         = pcCU->getPartitionSize ()        + uiAbsPartIdx;
872  m_pePredMode         = pcCU->getPredictionMode()        + uiAbsPartIdx;
873  m_CUTransquantBypass = pcCU->getCUTransquantBypass()    + uiAbsPartIdx;
874  m_puhInterDir        = pcCU->getInterDir      ()        + uiAbsPartIdx;
875 
876  m_puhDepth           = pcCU->getDepth ()                + uiAbsPartIdx;
877  m_puhWidth           = pcCU->getWidth ()                + uiAbsPartIdx;
878  m_puhHeight          = pcCU->getHeight()                + uiAbsPartIdx;
879 
880  m_pbMergeFlag        = pcCU->getMergeFlag()             + uiAbsPartIdx;
881  m_puhMergeIndex      = pcCU->getMergeIndex()            + uiAbsPartIdx;
882
883  m_apiMVPIdx[eRefPicList] = pcCU->getMVPIdx(eRefPicList) + uiAbsPartIdx;
884  m_apiMVPNum[eRefPicList] = pcCU->getMVPNum(eRefPicList) + uiAbsPartIdx;
885 
886  m_acCUMvField[ eRefPicList ].linkToWithOffset( pcCU->getCUMvField(eRefPicList), uiAbsPartIdx );
887
888  memcpy(m_sliceStartCU,pcCU->m_sliceStartCU+uiAbsPartIdx,sizeof(UInt)*m_uiNumPartition);
889  memcpy(m_sliceSegmentStartCU,pcCU->m_sliceSegmentStartCU+uiAbsPartIdx,sizeof(UInt)*m_uiNumPartition);
890}
891
892// Copy small CU to bigger CU.
893// One of quarter parts overwritten by predicted sub part.
894Void TComDataCU::copyPartFrom( TComDataCU* pcCU, UInt uiPartUnitIdx, UInt uiDepth )
895{
896  assert( uiPartUnitIdx<4 );
897 
898  m_dTotalCost         += pcCU->getTotalCost();
899  m_uiTotalDistortion  += pcCU->getTotalDistortion();
900  m_uiTotalBits        += pcCU->getTotalBits();
901 
902  UInt uiOffset         = pcCU->getTotalNumPart()*uiPartUnitIdx;
903 
904  UInt uiNumPartition = pcCU->getTotalNumPart();
905  Int iSizeInUchar  = sizeof( UChar ) * uiNumPartition;
906  Int iSizeInBool   = sizeof( Bool  ) * uiNumPartition;
907 
908  Int sizeInChar  = sizeof( Char ) * uiNumPartition;
909  memcpy( m_skipFlag   + uiOffset, pcCU->getSkipFlag(),       sizeof( *m_skipFlag )   * uiNumPartition );
910  memcpy( m_phQP       + uiOffset, pcCU->getQP(),             sizeInChar                        );
911  memcpy( m_pePartSize + uiOffset, pcCU->getPartitionSize(),  sizeof( *m_pePartSize ) * uiNumPartition );
912  memcpy( m_pePredMode + uiOffset, pcCU->getPredictionMode(), sizeof( *m_pePredMode ) * uiNumPartition );
913  memcpy( m_CUTransquantBypass + uiOffset, pcCU->getCUTransquantBypass(), sizeof( *m_CUTransquantBypass ) * uiNumPartition );
914  memcpy( m_pbMergeFlag         + uiOffset, pcCU->getMergeFlag(),         iSizeInBool  );
915  memcpy( m_puhMergeIndex       + uiOffset, pcCU->getMergeIndex(),        iSizeInUchar );
916  memcpy( m_puhLumaIntraDir     + uiOffset, pcCU->getLumaIntraDir(),      iSizeInUchar );
917  memcpy( m_puhChromaIntraDir   + uiOffset, pcCU->getChromaIntraDir(),    iSizeInUchar );
918  memcpy( m_puhInterDir         + uiOffset, pcCU->getInterDir(),          iSizeInUchar );
919  memcpy( m_puhTrIdx            + uiOffset, pcCU->getTransformIdx(),      iSizeInUchar );
920  memcpy( m_puhTransformSkip[0] + uiOffset, pcCU->getTransformSkip(TEXT_LUMA),     iSizeInUchar );
921  memcpy( m_puhTransformSkip[1] + uiOffset, pcCU->getTransformSkip(TEXT_CHROMA_U), iSizeInUchar );
922  memcpy( m_puhTransformSkip[2] + uiOffset, pcCU->getTransformSkip(TEXT_CHROMA_V), iSizeInUchar );
923
924  memcpy( m_puhCbf[0] + uiOffset, pcCU->getCbf(TEXT_LUMA)    , iSizeInUchar );
925  memcpy( m_puhCbf[1] + uiOffset, pcCU->getCbf(TEXT_CHROMA_U), iSizeInUchar );
926  memcpy( m_puhCbf[2] + uiOffset, pcCU->getCbf(TEXT_CHROMA_V), iSizeInUchar );
927 
928  memcpy( m_puhDepth  + uiOffset, pcCU->getDepth(),  iSizeInUchar );
929  memcpy( m_puhWidth  + uiOffset, pcCU->getWidth(),  iSizeInUchar );
930  memcpy( m_puhHeight + uiOffset, pcCU->getHeight(), iSizeInUchar );
931 
932  memcpy( m_apiMVPIdx[0] + uiOffset, pcCU->getMVPIdx(REF_PIC_LIST_0), iSizeInUchar );
933  memcpy( m_apiMVPIdx[1] + uiOffset, pcCU->getMVPIdx(REF_PIC_LIST_1), iSizeInUchar );
934  memcpy( m_apiMVPNum[0] + uiOffset, pcCU->getMVPNum(REF_PIC_LIST_0), iSizeInUchar );
935  memcpy( m_apiMVPNum[1] + uiOffset, pcCU->getMVPNum(REF_PIC_LIST_1), iSizeInUchar );
936 
937  memcpy( m_pbIPCMFlag + uiOffset, pcCU->getIPCMFlag(), iSizeInBool );
938
939  m_pcCUAboveLeft      = pcCU->getCUAboveLeft();
940  m_pcCUAboveRight     = pcCU->getCUAboveRight();
941  m_pcCUAbove          = pcCU->getCUAbove();
942  m_pcCULeft           = pcCU->getCULeft();
943 
944  m_apcCUColocated[0] = pcCU->getCUColocated(REF_PIC_LIST_0);
945  m_apcCUColocated[1] = pcCU->getCUColocated(REF_PIC_LIST_1);
946 
947  m_acCUMvField[0].copyFrom( pcCU->getCUMvField( REF_PIC_LIST_0 ), pcCU->getTotalNumPart(), uiOffset );
948  m_acCUMvField[1].copyFrom( pcCU->getCUMvField( REF_PIC_LIST_1 ), pcCU->getTotalNumPart(), uiOffset );
949 
950  UInt uiTmp  = g_uiMaxCUWidth*g_uiMaxCUHeight >> (uiDepth<<1);
951  UInt uiTmp2 = uiPartUnitIdx*uiTmp;
952  memcpy( m_pcTrCoeffY  + uiTmp2, pcCU->getCoeffY(),  sizeof(TCoeff)*uiTmp );
953#if ADAPTIVE_QP_SELECTION
954  memcpy( m_pcArlCoeffY  + uiTmp2, pcCU->getArlCoeffY(),  sizeof(Int)*uiTmp );
955#endif
956  memcpy( m_pcIPCMSampleY + uiTmp2 , pcCU->getPCMSampleY(), sizeof(Pel) * uiTmp );
957
958  uiTmp >>= 2; uiTmp2>>= 2;
959  memcpy( m_pcTrCoeffCb + uiTmp2, pcCU->getCoeffCb(), sizeof(TCoeff)*uiTmp );
960  memcpy( m_pcTrCoeffCr + uiTmp2, pcCU->getCoeffCr(), sizeof(TCoeff)*uiTmp );
961#if ADAPTIVE_QP_SELECTION
962  memcpy( m_pcArlCoeffCb + uiTmp2, pcCU->getArlCoeffCb(), sizeof(Int)*uiTmp );
963  memcpy( m_pcArlCoeffCr + uiTmp2, pcCU->getArlCoeffCr(), sizeof(Int)*uiTmp );
964#endif
965  memcpy( m_pcIPCMSampleCb + uiTmp2 , pcCU->getPCMSampleCb(), sizeof(Pel) * uiTmp );
966  memcpy( m_pcIPCMSampleCr + uiTmp2 , pcCU->getPCMSampleCr(), sizeof(Pel) * uiTmp );
967  m_uiTotalBins += pcCU->getTotalBins();
968  memcpy( m_sliceStartCU        + uiOffset, pcCU->m_sliceStartCU,        sizeof( UInt ) * uiNumPartition  );
969  memcpy( m_sliceSegmentStartCU + uiOffset, pcCU->m_sliceSegmentStartCU, sizeof( UInt ) * uiNumPartition  );
970}
971
972// Copy current predicted part to a CU in picture.
973// It is used to predict for next part
974Void TComDataCU::copyToPic( UChar uhDepth )
975{
976  TComDataCU*& rpcCU = m_pcPic->getCU( m_uiCUAddr );
977 
978  rpcCU->getTotalCost()       = m_dTotalCost;
979  rpcCU->getTotalDistortion() = m_uiTotalDistortion;
980  rpcCU->getTotalBits()       = m_uiTotalBits;
981 
982  Int iSizeInUchar  = sizeof( UChar ) * m_uiNumPartition;
983  Int iSizeInBool   = sizeof( Bool  ) * m_uiNumPartition;
984 
985  Int sizeInChar  = sizeof( Char ) * m_uiNumPartition;
986
987  memcpy( rpcCU->getSkipFlag() + m_uiAbsIdxInLCU, m_skipFlag, sizeof( *m_skipFlag ) * m_uiNumPartition );
988
989  memcpy( rpcCU->getQP() + m_uiAbsIdxInLCU, m_phQP, sizeInChar  );
990
991  memcpy( rpcCU->getPartitionSize()  + m_uiAbsIdxInLCU, m_pePartSize, sizeof( *m_pePartSize ) * m_uiNumPartition );
992  memcpy( rpcCU->getPredictionMode() + m_uiAbsIdxInLCU, m_pePredMode, sizeof( *m_pePredMode ) * m_uiNumPartition );
993  memcpy( rpcCU->getCUTransquantBypass()+ m_uiAbsIdxInLCU, m_CUTransquantBypass, sizeof( *m_CUTransquantBypass ) * m_uiNumPartition );
994  memcpy( rpcCU->getMergeFlag()         + m_uiAbsIdxInLCU, m_pbMergeFlag,         iSizeInBool  );
995  memcpy( rpcCU->getMergeIndex()        + m_uiAbsIdxInLCU, m_puhMergeIndex,       iSizeInUchar );
996  memcpy( rpcCU->getLumaIntraDir()      + m_uiAbsIdxInLCU, m_puhLumaIntraDir,     iSizeInUchar );
997  memcpy( rpcCU->getChromaIntraDir()    + m_uiAbsIdxInLCU, m_puhChromaIntraDir,   iSizeInUchar );
998  memcpy( rpcCU->getInterDir()          + m_uiAbsIdxInLCU, m_puhInterDir,         iSizeInUchar );
999  memcpy( rpcCU->getTransformIdx()      + m_uiAbsIdxInLCU, m_puhTrIdx,            iSizeInUchar );
1000  memcpy( rpcCU->getTransformSkip(TEXT_LUMA)     + m_uiAbsIdxInLCU, m_puhTransformSkip[0], iSizeInUchar );
1001  memcpy( rpcCU->getTransformSkip(TEXT_CHROMA_U) + m_uiAbsIdxInLCU, m_puhTransformSkip[1], iSizeInUchar );
1002  memcpy( rpcCU->getTransformSkip(TEXT_CHROMA_V) + m_uiAbsIdxInLCU, m_puhTransformSkip[2], iSizeInUchar );
1003
1004  memcpy( rpcCU->getCbf(TEXT_LUMA)     + m_uiAbsIdxInLCU, m_puhCbf[0], iSizeInUchar );
1005  memcpy( rpcCU->getCbf(TEXT_CHROMA_U) + m_uiAbsIdxInLCU, m_puhCbf[1], iSizeInUchar );
1006  memcpy( rpcCU->getCbf(TEXT_CHROMA_V) + m_uiAbsIdxInLCU, m_puhCbf[2], iSizeInUchar );
1007 
1008  memcpy( rpcCU->getDepth()  + m_uiAbsIdxInLCU, m_puhDepth,  iSizeInUchar );
1009  memcpy( rpcCU->getWidth()  + m_uiAbsIdxInLCU, m_puhWidth,  iSizeInUchar );
1010  memcpy( rpcCU->getHeight() + m_uiAbsIdxInLCU, m_puhHeight, iSizeInUchar );
1011 
1012  memcpy( rpcCU->getMVPIdx(REF_PIC_LIST_0) + m_uiAbsIdxInLCU, m_apiMVPIdx[0], iSizeInUchar );
1013  memcpy( rpcCU->getMVPIdx(REF_PIC_LIST_1) + m_uiAbsIdxInLCU, m_apiMVPIdx[1], iSizeInUchar );
1014  memcpy( rpcCU->getMVPNum(REF_PIC_LIST_0) + m_uiAbsIdxInLCU, m_apiMVPNum[0], iSizeInUchar );
1015  memcpy( rpcCU->getMVPNum(REF_PIC_LIST_1) + m_uiAbsIdxInLCU, m_apiMVPNum[1], iSizeInUchar );
1016 
1017  m_acCUMvField[0].copyTo( rpcCU->getCUMvField( REF_PIC_LIST_0 ), m_uiAbsIdxInLCU );
1018  m_acCUMvField[1].copyTo( rpcCU->getCUMvField( REF_PIC_LIST_1 ), m_uiAbsIdxInLCU );
1019 
1020  memcpy( rpcCU->getIPCMFlag() + m_uiAbsIdxInLCU, m_pbIPCMFlag,         iSizeInBool  );
1021
1022  UInt uiTmp  = (g_uiMaxCUWidth*g_uiMaxCUHeight)>>(uhDepth<<1);
1023  UInt uiTmp2 = m_uiAbsIdxInLCU*m_pcPic->getMinCUWidth()*m_pcPic->getMinCUHeight();
1024  memcpy( rpcCU->getCoeffY()  + uiTmp2, m_pcTrCoeffY,  sizeof(TCoeff)*uiTmp  );
1025#if ADAPTIVE_QP_SELECTION 
1026  memcpy( rpcCU->getArlCoeffY()  + uiTmp2, m_pcArlCoeffY,  sizeof(Int)*uiTmp  );
1027#endif
1028  memcpy( rpcCU->getPCMSampleY() + uiTmp2 , m_pcIPCMSampleY, sizeof(Pel)*uiTmp );
1029
1030  uiTmp >>= 2; uiTmp2 >>= 2;
1031  memcpy( rpcCU->getCoeffCb() + uiTmp2, m_pcTrCoeffCb, sizeof(TCoeff)*uiTmp  );
1032  memcpy( rpcCU->getCoeffCr() + uiTmp2, m_pcTrCoeffCr, sizeof(TCoeff)*uiTmp  );
1033#if ADAPTIVE_QP_SELECTION
1034  memcpy( rpcCU->getArlCoeffCb() + uiTmp2, m_pcArlCoeffCb, sizeof(Int)*uiTmp  );
1035  memcpy( rpcCU->getArlCoeffCr() + uiTmp2, m_pcArlCoeffCr, sizeof(Int)*uiTmp  );
1036#endif
1037  memcpy( rpcCU->getPCMSampleCb() + uiTmp2 , m_pcIPCMSampleCb, sizeof( Pel ) * uiTmp );
1038  memcpy( rpcCU->getPCMSampleCr() + uiTmp2 , m_pcIPCMSampleCr, sizeof( Pel ) * uiTmp );
1039  rpcCU->getTotalBins() = m_uiTotalBins;
1040  memcpy( rpcCU->m_sliceStartCU        + m_uiAbsIdxInLCU, m_sliceStartCU,        sizeof( UInt ) * m_uiNumPartition  );
1041  memcpy( rpcCU->m_sliceSegmentStartCU + m_uiAbsIdxInLCU, m_sliceSegmentStartCU, sizeof( UInt ) * m_uiNumPartition  );
1042}
1043
1044Void TComDataCU::copyToPic( UChar uhDepth, UInt uiPartIdx, UInt uiPartDepth )
1045{
1046  TComDataCU*&  rpcCU       = m_pcPic->getCU( m_uiCUAddr );
1047  UInt          uiQNumPart  = m_uiNumPartition>>(uiPartDepth<<1);
1048 
1049  UInt uiPartStart          = uiPartIdx*uiQNumPart;
1050  UInt uiPartOffset         = m_uiAbsIdxInLCU + uiPartStart;
1051 
1052  rpcCU->getTotalCost()       = m_dTotalCost;
1053  rpcCU->getTotalDistortion() = m_uiTotalDistortion;
1054  rpcCU->getTotalBits()       = m_uiTotalBits;
1055 
1056  Int iSizeInUchar  = sizeof( UChar  ) * uiQNumPart;
1057  Int iSizeInBool   = sizeof( Bool   ) * uiQNumPart;
1058 
1059  Int sizeInChar  = sizeof( Char ) * uiQNumPart;
1060  memcpy( rpcCU->getSkipFlag()       + uiPartOffset, m_skipFlag,   sizeof( *m_skipFlag )   * uiQNumPart );
1061
1062  memcpy( rpcCU->getQP() + uiPartOffset, m_phQP, sizeInChar );
1063  memcpy( rpcCU->getPartitionSize()  + uiPartOffset, m_pePartSize, sizeof( *m_pePartSize ) * uiQNumPart );
1064  memcpy( rpcCU->getPredictionMode() + uiPartOffset, m_pePredMode, sizeof( *m_pePredMode ) * uiQNumPart );
1065  memcpy( rpcCU->getCUTransquantBypass()+ uiPartOffset, m_CUTransquantBypass, sizeof( *m_CUTransquantBypass ) * uiQNumPart );
1066  memcpy( rpcCU->getMergeFlag()         + uiPartOffset, m_pbMergeFlag,         iSizeInBool  );
1067  memcpy( rpcCU->getMergeIndex()        + uiPartOffset, m_puhMergeIndex,       iSizeInUchar );
1068  memcpy( rpcCU->getLumaIntraDir()      + uiPartOffset, m_puhLumaIntraDir,     iSizeInUchar );
1069  memcpy( rpcCU->getChromaIntraDir()    + uiPartOffset, m_puhChromaIntraDir,   iSizeInUchar );
1070  memcpy( rpcCU->getInterDir()          + uiPartOffset, m_puhInterDir,         iSizeInUchar );
1071  memcpy( rpcCU->getTransformIdx()      + uiPartOffset, m_puhTrIdx,            iSizeInUchar );
1072  memcpy( rpcCU->getTransformSkip(TEXT_LUMA)     + uiPartOffset, m_puhTransformSkip[0], iSizeInUchar );
1073  memcpy( rpcCU->getTransformSkip(TEXT_CHROMA_U) + uiPartOffset, m_puhTransformSkip[1], iSizeInUchar );
1074  memcpy( rpcCU->getTransformSkip(TEXT_CHROMA_V) + uiPartOffset, m_puhTransformSkip[2], iSizeInUchar );
1075  memcpy( rpcCU->getCbf(TEXT_LUMA)     + uiPartOffset, m_puhCbf[0], iSizeInUchar );
1076  memcpy( rpcCU->getCbf(TEXT_CHROMA_U) + uiPartOffset, m_puhCbf[1], iSizeInUchar );
1077  memcpy( rpcCU->getCbf(TEXT_CHROMA_V) + uiPartOffset, m_puhCbf[2], iSizeInUchar );
1078 
1079  memcpy( rpcCU->getDepth()  + uiPartOffset, m_puhDepth,  iSizeInUchar );
1080  memcpy( rpcCU->getWidth()  + uiPartOffset, m_puhWidth,  iSizeInUchar );
1081  memcpy( rpcCU->getHeight() + uiPartOffset, m_puhHeight, iSizeInUchar );
1082 
1083  memcpy( rpcCU->getMVPIdx(REF_PIC_LIST_0) + uiPartOffset, m_apiMVPIdx[0], iSizeInUchar );
1084  memcpy( rpcCU->getMVPIdx(REF_PIC_LIST_1) + uiPartOffset, m_apiMVPIdx[1], iSizeInUchar );
1085  memcpy( rpcCU->getMVPNum(REF_PIC_LIST_0) + uiPartOffset, m_apiMVPNum[0], iSizeInUchar );
1086  memcpy( rpcCU->getMVPNum(REF_PIC_LIST_1) + uiPartOffset, m_apiMVPNum[1], iSizeInUchar );
1087  m_acCUMvField[0].copyTo( rpcCU->getCUMvField( REF_PIC_LIST_0 ), m_uiAbsIdxInLCU, uiPartStart, uiQNumPart );
1088  m_acCUMvField[1].copyTo( rpcCU->getCUMvField( REF_PIC_LIST_1 ), m_uiAbsIdxInLCU, uiPartStart, uiQNumPart );
1089 
1090  memcpy( rpcCU->getIPCMFlag() + uiPartOffset, m_pbIPCMFlag,         iSizeInBool  );
1091
1092  UInt uiTmp  = (g_uiMaxCUWidth*g_uiMaxCUHeight)>>((uhDepth+uiPartDepth)<<1);
1093  UInt uiTmp2 = uiPartOffset*m_pcPic->getMinCUWidth()*m_pcPic->getMinCUHeight();
1094  memcpy( rpcCU->getCoeffY()  + uiTmp2, m_pcTrCoeffY,  sizeof(TCoeff)*uiTmp  );
1095#if ADAPTIVE_QP_SELECTION
1096  memcpy( rpcCU->getArlCoeffY()  + uiTmp2, m_pcArlCoeffY,  sizeof(Int)*uiTmp  );
1097#endif
1098 
1099  memcpy( rpcCU->getPCMSampleY() + uiTmp2 , m_pcIPCMSampleY, sizeof( Pel ) * uiTmp );
1100
1101  uiTmp >>= 2; uiTmp2 >>= 2;
1102  memcpy( rpcCU->getCoeffCb() + uiTmp2, m_pcTrCoeffCb, sizeof(TCoeff)*uiTmp  );
1103  memcpy( rpcCU->getCoeffCr() + uiTmp2, m_pcTrCoeffCr, sizeof(TCoeff)*uiTmp  );
1104#if ADAPTIVE_QP_SELECTION
1105  memcpy( rpcCU->getArlCoeffCb() + uiTmp2, m_pcArlCoeffCb, sizeof(Int)*uiTmp  );
1106  memcpy( rpcCU->getArlCoeffCr() + uiTmp2, m_pcArlCoeffCr, sizeof(Int)*uiTmp  );
1107#endif
1108
1109  memcpy( rpcCU->getPCMSampleCb() + uiTmp2 , m_pcIPCMSampleCb, sizeof( Pel ) * uiTmp );
1110  memcpy( rpcCU->getPCMSampleCr() + uiTmp2 , m_pcIPCMSampleCr, sizeof( Pel ) * uiTmp );
1111  rpcCU->getTotalBins() = m_uiTotalBins;
1112  memcpy( rpcCU->m_sliceStartCU        + uiPartOffset, m_sliceStartCU,        sizeof( UInt ) * uiQNumPart  );
1113  memcpy( rpcCU->m_sliceSegmentStartCU + uiPartOffset, m_sliceSegmentStartCU, sizeof( UInt ) * uiQNumPart  );
1114}
1115
1116// --------------------------------------------------------------------------------------------------------------------
1117// Other public functions
1118// --------------------------------------------------------------------------------------------------------------------
1119
1120TComDataCU* TComDataCU::getPULeft( UInt& uiLPartUnitIdx, 
1121                                   UInt uiCurrPartUnitIdx, 
1122                                   Bool bEnforceSliceRestriction, 
1123                                   Bool bEnforceTileRestriction )
1124{
1125  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1126  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_uiAbsIdxInLCU];
1127  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
1128 
1129  if ( !RasterAddress::isZeroCol( uiAbsPartIdx, uiNumPartInCUWidth ) )
1130  {
1131    uiLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - 1 ];
1132    if ( RasterAddress::isEqualCol( uiAbsPartIdx, uiAbsZorderCUIdx, uiNumPartInCUWidth ) )
1133    {
1134      return m_pcPic->getCU( getAddr() );
1135    }
1136    else
1137    {
1138      uiLPartUnitIdx -= m_uiAbsIdxInLCU;
1139      return this;
1140    }
1141  }
1142 
1143  uiLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + uiNumPartInCUWidth - 1 ];
1144
1145
1146  if ( (bEnforceSliceRestriction && (m_pcCULeft==NULL || m_pcCULeft->getSlice()==NULL || m_pcCULeft->getSCUAddr()+uiLPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)))
1147      ||
1148       (bEnforceTileRestriction && ( m_pcCULeft==NULL || m_pcCULeft->getSlice()==NULL || (m_pcPic->getPicSym()->getTileIdxMap( m_pcCULeft->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))  )  )
1149      )
1150  {
1151    return NULL;
1152  }
1153  return m_pcCULeft;
1154}
1155
1156TComDataCU* TComDataCU::getPUAbove( UInt& uiAPartUnitIdx,
1157                                    UInt uiCurrPartUnitIdx, 
1158                                    Bool bEnforceSliceRestriction, 
1159                                    Bool planarAtLCUBoundary ,
1160                                    Bool bEnforceTileRestriction )
1161{
1162  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1163  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_uiAbsIdxInLCU];
1164  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
1165 
1166  if ( !RasterAddress::isZeroRow( uiAbsPartIdx, uiNumPartInCUWidth ) )
1167  {
1168    uiAPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - uiNumPartInCUWidth ];
1169    if ( RasterAddress::isEqualRow( uiAbsPartIdx, uiAbsZorderCUIdx, uiNumPartInCUWidth ) )
1170    {
1171      return m_pcPic->getCU( getAddr() );
1172    }
1173    else
1174    {
1175      uiAPartUnitIdx -= m_uiAbsIdxInLCU;
1176      return this;
1177    }
1178  }
1179
1180  if(planarAtLCUBoundary)
1181  {
1182    return NULL;
1183  }
1184 
1185  uiAPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + m_pcPic->getNumPartInCU() - uiNumPartInCUWidth ];
1186
1187  if ( (bEnforceSliceRestriction && (m_pcCUAbove==NULL || m_pcCUAbove->getSlice()==NULL || m_pcCUAbove->getSCUAddr()+uiAPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)))
1188      ||
1189       (bEnforceTileRestriction &&(m_pcCUAbove==NULL || m_pcCUAbove->getSlice()==NULL || (m_pcPic->getPicSym()->getTileIdxMap( m_pcCUAbove->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))))
1190      )
1191  {
1192    return NULL;
1193  }
1194  return m_pcCUAbove;
1195}
1196
1197TComDataCU* TComDataCU::getPUAboveLeft( UInt& uiALPartUnitIdx, UInt uiCurrPartUnitIdx, Bool bEnforceSliceRestriction )
1198{
1199  UInt uiAbsPartIdx       = g_auiZscanToRaster[uiCurrPartUnitIdx];
1200  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[m_uiAbsIdxInLCU];
1201  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
1202 
1203  if ( !RasterAddress::isZeroCol( uiAbsPartIdx, uiNumPartInCUWidth ) )
1204  {
1205    if ( !RasterAddress::isZeroRow( uiAbsPartIdx, uiNumPartInCUWidth ) )
1206    {
1207      uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - uiNumPartInCUWidth - 1 ];
1208      if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdx, uiAbsZorderCUIdx, uiNumPartInCUWidth ) )
1209      {
1210        return m_pcPic->getCU( getAddr() );
1211      }
1212      else
1213      {
1214        uiALPartUnitIdx -= m_uiAbsIdxInLCU;
1215        return this;
1216      }
1217    }
1218    uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx + getPic()->getNumPartInCU() - uiNumPartInCUWidth - 1 ];
1219    if ( (bEnforceSliceRestriction && (m_pcCUAbove==NULL || m_pcCUAbove->getSlice()==NULL ||
1220       m_pcCUAbove->getSCUAddr()+uiALPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1221       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCUAbove->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1222       ))
1223     )
1224    {
1225      return NULL;
1226    }
1227    return m_pcCUAbove;
1228  }
1229 
1230  if ( !RasterAddress::isZeroRow( uiAbsPartIdx, uiNumPartInCUWidth ) )
1231  {
1232    uiALPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdx - 1 ];
1233    if ( (bEnforceSliceRestriction && (m_pcCULeft==NULL || m_pcCULeft->getSlice()==NULL || 
1234       m_pcCULeft->getSCUAddr()+uiALPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1235       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCULeft->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1236       ))
1237     )
1238    {
1239      return NULL;
1240    }
1241    return m_pcCULeft;
1242  }
1243 
1244  uiALPartUnitIdx = g_auiRasterToZscan[ m_pcPic->getNumPartInCU() - 1 ];
1245  if ( (bEnforceSliceRestriction && (m_pcCUAboveLeft==NULL || m_pcCUAboveLeft->getSlice()==NULL ||
1246       m_pcCUAboveLeft->getSCUAddr()+uiALPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1247       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCUAboveLeft->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1248       ))
1249     )
1250  {
1251    return NULL;
1252  }
1253  return m_pcCUAboveLeft;
1254}
1255
1256TComDataCU* TComDataCU::getPUAboveRight( UInt& uiARPartUnitIdx, UInt uiCurrPartUnitIdx, Bool bEnforceSliceRestriction )
1257{
1258  UInt uiAbsPartIdxRT     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1259  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[ m_uiAbsIdxInLCU ] + m_puhWidth[0] / m_pcPic->getMinCUWidth() - 1;
1260  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
1261 
1262#if REPN_FORMAT_IN_VPS
1263  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxRT] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getPicWidthInLumaSamples() )
1264#else
1265  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxRT] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
1266#endif
1267  {
1268    uiARPartUnitIdx = MAX_UINT;
1269    return NULL;
1270  }
1271 
1272  if ( RasterAddress::lessThanCol( uiAbsPartIdxRT, uiNumPartInCUWidth - 1, uiNumPartInCUWidth ) )
1273  {
1274    if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, uiNumPartInCUWidth ) )
1275    {
1276      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxRT - uiNumPartInCUWidth + 1 ] )
1277      {
1278        uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT - uiNumPartInCUWidth + 1 ];
1279        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxRT, uiAbsZorderCUIdx, uiNumPartInCUWidth ) )
1280        {
1281          return m_pcPic->getCU( getAddr() );
1282        }
1283        else
1284        {
1285          uiARPartUnitIdx -= m_uiAbsIdxInLCU;
1286          return this;
1287        }
1288      }
1289      uiARPartUnitIdx = MAX_UINT;
1290      return NULL;
1291    }
1292    uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT + m_pcPic->getNumPartInCU() - uiNumPartInCUWidth + 1 ];
1293    if ( (bEnforceSliceRestriction && (m_pcCUAbove==NULL || m_pcCUAbove->getSlice()==NULL ||
1294       m_pcCUAbove->getSCUAddr()+uiARPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1295       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCUAbove->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1296       ))
1297     )
1298    {
1299      return NULL;
1300    }
1301    return m_pcCUAbove;
1302  }
1303 
1304  if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, uiNumPartInCUWidth ) )
1305  {
1306    uiARPartUnitIdx = MAX_UINT;
1307    return NULL;
1308  }
1309 
1310  uiARPartUnitIdx = g_auiRasterToZscan[ m_pcPic->getNumPartInCU() - uiNumPartInCUWidth ];
1311  if ( (bEnforceSliceRestriction && (m_pcCUAboveRight==NULL || m_pcCUAboveRight->getSlice()==NULL ||
1312       m_pcPic->getPicSym()->getInverseCUOrderMap( m_pcCUAboveRight->getAddr()) > m_pcPic->getPicSym()->getInverseCUOrderMap( getAddr()) ||
1313       m_pcCUAboveRight->getSCUAddr()+uiARPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1314       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCUAboveRight->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1315       ))
1316     )
1317  {
1318    return NULL;
1319  }
1320  return m_pcCUAboveRight;
1321}
1322
1323TComDataCU* TComDataCU::getPUBelowLeft( UInt& uiBLPartUnitIdx, UInt uiCurrPartUnitIdx, Bool bEnforceSliceRestriction )
1324{
1325  UInt uiAbsPartIdxLB     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1326  UInt uiAbsZorderCUIdxLB = g_auiZscanToRaster[ m_uiAbsIdxInLCU ] + (m_puhHeight[0] / m_pcPic->getMinCUHeight() - 1)*m_pcPic->getNumPartInWidth();
1327  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
1328
1329#if REPN_FORMAT_IN_VPS
1330  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxLB] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getPicHeightInLumaSamples() )
1331#else
1332  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxLB] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
1333#endif
1334  {
1335    uiBLPartUnitIdx = MAX_UINT;
1336    return NULL;
1337  }
1338 
1339  if ( RasterAddress::lessThanRow( uiAbsPartIdxLB, m_pcPic->getNumPartInHeight() - 1, uiNumPartInCUWidth ) )
1340  {
1341    if ( !RasterAddress::isZeroCol( uiAbsPartIdxLB, uiNumPartInCUWidth ) )
1342    {
1343      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxLB + uiNumPartInCUWidth - 1 ] )
1344      {
1345        uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + uiNumPartInCUWidth - 1 ];
1346        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxLB, uiAbsZorderCUIdxLB, uiNumPartInCUWidth ) )
1347        {
1348          return m_pcPic->getCU( getAddr() );
1349        }
1350        else
1351        {
1352          uiBLPartUnitIdx -= m_uiAbsIdxInLCU;
1353          return this;
1354        }
1355      }
1356      uiBLPartUnitIdx = MAX_UINT;
1357      return NULL;
1358    }
1359    uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + uiNumPartInCUWidth*2 - 1 ];
1360    if ( (bEnforceSliceRestriction && (m_pcCULeft==NULL || m_pcCULeft->getSlice()==NULL || 
1361       m_pcCULeft->getSCUAddr()+uiBLPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1362       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCULeft->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1363       ))
1364     )
1365    {
1366      return NULL;
1367    }
1368    return m_pcCULeft;
1369  }
1370 
1371  uiBLPartUnitIdx = MAX_UINT;
1372  return NULL;
1373}
1374
1375TComDataCU* TComDataCU::getPUBelowLeftAdi(UInt& uiBLPartUnitIdx,  UInt uiCurrPartUnitIdx, UInt uiPartUnitOffset, Bool bEnforceSliceRestriction )
1376{
1377  UInt uiAbsPartIdxLB     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1378  UInt uiAbsZorderCUIdxLB = g_auiZscanToRaster[ m_uiAbsIdxInLCU ] + ((m_puhHeight[0] / m_pcPic->getMinCUHeight()) - 1)*m_pcPic->getNumPartInWidth();
1379  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
1380 
1381#if REPN_FORMAT_IN_VPS
1382  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxLB] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getPicHeightInLumaSamples())
1383#else
1384  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxLB] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples())
1385#endif
1386  {
1387    uiBLPartUnitIdx = MAX_UINT;
1388    return NULL;
1389  }
1390 
1391  if ( RasterAddress::lessThanRow( uiAbsPartIdxLB, m_pcPic->getNumPartInHeight() - uiPartUnitOffset, uiNumPartInCUWidth ) )
1392  {
1393    if ( !RasterAddress::isZeroCol( uiAbsPartIdxLB, uiNumPartInCUWidth ) )
1394    {
1395      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxLB + uiPartUnitOffset * uiNumPartInCUWidth - 1 ] )
1396      {
1397        uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + uiPartUnitOffset * uiNumPartInCUWidth - 1 ];
1398        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxLB, uiAbsZorderCUIdxLB, uiNumPartInCUWidth ) )
1399        {
1400          return m_pcPic->getCU( getAddr() );
1401        }
1402        else
1403        {
1404          uiBLPartUnitIdx -= m_uiAbsIdxInLCU;
1405          return this;
1406        }
1407      }
1408      uiBLPartUnitIdx = MAX_UINT;
1409      return NULL;
1410    }
1411    uiBLPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxLB + (1+uiPartUnitOffset) * uiNumPartInCUWidth - 1 ];
1412    if ( (bEnforceSliceRestriction && (m_pcCULeft==NULL || m_pcCULeft->getSlice()==NULL || 
1413       m_pcCULeft->getSCUAddr()+uiBLPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1414       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCULeft->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1415       ))
1416     )
1417    {
1418      return NULL;
1419    }
1420    return m_pcCULeft;
1421  }
1422 
1423  uiBLPartUnitIdx = MAX_UINT;
1424  return NULL;
1425}
1426
1427TComDataCU* TComDataCU::getPUAboveRightAdi(UInt&  uiARPartUnitIdx, UInt uiCurrPartUnitIdx, UInt uiPartUnitOffset, Bool bEnforceSliceRestriction )
1428{
1429  UInt uiAbsPartIdxRT     = g_auiZscanToRaster[uiCurrPartUnitIdx];
1430  UInt uiAbsZorderCUIdx   = g_auiZscanToRaster[ m_uiAbsIdxInLCU ] + (m_puhWidth[0] / m_pcPic->getMinCUWidth()) - 1;
1431  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
1432 
1433#if REPN_FORMAT_IN_VPS
1434  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxRT] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getPicWidthInLumaSamples() )
1435#else
1436  if( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxRT] + (m_pcPic->getPicSym()->getMinCUHeight() * uiPartUnitOffset)) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )
1437#endif
1438  {
1439    uiARPartUnitIdx = MAX_UINT;
1440    return NULL;
1441  }
1442 
1443  if ( RasterAddress::lessThanCol( uiAbsPartIdxRT, uiNumPartInCUWidth - uiPartUnitOffset, uiNumPartInCUWidth ) )
1444  {
1445    if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, uiNumPartInCUWidth ) )
1446    {
1447      if ( uiCurrPartUnitIdx > g_auiRasterToZscan[ uiAbsPartIdxRT - uiNumPartInCUWidth + uiPartUnitOffset ] )
1448      {
1449        uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT - uiNumPartInCUWidth + uiPartUnitOffset ];
1450        if ( RasterAddress::isEqualRowOrCol( uiAbsPartIdxRT, uiAbsZorderCUIdx, uiNumPartInCUWidth ) )
1451        {
1452          return m_pcPic->getCU( getAddr() );
1453        }
1454        else
1455        {
1456          uiARPartUnitIdx -= m_uiAbsIdxInLCU;
1457          return this;
1458        }
1459      }
1460      uiARPartUnitIdx = MAX_UINT;
1461      return NULL;
1462    }
1463    uiARPartUnitIdx = g_auiRasterToZscan[ uiAbsPartIdxRT + m_pcPic->getNumPartInCU() - uiNumPartInCUWidth + uiPartUnitOffset ];
1464    if ( (bEnforceSliceRestriction && (m_pcCUAbove==NULL || m_pcCUAbove->getSlice()==NULL || 
1465       m_pcCUAbove->getSCUAddr()+uiARPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1466       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCUAbove->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1467       ))
1468     )
1469    {
1470      return NULL;
1471    }
1472    return m_pcCUAbove;
1473  }
1474 
1475  if ( !RasterAddress::isZeroRow( uiAbsPartIdxRT, uiNumPartInCUWidth ) )
1476  {
1477    uiARPartUnitIdx = MAX_UINT;
1478    return NULL;
1479  }
1480 
1481  uiARPartUnitIdx = g_auiRasterToZscan[ m_pcPic->getNumPartInCU() - uiNumPartInCUWidth + uiPartUnitOffset-1 ];
1482  if ( (bEnforceSliceRestriction && (m_pcCUAboveRight==NULL || m_pcCUAboveRight->getSlice()==NULL ||
1483       m_pcPic->getPicSym()->getInverseCUOrderMap( m_pcCUAboveRight->getAddr()) > m_pcPic->getPicSym()->getInverseCUOrderMap( getAddr()) ||
1484       m_pcCUAboveRight->getSCUAddr()+uiARPartUnitIdx < m_pcPic->getCU( getAddr() )->getSliceStartCU(uiCurrPartUnitIdx)||
1485       (m_pcPic->getPicSym()->getTileIdxMap( m_pcCUAboveRight->getAddr() ) != m_pcPic->getPicSym()->getTileIdxMap(getAddr()))
1486       ))
1487     )
1488  {
1489    return NULL;
1490  }
1491  return m_pcCUAboveRight;
1492}
1493
1494/** Get left QpMinCu
1495*\param   uiLPartUnitIdx
1496*\param   uiCurrAbsIdxInLCU
1497*\returns TComDataCU*   point of TComDataCU of left QpMinCu
1498*/
1499TComDataCU* TComDataCU::getQpMinCuLeft( UInt& uiLPartUnitIdx, UInt uiCurrAbsIdxInLCU)
1500{
1501  UInt numPartInCUWidth = m_pcPic->getNumPartInWidth();
1502  UInt absZorderQpMinCUIdx = (uiCurrAbsIdxInLCU>>((g_uiMaxCUDepth - getSlice()->getPPS()->getMaxCuDQPDepth())<<1))<<((g_uiMaxCUDepth -getSlice()->getPPS()->getMaxCuDQPDepth())<<1);
1503  UInt absRorderQpMinCUIdx = g_auiZscanToRaster[absZorderQpMinCUIdx];
1504
1505  // check for left LCU boundary
1506  if ( RasterAddress::isZeroCol(absRorderQpMinCUIdx, numPartInCUWidth) )
1507  {
1508    return NULL;
1509  }
1510
1511  // get index of left-CU relative to top-left corner of current quantization group
1512  uiLPartUnitIdx = g_auiRasterToZscan[absRorderQpMinCUIdx - 1];
1513
1514  // return pointer to current LCU
1515  return m_pcPic->getCU( getAddr() );
1516}
1517
1518/** Get Above QpMinCu
1519*\param   aPartUnitIdx
1520*\param   currAbsIdxInLCU
1521*\returns TComDataCU*   point of TComDataCU of above QpMinCu
1522*/
1523TComDataCU* TComDataCU::getQpMinCuAbove( UInt& aPartUnitIdx, UInt currAbsIdxInLCU )
1524{
1525  UInt numPartInCUWidth = m_pcPic->getNumPartInWidth();
1526  UInt absZorderQpMinCUIdx = (currAbsIdxInLCU>>((g_uiMaxCUDepth - getSlice()->getPPS()->getMaxCuDQPDepth())<<1))<<((g_uiMaxCUDepth - getSlice()->getPPS()->getMaxCuDQPDepth())<<1);
1527  UInt absRorderQpMinCUIdx = g_auiZscanToRaster[absZorderQpMinCUIdx];
1528
1529  // check for top LCU boundary
1530  if ( RasterAddress::isZeroRow( absRorderQpMinCUIdx, numPartInCUWidth) )
1531  {
1532    return NULL;
1533  }
1534
1535  // get index of top-CU relative to top-left corner of current quantization group
1536  aPartUnitIdx = g_auiRasterToZscan[absRorderQpMinCUIdx - numPartInCUWidth];
1537
1538  // return pointer to current LCU
1539  return m_pcPic->getCU( getAddr() );
1540}
1541
1542/** Get reference QP from left QpMinCu or latest coded QP
1543*\param   uiCurrAbsIdxInLCU
1544*\returns Char   reference QP value
1545*/
1546Char TComDataCU::getRefQP( UInt uiCurrAbsIdxInLCU )
1547{
1548  UInt        lPartIdx = 0, aPartIdx = 0;
1549  TComDataCU* cULeft  = getQpMinCuLeft ( lPartIdx, m_uiAbsIdxInLCU + uiCurrAbsIdxInLCU );
1550  TComDataCU* cUAbove = getQpMinCuAbove( aPartIdx, m_uiAbsIdxInLCU + uiCurrAbsIdxInLCU );
1551  return (((cULeft? cULeft->getQP( lPartIdx ): getLastCodedQP( uiCurrAbsIdxInLCU )) + (cUAbove? cUAbove->getQP( aPartIdx ): getLastCodedQP( uiCurrAbsIdxInLCU )) + 1) >> 1);
1552}
1553
1554Int TComDataCU::getLastValidPartIdx( Int iAbsPartIdx )
1555{
1556  Int iLastValidPartIdx = iAbsPartIdx-1;
1557  while ( iLastValidPartIdx >= 0
1558       && getPredictionMode( iLastValidPartIdx ) == MODE_NONE )
1559  {
1560    UInt uiDepth = getDepth( iLastValidPartIdx );
1561    iLastValidPartIdx -= m_uiNumPartition>>(uiDepth<<1);
1562  }
1563  return iLastValidPartIdx;
1564}
1565
1566Char TComDataCU::getLastCodedQP( UInt uiAbsPartIdx )
1567{
1568  UInt uiQUPartIdxMask = ~((1<<((g_uiMaxCUDepth - getSlice()->getPPS()->getMaxCuDQPDepth())<<1))-1);
1569  Int iLastValidPartIdx = getLastValidPartIdx( uiAbsPartIdx&uiQUPartIdxMask );
1570  if ( uiAbsPartIdx < m_uiNumPartition
1571    && (getSCUAddr()+iLastValidPartIdx < getSliceStartCU(m_uiAbsIdxInLCU+uiAbsPartIdx)))
1572  {
1573    return getSlice()->getSliceQp();
1574  }
1575  else if ( iLastValidPartIdx >= 0 )
1576  {
1577    return getQP( iLastValidPartIdx );
1578  }
1579  else
1580  {
1581    if ( getZorderIdxInCU() > 0 )
1582    {
1583      return getPic()->getCU( getAddr() )->getLastCodedQP( getZorderIdxInCU() );
1584    }
1585    else if ( getPic()->getPicSym()->getInverseCUOrderMap(getAddr()) > 0
1586      && getPic()->getPicSym()->getTileIdxMap(getAddr()) == getPic()->getPicSym()->getTileIdxMap(getPic()->getPicSym()->getCUOrderMap(getPic()->getPicSym()->getInverseCUOrderMap(getAddr())-1))
1587      && !( getSlice()->getPPS()->getEntropyCodingSyncEnabledFlag() && getAddr() % getPic()->getFrameWidthInCU() == 0 ) )
1588    {
1589      return getPic()->getCU( getPic()->getPicSym()->getCUOrderMap(getPic()->getPicSym()->getInverseCUOrderMap(getAddr())-1) )->getLastCodedQP( getPic()->getNumPartInCU() );
1590    }
1591    else
1592    {
1593      return getSlice()->getSliceQp();
1594    }
1595  }
1596}
1597/** Check whether the CU is coded in lossless coding mode
1598 * \param   uiAbsPartIdx
1599 * \returns true if the CU is coded in lossless coding mode; false if otherwise
1600 */
1601Bool TComDataCU::isLosslessCoded(UInt absPartIdx)
1602{
1603  return (getSlice()->getPPS()->getTransquantBypassEnableFlag() && getCUTransquantBypass (absPartIdx));
1604}
1605
1606/** Get allowed chroma intra modes
1607*\param   uiAbsPartIdx
1608*\param   uiModeList  pointer to chroma intra modes array
1609*\returns
1610*- fill uiModeList with chroma intra modes
1611*/
1612Void TComDataCU::getAllowedChromaDir( UInt uiAbsPartIdx, UInt* uiModeList )
1613{
1614  uiModeList[0] = PLANAR_IDX;
1615  uiModeList[1] = VER_IDX;
1616  uiModeList[2] = HOR_IDX;
1617  uiModeList[3] = DC_IDX;
1618  uiModeList[4] = DM_CHROMA_IDX;
1619
1620  UInt uiLumaMode = getLumaIntraDir( uiAbsPartIdx );
1621
1622  for( Int i = 0; i < NUM_CHROMA_MODE - 1; i++ )
1623  {
1624    if( uiLumaMode == uiModeList[i] )
1625    {
1626      uiModeList[i] = 34; // VER+8 mode
1627      break;
1628    }
1629  }
1630}
1631
1632/** Get most probable intra modes
1633*\param   uiAbsPartIdx
1634*\param   uiIntraDirPred  pointer to the array for MPM storage
1635*\param   piMode          it is set with MPM mode in case both MPM are equal. It is used to restrict RD search at encode side.
1636*\returns Number of MPM
1637*/
1638Int TComDataCU::getIntraDirLumaPredictor( UInt uiAbsPartIdx, Int* uiIntraDirPred, Int* piMode  )
1639{
1640  TComDataCU* pcTempCU;
1641  UInt        uiTempPartIdx;
1642  Int         iLeftIntraDir, iAboveIntraDir;
1643  Int         uiPredNum = 0;
1644
1645  // Get intra direction of left PU
1646  pcTempCU = getPULeft( uiTempPartIdx, m_uiAbsIdxInLCU + uiAbsPartIdx );
1647 
1648  iLeftIntraDir  = pcTempCU ? ( pcTempCU->isIntra( uiTempPartIdx ) ? pcTempCU->getLumaIntraDir( uiTempPartIdx ) : DC_IDX ) : DC_IDX;
1649 
1650  // Get intra direction of above PU
1651  pcTempCU = getPUAbove( uiTempPartIdx, m_uiAbsIdxInLCU + uiAbsPartIdx, true, true );
1652 
1653  iAboveIntraDir = pcTempCU ? ( pcTempCU->isIntra( uiTempPartIdx ) ? pcTempCU->getLumaIntraDir( uiTempPartIdx ) : DC_IDX ) : DC_IDX;
1654 
1655  uiPredNum = 3;
1656  if(iLeftIntraDir == iAboveIntraDir)
1657  {
1658    if( piMode )
1659    {
1660      *piMode = 1;
1661    }
1662   
1663    if (iLeftIntraDir > 1) // angular modes
1664    {
1665      uiIntraDirPred[0] = iLeftIntraDir;
1666      uiIntraDirPred[1] = ((iLeftIntraDir + 29) % 32) + 2;
1667      uiIntraDirPred[2] = ((iLeftIntraDir - 1 ) % 32) + 2;
1668    }
1669    else //non-angular
1670    {
1671      uiIntraDirPred[0] = PLANAR_IDX;
1672      uiIntraDirPred[1] = DC_IDX;
1673      uiIntraDirPred[2] = VER_IDX; 
1674    }
1675  }
1676  else
1677  {
1678    if( piMode )
1679    {
1680      *piMode = 2;
1681    }
1682    uiIntraDirPred[0] = iLeftIntraDir;
1683    uiIntraDirPred[1] = iAboveIntraDir;
1684   
1685    if (iLeftIntraDir && iAboveIntraDir ) //both modes are non-planar
1686    {
1687      uiIntraDirPred[2] = PLANAR_IDX;
1688    }
1689    else
1690    {
1691      uiIntraDirPred[2] =  (iLeftIntraDir+iAboveIntraDir)<2? VER_IDX : DC_IDX;
1692    }
1693  }
1694 
1695  return uiPredNum;
1696}
1697
1698UInt TComDataCU::getCtxSplitFlag( UInt uiAbsPartIdx, UInt uiDepth )
1699{
1700  TComDataCU* pcTempCU;
1701  UInt        uiTempPartIdx;
1702  UInt        uiCtx;
1703  // Get left split flag
1704  pcTempCU = getPULeft( uiTempPartIdx, m_uiAbsIdxInLCU + uiAbsPartIdx );
1705  uiCtx  = ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;
1706 
1707  // Get above split flag
1708  pcTempCU = getPUAbove( uiTempPartIdx, m_uiAbsIdxInLCU + uiAbsPartIdx );
1709  uiCtx += ( pcTempCU ) ? ( ( pcTempCU->getDepth( uiTempPartIdx ) > uiDepth ) ? 1 : 0 ) : 0;
1710 
1711  return uiCtx;
1712}
1713
1714UInt TComDataCU::getCtxQtCbf( TextType eType, UInt uiTrDepth )
1715{
1716  if( eType )
1717  {
1718    return uiTrDepth;
1719  }
1720  else
1721  {
1722    const UInt uiCtx = ( uiTrDepth == 0 ? 1 : 0 );
1723    return uiCtx;
1724  }
1725}
1726
1727UInt TComDataCU::getQuadtreeTULog2MinSizeInCU( UInt absPartIdx )
1728{
1729  UInt log2CbSize = g_aucConvertToBit[getWidth( absPartIdx )] + 2;
1730  PartSize  partSize  = getPartitionSize( absPartIdx );
1731  UInt quadtreeTUMaxDepth = getPredictionMode( absPartIdx ) == MODE_INTRA ? m_pcSlice->getSPS()->getQuadtreeTUMaxDepthIntra() : m_pcSlice->getSPS()->getQuadtreeTUMaxDepthInter(); 
1732  Int intraSplitFlag = ( getPredictionMode( absPartIdx ) == MODE_INTRA && partSize == SIZE_NxN ) ? 1 : 0;
1733  Int interSplitFlag = ((quadtreeTUMaxDepth == 1) && (getPredictionMode( absPartIdx ) == MODE_INTER) && (partSize != SIZE_2Nx2N) );
1734 
1735  UInt log2MinTUSizeInCU = 0;
1736  if (log2CbSize < (m_pcSlice->getSPS()->getQuadtreeTULog2MinSize() + quadtreeTUMaxDepth - 1 + interSplitFlag + intraSplitFlag) ) 
1737  {
1738    // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is < QuadtreeTULog2MinSize
1739    log2MinTUSizeInCU = m_pcSlice->getSPS()->getQuadtreeTULog2MinSize();
1740  }
1741  else
1742  {
1743    // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is still >= QuadtreeTULog2MinSize
1744    log2MinTUSizeInCU = log2CbSize - ( quadtreeTUMaxDepth - 1 + interSplitFlag + intraSplitFlag); // stop when trafoDepth == hierarchy_depth = splitFlag
1745    if ( log2MinTUSizeInCU > m_pcSlice->getSPS()->getQuadtreeTULog2MaxSize())
1746    {
1747      // when fully making use of signaled TUMaxDepth + inter/intraSplitFlag, resulting luma TB size is still > QuadtreeTULog2MaxSize
1748      log2MinTUSizeInCU = m_pcSlice->getSPS()->getQuadtreeTULog2MaxSize();
1749    } 
1750  }
1751  return log2MinTUSizeInCU;
1752}
1753
1754UInt TComDataCU::getCtxSkipFlag( UInt uiAbsPartIdx )
1755{
1756  TComDataCU* pcTempCU;
1757  UInt        uiTempPartIdx;
1758  UInt        uiCtx = 0;
1759 
1760  // Get BCBP of left PU
1761  pcTempCU = getPULeft( uiTempPartIdx, m_uiAbsIdxInLCU + uiAbsPartIdx );
1762  uiCtx    = ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;
1763 
1764  // Get BCBP of above PU
1765  pcTempCU = getPUAbove( uiTempPartIdx, m_uiAbsIdxInLCU + uiAbsPartIdx );
1766  uiCtx   += ( pcTempCU ) ? pcTempCU->isSkipped( uiTempPartIdx ) : 0;
1767 
1768  return uiCtx;
1769}
1770
1771UInt TComDataCU::getCtxInterDir( UInt uiAbsPartIdx )
1772{
1773  return getDepth( uiAbsPartIdx );
1774}
1775
1776Void TComDataCU::setCbfSubParts( UInt uiCbfY, UInt uiCbfU, UInt uiCbfV, UInt uiAbsPartIdx, UInt uiDepth )
1777{
1778  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
1779  memset( m_puhCbf[0] + uiAbsPartIdx, uiCbfY, sizeof( UChar ) * uiCurrPartNumb );
1780  memset( m_puhCbf[1] + uiAbsPartIdx, uiCbfU, sizeof( UChar ) * uiCurrPartNumb );
1781  memset( m_puhCbf[2] + uiAbsPartIdx, uiCbfV, sizeof( UChar ) * uiCurrPartNumb );
1782}
1783
1784Void TComDataCU::setCbfSubParts( UInt uiCbf, TextType eTType, UInt uiAbsPartIdx, UInt uiDepth )
1785{
1786  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
1787  memset( m_puhCbf[g_aucConvertTxtTypeToIdx[eTType]] + uiAbsPartIdx, uiCbf, sizeof( UChar ) * uiCurrPartNumb );
1788}
1789
1790/** Sets a coded block flag for all sub-partitions of a partition
1791 * \param uiCbf The value of the coded block flag to be set
1792 * \param eTType
1793 * \param uiAbsPartIdx
1794 * \param uiPartIdx
1795 * \param uiDepth
1796 * \returns Void
1797 */
1798Void TComDataCU::setCbfSubParts ( UInt uiCbf, TextType eTType, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
1799{
1800  setSubPart<UChar>( uiCbf, m_puhCbf[g_aucConvertTxtTypeToIdx[eTType]], uiAbsPartIdx, uiDepth, uiPartIdx );
1801}
1802
1803Void TComDataCU::setDepthSubParts( UInt uiDepth, UInt uiAbsPartIdx )
1804{
1805  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
1806  memset( m_puhDepth + uiAbsPartIdx, uiDepth, sizeof(UChar)*uiCurrPartNumb );
1807}
1808
1809Bool TComDataCU::isFirstAbsZorderIdxInDepth (UInt uiAbsPartIdx, UInt uiDepth)
1810{
1811  UInt uiPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
1812  return (((m_uiAbsIdxInLCU + uiAbsPartIdx)% uiPartNumb) == 0);
1813}
1814
1815Void TComDataCU::setPartSizeSubParts( PartSize eMode, UInt uiAbsPartIdx, UInt uiDepth )
1816{
1817  assert( sizeof( *m_pePartSize) == 1 );
1818  memset( m_pePartSize + uiAbsPartIdx, eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
1819}
1820
1821Void TComDataCU::setCUTransquantBypassSubParts( Bool flag, UInt uiAbsPartIdx, UInt uiDepth )
1822{
1823  memset( m_CUTransquantBypass + uiAbsPartIdx, flag, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
1824}
1825
1826Void TComDataCU::setSkipFlagSubParts( Bool skip, UInt absPartIdx, UInt depth )
1827{
1828  assert( sizeof( *m_skipFlag) == 1 );
1829  memset( m_skipFlag + absPartIdx, skip, m_pcPic->getNumPartInCU() >> ( 2 * depth ) );
1830}
1831
1832Void TComDataCU::setPredModeSubParts( PredMode eMode, UInt uiAbsPartIdx, UInt uiDepth )
1833{
1834  assert( sizeof( *m_pePredMode) == 1 );
1835  memset( m_pePredMode + uiAbsPartIdx, eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
1836}
1837
1838Void TComDataCU::setQPSubCUs( Int qp, TComDataCU* pcCU, UInt absPartIdx, UInt depth, Bool &foundNonZeroCbf )
1839{
1840  UInt currPartNumb = m_pcPic->getNumPartInCU() >> (depth << 1);
1841  UInt currPartNumQ = currPartNumb >> 2;
1842
1843  if(!foundNonZeroCbf)
1844  {
1845    if(pcCU->getDepth(absPartIdx) > depth)
1846    {
1847      for ( UInt partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++ )
1848      {
1849        pcCU->setQPSubCUs( qp, pcCU, absPartIdx+partUnitIdx*currPartNumQ, depth+1, foundNonZeroCbf );
1850      }
1851    }
1852    else
1853    {
1854      if(pcCU->getCbf( absPartIdx, TEXT_LUMA ) || pcCU->getCbf( absPartIdx, TEXT_CHROMA_U ) || pcCU->getCbf( absPartIdx, TEXT_CHROMA_V ) )
1855      {
1856        foundNonZeroCbf = true;
1857      }
1858      else
1859      {
1860        setQPSubParts(qp, absPartIdx, depth);
1861      }
1862    }
1863  }
1864}
1865
1866Void TComDataCU::setQPSubParts( Int qp, UInt uiAbsPartIdx, UInt uiDepth )
1867{
1868  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
1869  TComSlice * pcSlice = getPic()->getSlice(getPic()->getCurrSliceIdx());
1870
1871  for(UInt uiSCUIdx = uiAbsPartIdx; uiSCUIdx < uiAbsPartIdx+uiCurrPartNumb; uiSCUIdx++)
1872  {
1873    if( m_pcPic->getCU( getAddr() )->getSliceSegmentStartCU(uiSCUIdx+getZorderIdxInCU()) == pcSlice->getSliceSegmentCurStartCUAddr() )
1874    {
1875      m_phQP[uiSCUIdx] = qp;
1876    }
1877  }
1878}
1879
1880Void TComDataCU::setLumaIntraDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiDepth )
1881{
1882  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
1883 
1884  memset( m_puhLumaIntraDir + uiAbsPartIdx, uiDir, sizeof(UChar)*uiCurrPartNumb );
1885}
1886
1887template<typename T>
1888Void TComDataCU::setSubPart( T uiParameter, T* puhBaseLCU, UInt uiCUAddr, UInt uiCUDepth, UInt uiPUIdx )
1889{
1890  assert( sizeof(T) == 1 ); // Using memset() works only for types of size 1
1891 
1892  UInt uiCurrPartNumQ = (m_pcPic->getNumPartInCU() >> (2 * uiCUDepth)) >> 2;
1893  switch ( m_pePartSize[ uiCUAddr ] )
1894  {
1895    case SIZE_2Nx2N:
1896      memset( puhBaseLCU + uiCUAddr, uiParameter, 4 * uiCurrPartNumQ );
1897      break;
1898    case SIZE_2NxN:
1899      memset( puhBaseLCU + uiCUAddr, uiParameter, 2 * uiCurrPartNumQ );
1900      break;
1901    case SIZE_Nx2N:
1902      memset( puhBaseLCU + uiCUAddr, uiParameter, uiCurrPartNumQ );
1903      memset( puhBaseLCU + uiCUAddr + 2 * uiCurrPartNumQ, uiParameter, uiCurrPartNumQ );
1904      break;
1905    case SIZE_NxN:
1906      memset( puhBaseLCU + uiCUAddr, uiParameter, uiCurrPartNumQ ); 
1907      break;
1908    case SIZE_2NxnU:
1909      if ( uiPUIdx == 0 )
1910      {
1911        memset( puhBaseLCU + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );                     
1912        memset( puhBaseLCU + uiCUAddr + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );                     
1913      }
1914      else if ( uiPUIdx == 1 )
1915      {
1916        memset( puhBaseLCU + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );                     
1917        memset( puhBaseLCU + uiCUAddr + uiCurrPartNumQ, uiParameter, ((uiCurrPartNumQ >> 1) + (uiCurrPartNumQ << 1)) );                     
1918      }
1919      else
1920      {
1921        assert(0);
1922      }
1923      break;
1924    case SIZE_2NxnD:
1925      if ( uiPUIdx == 0 )
1926      {
1927        memset( puhBaseLCU + uiCUAddr, uiParameter, ((uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1)) );                     
1928        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );                     
1929      }
1930      else if ( uiPUIdx == 1 )
1931      {
1932        memset( puhBaseLCU + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 1) );                     
1933        memset( puhBaseLCU + uiCUAddr + uiCurrPartNumQ, uiParameter, (uiCurrPartNumQ >> 1) );                     
1934      }
1935      else
1936      {
1937        assert(0);
1938      }
1939      break;
1940    case SIZE_nLx2N:
1941      if ( uiPUIdx == 0 )
1942      {
1943        memset( puhBaseLCU + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
1944        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) ); 
1945        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) ); 
1946        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) ); 
1947      }
1948      else if ( uiPUIdx == 1 )
1949      {
1950        memset( puhBaseLCU + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );
1951        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) ); 
1952        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) ); 
1953        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) ); 
1954      }
1955      else
1956      {
1957        assert(0);
1958      }
1959      break;
1960    case SIZE_nRx2N:
1961      if ( uiPUIdx == 0 )
1962      {     
1963        memset( puhBaseLCU + uiCUAddr, uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );                           
1964        memset( puhBaseLCU + uiCUAddr + uiCurrPartNumQ + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );                           
1965        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ + (uiCurrPartNumQ >> 2)) );                           
1966        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1) + uiCurrPartNumQ + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );                           
1967      }
1968      else if ( uiPUIdx == 1 )
1969      {
1970        memset( puhBaseLCU + uiCUAddr, uiParameter, (uiCurrPartNumQ >> 2) );                           
1971        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );                           
1972        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1), uiParameter, (uiCurrPartNumQ >> 2) );                           
1973        memset( puhBaseLCU + uiCUAddr + (uiCurrPartNumQ << 1) + (uiCurrPartNumQ >> 1), uiParameter, (uiCurrPartNumQ >> 2) );                         
1974      }
1975      else
1976      {
1977        assert(0);
1978      }
1979      break;
1980    default:
1981      assert( 0 );
1982  }
1983}
1984
1985Void TComDataCU::setMergeFlagSubParts ( Bool bMergeFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
1986{
1987  setSubPart( bMergeFlag, m_pbMergeFlag, uiAbsPartIdx, uiDepth, uiPartIdx );
1988}
1989
1990Void TComDataCU::setMergeIndexSubParts ( UInt uiMergeIndex, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
1991{
1992  setSubPart<UChar>( uiMergeIndex, m_puhMergeIndex, uiAbsPartIdx, uiDepth, uiPartIdx );
1993}
1994
1995Void TComDataCU::setChromIntraDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiDepth )
1996{
1997  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
1998 
1999  memset( m_puhChromaIntraDir + uiAbsPartIdx, uiDir, sizeof(UChar)*uiCurrPartNumb );
2000}
2001
2002Void TComDataCU::setInterDirSubParts( UInt uiDir, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2003{
2004  setSubPart<UChar>( uiDir, m_puhInterDir, uiAbsPartIdx, uiDepth, uiPartIdx );
2005}
2006
2007Void TComDataCU::setMVPIdxSubParts( Int iMVPIdx, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2008{
2009  setSubPart<Char>( iMVPIdx, m_apiMVPIdx[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2010}
2011
2012Void TComDataCU::setMVPNumSubParts( Int iMVPNum, RefPicList eRefPicList, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
2013{
2014  setSubPart<Char>( iMVPNum, m_apiMVPNum[eRefPicList], uiAbsPartIdx, uiDepth, uiPartIdx );
2015}
2016
2017
2018Void TComDataCU::setTrIdxSubParts( UInt uiTrIdx, UInt uiAbsPartIdx, UInt uiDepth )
2019{
2020  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2021 
2022  memset( m_puhTrIdx + uiAbsPartIdx, uiTrIdx, sizeof(UChar)*uiCurrPartNumb );
2023}
2024
2025Void TComDataCU::setTransformSkipSubParts( UInt useTransformSkipY, UInt useTransformSkipU, UInt useTransformSkipV, UInt uiAbsPartIdx, UInt uiDepth )
2026{
2027  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2028
2029  memset( m_puhTransformSkip[0] + uiAbsPartIdx, useTransformSkipY, sizeof( UChar ) * uiCurrPartNumb );
2030  memset( m_puhTransformSkip[1] + uiAbsPartIdx, useTransformSkipU, sizeof( UChar ) * uiCurrPartNumb );
2031  memset( m_puhTransformSkip[2] + uiAbsPartIdx, useTransformSkipV, sizeof( UChar ) * uiCurrPartNumb );
2032}
2033
2034Void TComDataCU::setTransformSkipSubParts( UInt useTransformSkip, TextType eType, UInt uiAbsPartIdx, UInt uiDepth)
2035{
2036  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2037
2038  memset( m_puhTransformSkip[g_aucConvertTxtTypeToIdx[eType]] + uiAbsPartIdx, useTransformSkip, sizeof( UChar ) * uiCurrPartNumb );
2039}
2040
2041Void TComDataCU::setSizeSubParts( UInt uiWidth, UInt uiHeight, UInt uiAbsPartIdx, UInt uiDepth )
2042{
2043  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
2044 
2045  memset( m_puhWidth  + uiAbsPartIdx, uiWidth,  sizeof(UChar)*uiCurrPartNumb );
2046  memset( m_puhHeight + uiAbsPartIdx, uiHeight, sizeof(UChar)*uiCurrPartNumb );
2047}
2048
2049UChar TComDataCU::getNumPartitions()
2050{
2051  UChar iNumPart = 0;
2052 
2053  switch ( m_pePartSize[0] )
2054  {
2055    case SIZE_2Nx2N:    iNumPart = 1; break;
2056    case SIZE_2NxN:     iNumPart = 2; break;
2057    case SIZE_Nx2N:     iNumPart = 2; break;
2058    case SIZE_NxN:      iNumPart = 4; break;
2059    case SIZE_2NxnU:    iNumPart = 2; break;
2060    case SIZE_2NxnD:    iNumPart = 2; break;
2061    case SIZE_nLx2N:    iNumPart = 2; break;
2062    case SIZE_nRx2N:    iNumPart = 2; break;
2063    default:            assert (0);   break;
2064  }
2065 
2066  return  iNumPart;
2067}
2068
2069Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight )
2070{
2071  switch ( m_pePartSize[0] )
2072  {
2073    case SIZE_2NxN:
2074      riWidth = getWidth(0);      riHeight = getHeight(0) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2075      break;
2076    case SIZE_Nx2N:
2077      riWidth = getWidth(0) >> 1; riHeight = getHeight(0);      ruiPartAddr = ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2;
2078      break;
2079    case SIZE_NxN:
2080      riWidth = getWidth(0) >> 1; riHeight = getHeight(0) >> 1; ruiPartAddr = ( m_uiNumPartition >> 2 ) * uiPartIdx;
2081      break;
2082    case SIZE_2NxnU:
2083      riWidth     = getWidth(0);
2084      riHeight    = ( uiPartIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
2085      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 3;
2086      break;
2087    case SIZE_2NxnD:
2088      riWidth     = getWidth(0);
2089      riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
2090      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 3);
2091      break;
2092    case SIZE_nLx2N:
2093      riWidth     = ( uiPartIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
2094      riHeight    = getHeight(0);
2095      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : m_uiNumPartition >> 4;
2096      break;
2097    case SIZE_nRx2N:
2098      riWidth     = ( uiPartIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
2099      riHeight    = getHeight(0);
2100      ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2101      break;
2102    default:
2103      assert ( m_pePartSize[0] == SIZE_2Nx2N );
2104      riWidth = getWidth(0);      riHeight = getHeight(0);      ruiPartAddr = 0;
2105      break;
2106  }
2107}
2108
2109
2110Void TComDataCU::getMvField ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefPicList, TComMvField& rcMvField )
2111{
2112  if ( pcCU == NULL )  // OUT OF BOUNDARY
2113  {
2114    TComMv  cZeroMv;
2115    rcMvField.setMvField( cZeroMv, NOT_VALID );
2116    return;
2117  }
2118 
2119  TComCUMvField*  pcCUMvField = pcCU->getCUMvField( eRefPicList );
2120  rcMvField.setMvField( pcCUMvField->getMv( uiAbsPartIdx ), pcCUMvField->getRefIdx( uiAbsPartIdx ) );
2121}
2122
2123Void TComDataCU::deriveLeftRightTopIdxGeneral ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT )
2124{
2125  ruiPartIdxLT = m_uiAbsIdxInLCU + uiAbsPartIdx;
2126  UInt uiPUWidth = 0;
2127 
2128  switch ( m_pePartSize[uiAbsPartIdx] )
2129  {
2130    case SIZE_2Nx2N: uiPUWidth = m_puhWidth[uiAbsPartIdx];  break;
2131    case SIZE_2NxN:  uiPUWidth = m_puhWidth[uiAbsPartIdx];   break;
2132    case SIZE_Nx2N:  uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1;  break;
2133    case SIZE_NxN:   uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 1; break;
2134    case SIZE_2NxnU:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2135    case SIZE_2NxnD:   uiPUWidth = m_puhWidth[uiAbsPartIdx]; break;
2136    case SIZE_nLx2N:   
2137      if ( uiPartIdx == 0 )
2138      {
2139        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2; 
2140      }
2141      else if ( uiPartIdx == 1 )
2142      {
2143        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2); 
2144      }
2145      else
2146      {
2147        assert(0);
2148      }
2149      break;
2150    case SIZE_nRx2N:   
2151      if ( uiPartIdx == 0 )
2152      {
2153        uiPUWidth = (m_puhWidth[uiAbsPartIdx]  >> 1) + (m_puhWidth[uiAbsPartIdx]  >> 2); 
2154      }
2155      else if ( uiPartIdx == 1 )
2156      {
2157        uiPUWidth = m_puhWidth[uiAbsPartIdx]  >> 2; 
2158      }
2159      else
2160      {
2161        assert(0);
2162      }
2163      break;
2164    default:
2165      assert (0);
2166      break;
2167  }
2168 
2169  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + uiPUWidth / m_pcPic->getMinCUWidth() - 1 ];
2170}
2171
2172Void TComDataCU::deriveLeftBottomIdxGeneral( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLB )
2173{
2174  UInt uiPUHeight = 0;
2175  switch ( m_pePartSize[uiAbsPartIdx] )
2176  {
2177    case SIZE_2Nx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];    break;
2178    case SIZE_2NxN:  uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2179    case SIZE_Nx2N:  uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2180    case SIZE_NxN:   uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 1;    break;
2181    case SIZE_2NxnU: 
2182      if ( uiPartIdx == 0 )
2183      {
2184        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;   
2185      }
2186      else if ( uiPartIdx == 1 )
2187      {
2188        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);   
2189      }
2190      else
2191      {
2192        assert(0);
2193      }
2194      break;
2195    case SIZE_2NxnD: 
2196      if ( uiPartIdx == 0 )
2197      {
2198        uiPUHeight = (m_puhHeight[uiAbsPartIdx] >> 1) + (m_puhHeight[uiAbsPartIdx] >> 2);   
2199      }
2200      else if ( uiPartIdx == 1 )
2201      {
2202        uiPUHeight = m_puhHeight[uiAbsPartIdx] >> 2;   
2203      }
2204      else
2205      {
2206        assert(0);
2207      }
2208      break;
2209    case SIZE_nLx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2210    case SIZE_nRx2N: uiPUHeight = m_puhHeight[uiAbsPartIdx];  break;
2211    default:
2212      assert (0);
2213      break;
2214  }
2215 
2216  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_uiAbsIdxInLCU + uiAbsPartIdx ] + ((uiPUHeight / m_pcPic->getMinCUHeight()) - 1)*m_pcPic->getNumPartInWidth()];
2217}
2218
2219Void TComDataCU::deriveLeftRightTopIdx ( UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT )
2220{
2221  ruiPartIdxLT = m_uiAbsIdxInLCU;
2222  ruiPartIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ ruiPartIdxLT ] + m_puhWidth[0] / m_pcPic->getMinCUWidth() - 1 ];
2223 
2224  switch ( m_pePartSize[0] )
2225  {
2226    case SIZE_2Nx2N:                                                                                                                                break;
2227    case SIZE_2NxN:
2228      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1; ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2229      break;
2230    case SIZE_Nx2N:
2231      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 2; ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 2;
2232      break;
2233    case SIZE_NxN:
2234      ruiPartIdxLT += ( m_uiNumPartition >> 2 ) * uiPartIdx;         ruiPartIdxRT +=  ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );
2235      break;
2236    case SIZE_2NxnU:
2237      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2238      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 3;
2239      break;
2240    case SIZE_2NxnD:
2241      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2242      ruiPartIdxRT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 1 ) + ( m_uiNumPartition >> 3 );
2243      break;
2244    case SIZE_nLx2N:
2245      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 4;
2246      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2247      break;
2248    case SIZE_nRx2N:
2249      ruiPartIdxLT += ( uiPartIdx == 0 )? 0 : ( m_uiNumPartition >> 2 ) + ( m_uiNumPartition >> 4 );
2250      ruiPartIdxRT -= ( uiPartIdx == 1 )? 0 : m_uiNumPartition >> 4;
2251      break;
2252    default:
2253      assert (0);
2254      break;
2255  }
2256 
2257}
2258
2259Void TComDataCU::deriveLeftBottomIdx( UInt  uiPartIdx,      UInt&      ruiPartIdxLB )
2260{
2261  ruiPartIdxLB      = g_auiRasterToZscan [g_auiZscanToRaster[ m_uiAbsIdxInLCU ] + ( ((m_puhHeight[0] / m_pcPic->getMinCUHeight())>>1) - 1)*m_pcPic->getNumPartInWidth()];
2262 
2263  switch ( m_pePartSize[0] )
2264  {
2265    case SIZE_2Nx2N:
2266      ruiPartIdxLB += m_uiNumPartition >> 1;
2267      break;
2268    case SIZE_2NxN:
2269      ruiPartIdxLB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;
2270      break;
2271    case SIZE_Nx2N:
2272      ruiPartIdxLB += ( uiPartIdx == 0 )? m_uiNumPartition >> 1 : (m_uiNumPartition >> 2)*3;
2273      break;
2274    case SIZE_NxN:
2275      ruiPartIdxLB += ( m_uiNumPartition >> 2 ) * uiPartIdx;
2276      break;
2277    case SIZE_2NxnU:
2278      ruiPartIdxLB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2279      break;
2280    case SIZE_2NxnD:
2281      ruiPartIdxLB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2282      break;
2283    case SIZE_nLx2N:
2284      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 4);
2285      break;
2286    case SIZE_nRx2N:
2287      ruiPartIdxLB += ( uiPartIdx == 0 ) ? m_uiNumPartition >> 1 : (m_uiNumPartition >> 1) + (m_uiNumPartition >> 2) + (m_uiNumPartition >> 4);
2288      break;
2289    default:
2290      assert (0);
2291      break;
2292  }
2293}
2294
2295/** Derives the partition index of neighbouring bottom right block
2296 * \param [in]  eCUMode
2297 * \param [in]  uiPartIdx
2298 * \param [out] ruiPartIdxRB
2299 */
2300Void TComDataCU::deriveRightBottomIdx( UInt  uiPartIdx,      UInt&      ruiPartIdxRB )
2301{
2302  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];
2303
2304  switch ( m_pePartSize[0] )
2305  {
2306    case SIZE_2Nx2N: 
2307      ruiPartIdxRB += m_uiNumPartition >> 1;   
2308      break;
2309    case SIZE_2NxN: 
2310      ruiPartIdxRB += ( uiPartIdx == 0 )? 0 : m_uiNumPartition >> 1;   
2311      break;
2312    case SIZE_Nx2N: 
2313      ruiPartIdxRB += ( uiPartIdx == 0 )? m_uiNumPartition >> 2 : (m_uiNumPartition >> 1);   
2314      break;
2315    case SIZE_NxN:   
2316      ruiPartIdxRB += ( m_uiNumPartition >> 2 ) * ( uiPartIdx - 1 );   
2317      break;
2318    case SIZE_2NxnU:
2319      ruiPartIdxRB += ( uiPartIdx == 0 ) ? -((Int)m_uiNumPartition >> 3) : m_uiNumPartition >> 1;
2320      break;
2321    case SIZE_2NxnD:
2322      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3): m_uiNumPartition >> 1;
2323      break;
2324    case SIZE_nLx2N:
2325      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4): m_uiNumPartition >> 1;
2326      break;
2327    case SIZE_nRx2N:
2328      ruiPartIdxRB += ( uiPartIdx == 0 ) ? (m_uiNumPartition >> 2) + (m_uiNumPartition >> 3) + (m_uiNumPartition >> 4) : m_uiNumPartition >> 1;
2329      break;
2330    default:
2331      assert (0);
2332      break;
2333  }
2334}
2335
2336Void TComDataCU::deriveLeftRightTopIdxAdi ( UInt& ruiPartIdxLT, UInt& ruiPartIdxRT, UInt uiPartOffset, UInt uiPartDepth )
2337{
2338  UInt uiNumPartInWidth = (m_puhWidth[0]/m_pcPic->getMinCUWidth())>>uiPartDepth;
2339  ruiPartIdxLT = m_uiAbsIdxInLCU + uiPartOffset;
2340  ruiPartIdxRT = g_auiRasterToZscan[ g_auiZscanToRaster[ ruiPartIdxLT ] + uiNumPartInWidth - 1 ];
2341}
2342
2343Void TComDataCU::deriveLeftBottomIdxAdi( UInt& ruiPartIdxLB, UInt uiPartOffset, UInt uiPartDepth )
2344{
2345  UInt uiAbsIdx;
2346  UInt uiMinCuWidth, uiWidthInMinCus;
2347 
2348  uiMinCuWidth    = getPic()->getMinCUWidth();
2349  uiWidthInMinCus = (getWidth(0)/uiMinCuWidth)>>uiPartDepth;
2350  uiAbsIdx        = getZorderIdxInCU()+uiPartOffset+(m_uiNumPartition>>(uiPartDepth<<1))-1;
2351  uiAbsIdx        = g_auiZscanToRaster[uiAbsIdx]-(uiWidthInMinCus-1);
2352  ruiPartIdxLB    = g_auiRasterToZscan[uiAbsIdx];
2353}
2354
2355Bool TComDataCU::hasEqualMotion( UInt uiAbsPartIdx, TComDataCU* pcCandCU, UInt uiCandAbsPartIdx )
2356{
2357
2358  if ( getInterDir( uiAbsPartIdx ) != pcCandCU->getInterDir( uiCandAbsPartIdx ) )
2359  {
2360    return false;
2361  }
2362
2363  for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
2364  {
2365    if ( getInterDir( uiAbsPartIdx ) & ( 1 << uiRefListIdx ) )
2366    {
2367      if ( getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiAbsPartIdx )     != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getMv( uiCandAbsPartIdx ) || 
2368        getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiAbsPartIdx ) != pcCandCU->getCUMvField( RefPicList( uiRefListIdx ) )->getRefIdx( uiCandAbsPartIdx ) )
2369      {
2370        return false;
2371      }
2372    }
2373  }
2374
2375  return true;
2376}
2377
2378/** Constructs a list of merging candidates
2379 * \param uiAbsPartIdx
2380 * \param uiPUIdx
2381 * \param uiDepth
2382 * \param pcMvFieldNeighbours
2383 * \param puhInterDirNeighbours
2384 * \param numValidMergeCand
2385 */
2386Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx )
2387{
2388  UInt uiAbsPartAddr = m_uiAbsIdxInLCU + uiAbsPartIdx;
2389  Bool abCandIsInter[ MRG_MAX_NUM_CANDS ];
2390  for( UInt ui = 0; ui < getSlice()->getMaxNumMergeCand(); ++ui )
2391  {
2392    abCandIsInter[ui] = false;
2393    pcMvFieldNeighbours[ ( ui << 1 )     ].setRefIdx(NOT_VALID);
2394    pcMvFieldNeighbours[ ( ui << 1 ) + 1 ].setRefIdx(NOT_VALID);
2395  }
2396  numValidMergeCand = getSlice()->getMaxNumMergeCand();
2397  // compute the location of the current PU
2398  Int xP, yP, nPSW, nPSH;
2399  this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH);
2400
2401  Int iCount = 0;
2402
2403  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
2404  PartSize cCurPS = getPartitionSize( uiAbsPartIdx );
2405  deriveLeftRightTopIdxGeneral( uiAbsPartIdx, uiPUIdx, uiPartIdxLT, uiPartIdxRT );
2406  deriveLeftBottomIdxGeneral  ( uiAbsPartIdx, uiPUIdx, uiPartIdxLB );
2407
2408  //left
2409  UInt uiLeftPartIdx = 0;
2410  TComDataCU* pcCULeft = 0;
2411  pcCULeft = getPULeft( uiLeftPartIdx, uiPartIdxLB );
2412  Bool isAvailableA1 = pcCULeft &&
2413  pcCULeft->isDiffMER(xP -1, yP+nPSH-1, xP, yP) &&
2414  !( uiPUIdx == 1 && (cCurPS == SIZE_Nx2N || cCurPS == SIZE_nLx2N || cCurPS == SIZE_nRx2N) ) &&
2415  !pcCULeft->isIntra( uiLeftPartIdx ) ;
2416  if ( isAvailableA1 )
2417  {
2418    abCandIsInter[iCount] = true;
2419    // get Inter Dir
2420    puhInterDirNeighbours[iCount] = pcCULeft->getInterDir( uiLeftPartIdx );
2421    // get Mv from Left
2422    pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
2423    if ( getSlice()->isInterB() )
2424    {
2425      pcCULeft->getMvField( pcCULeft, uiLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
2426    }
2427    if ( mrgCandIdx == iCount )
2428    {
2429      return;
2430    }
2431    iCount ++;
2432  }
2433 
2434  // early termination
2435  if (iCount == getSlice()->getMaxNumMergeCand()) 
2436  {
2437    return;
2438  }
2439  // above
2440  UInt uiAbovePartIdx = 0;
2441  TComDataCU* pcCUAbove = 0;
2442  pcCUAbove = getPUAbove( uiAbovePartIdx, uiPartIdxRT );
2443  Bool isAvailableB1 = pcCUAbove &&
2444  pcCUAbove->isDiffMER(xP+nPSW-1, yP-1, xP, yP) &&
2445  !( uiPUIdx == 1 && (cCurPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD) ) &&
2446  !pcCUAbove->isIntra( uiAbovePartIdx );
2447  if ( isAvailableB1 && (!isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
2448  {
2449    abCandIsInter[iCount] = true;
2450    // get Inter Dir
2451    puhInterDirNeighbours[iCount] = pcCUAbove->getInterDir( uiAbovePartIdx );
2452    // get Mv from Left
2453    pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
2454    if ( getSlice()->isInterB() )
2455    {
2456      pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
2457    }
2458    if ( mrgCandIdx == iCount )
2459    {
2460      return;
2461    }
2462    iCount ++;
2463  }
2464  // early termination
2465  if (iCount == getSlice()->getMaxNumMergeCand()) 
2466  {
2467    return;
2468  }
2469
2470  // above right
2471  UInt uiAboveRightPartIdx = 0;
2472  TComDataCU* pcCUAboveRight = 0;
2473  pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT );
2474  Bool isAvailableB0 = pcCUAboveRight &&
2475  pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP) &&
2476  !pcCUAboveRight->isIntra( uiAboveRightPartIdx );
2477  if ( isAvailableB0 && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
2478  {
2479    abCandIsInter[iCount] = true;
2480    // get Inter Dir
2481    puhInterDirNeighbours[iCount] = pcCUAboveRight->getInterDir( uiAboveRightPartIdx );
2482    // get Mv from Left
2483    pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
2484    if ( getSlice()->isInterB() )
2485    {
2486      pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
2487    }
2488    if ( mrgCandIdx == iCount )
2489    {
2490      return;
2491    }
2492    iCount ++;
2493  }
2494  // early termination
2495  if (iCount == getSlice()->getMaxNumMergeCand()) 
2496  {
2497    return;
2498  }
2499
2500  //left bottom
2501  UInt uiLeftBottomPartIdx = 0;
2502  TComDataCU* pcCULeftBottom = 0;
2503  pcCULeftBottom = this->getPUBelowLeft( uiLeftBottomPartIdx, uiPartIdxLB );
2504  Bool isAvailableA0 = pcCULeftBottom &&
2505  pcCULeftBottom->isDiffMER(xP-1, yP+nPSH, xP, yP) &&
2506  !pcCULeftBottom->isIntra( uiLeftBottomPartIdx ) ;
2507  if ( isAvailableA0 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCULeftBottom, uiLeftBottomPartIdx ) ) )
2508  {
2509    abCandIsInter[iCount] = true;
2510    // get Inter Dir
2511    puhInterDirNeighbours[iCount] = pcCULeftBottom->getInterDir( uiLeftBottomPartIdx );
2512    // get Mv from Left
2513    pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
2514    if ( getSlice()->isInterB() )
2515    {
2516      pcCULeftBottom->getMvField( pcCULeftBottom, uiLeftBottomPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
2517    }
2518    if ( mrgCandIdx == iCount )
2519    {
2520      return;
2521    }
2522    iCount ++;
2523  }
2524  // early termination
2525  if (iCount == getSlice()->getMaxNumMergeCand()) 
2526  {
2527    return;
2528  }
2529  // above left
2530  if( iCount < 4 )
2531  {
2532    UInt uiAboveLeftPartIdx = 0;
2533    TComDataCU* pcCUAboveLeft = 0;
2534    pcCUAboveLeft = getPUAboveLeft( uiAboveLeftPartIdx, uiAbsPartAddr );
2535    Bool isAvailableB2 = pcCUAboveLeft &&
2536    pcCUAboveLeft->isDiffMER(xP-1, yP-1, xP, yP) &&
2537    !pcCUAboveLeft->isIntra( uiAboveLeftPartIdx );
2538    if ( isAvailableB2 && ( !isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) )
2539        && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveLeft, uiAboveLeftPartIdx ) ) )
2540    {
2541      abCandIsInter[iCount] = true;
2542      // get Inter Dir
2543      puhInterDirNeighbours[iCount] = pcCUAboveLeft->getInterDir( uiAboveLeftPartIdx );
2544      // get Mv from Left
2545      pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
2546      if ( getSlice()->isInterB() )
2547      {
2548        pcCUAboveLeft->getMvField( pcCUAboveLeft, uiAboveLeftPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
2549      }
2550      if ( mrgCandIdx == iCount )
2551      {
2552        return;
2553      }
2554      iCount ++;
2555    }
2556  }
2557  // early termination
2558  if (iCount == getSlice()->getMaxNumMergeCand()) 
2559  {
2560    return;
2561  }
2562  if ( getSlice()->getEnableTMVPFlag())
2563  {
2564    //>> MTK colocated-RightBottom
2565    UInt uiPartIdxRB;
2566
2567    deriveRightBottomIdx( uiPUIdx, uiPartIdxRB ); 
2568
2569    UInt uiAbsPartIdxTmp = g_auiZscanToRaster[uiPartIdxRB];
2570    UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
2571
2572    TComMv cColMv;
2573    Int iRefIdx;
2574    Int uiLCUIdx = -1;
2575
2576#if REPN_FORMAT_IN_VPS
2577    if      ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getPicWidthInLumaSamples() )  // image boundary check
2578    {
2579    }
2580    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getPicHeightInLumaSamples() )
2581    {
2582    }
2583#else
2584    if      ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdxTmp] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )  // image boundary check
2585    {
2586    }
2587    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdxTmp] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
2588    {
2589    }
2590#endif
2591    else
2592    {
2593      if ( ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
2594        ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
2595      {
2596        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + uiNumPartInCUWidth + 1 ];
2597        uiLCUIdx = getAddr();
2598      }
2599      else if ( uiAbsPartIdxTmp % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
2600      {
2601        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdxTmp + uiNumPartInCUWidth + 1) % m_pcPic->getNumPartInCU() ];
2602      }
2603      else if ( uiAbsPartIdxTmp / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
2604      {
2605        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdxTmp + 1 ];
2606        uiLCUIdx = getAddr() + 1;
2607      }
2608      else //is the right bottom corner of LCU                       
2609      {
2610        uiAbsPartAddr = 0;
2611      }
2612    }
2613   
2614   
2615    iRefIdx = 0;
2616    Bool bExistMV = false;
2617    UInt uiPartIdxCenter;
2618    UInt uiCurLCUIdx = getAddr();
2619    Int dir = 0;
2620    UInt uiArrayAddr = iCount;
2621    xDeriveCenterIdx( uiPUIdx, uiPartIdxCenter );
2622    bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_0, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx );
2623    if( bExistMV == false )
2624    {
2625      bExistMV = xGetColMVP( REF_PIC_LIST_0, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
2626    }
2627    if( bExistMV )
2628    {
2629      dir |= 1;
2630      pcMvFieldNeighbours[ 2 * uiArrayAddr ].setMvField( cColMv, iRefIdx );
2631    }
2632   
2633    if ( getSlice()->isInterB() )
2634    {
2635      bExistMV = uiLCUIdx >= 0 && xGetColMVP( REF_PIC_LIST_1, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx);
2636      if( bExistMV == false )
2637      {
2638        bExistMV = xGetColMVP( REF_PIC_LIST_1, uiCurLCUIdx, uiPartIdxCenter, cColMv, iRefIdx );
2639      }
2640      if( bExistMV )
2641      {
2642        dir |= 2;
2643        pcMvFieldNeighbours[ 2 * uiArrayAddr + 1 ].setMvField( cColMv, iRefIdx );
2644      }
2645    }
2646   
2647    if (dir != 0)
2648    {
2649      puhInterDirNeighbours[uiArrayAddr] = dir;
2650      abCandIsInter[uiArrayAddr] = true;
2651
2652      if ( mrgCandIdx == iCount )
2653      {
2654        return;
2655      }
2656      iCount++;
2657    }
2658  }
2659  // early termination
2660  if (iCount == getSlice()->getMaxNumMergeCand()) 
2661  {
2662    return;
2663  }
2664  UInt uiArrayAddr = iCount;
2665  UInt uiCutoff = uiArrayAddr;
2666   
2667  if ( getSlice()->isInterB())
2668  {
2669    UInt uiPriorityList0[12] = {0 , 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3};
2670    UInt uiPriorityList1[12] = {1 , 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2};
2671
2672    for (Int idx=0; idx<uiCutoff*(uiCutoff-1) && uiArrayAddr!= getSlice()->getMaxNumMergeCand(); idx++)
2673    {
2674      Int i = uiPriorityList0[idx]; Int j = uiPriorityList1[idx];
2675      if (abCandIsInter[i] && abCandIsInter[j]&& (puhInterDirNeighbours[i]&0x1)&&(puhInterDirNeighbours[j]&0x2))
2676      {
2677        abCandIsInter[uiArrayAddr] = true;
2678        puhInterDirNeighbours[uiArrayAddr] = 3;
2679
2680        // get Mv from cand[i] and cand[j]
2681        pcMvFieldNeighbours[uiArrayAddr << 1].setMvField(pcMvFieldNeighbours[i<<1].getMv(), pcMvFieldNeighbours[i<<1].getRefIdx());
2682        pcMvFieldNeighbours[( uiArrayAddr << 1 ) + 1].setMvField(pcMvFieldNeighbours[(j<<1)+1].getMv(), pcMvFieldNeighbours[(j<<1)+1].getRefIdx());
2683
2684        Int iRefPOCL0 = m_pcSlice->getRefPOC( REF_PIC_LIST_0, pcMvFieldNeighbours[(uiArrayAddr<<1)].getRefIdx() );
2685        Int iRefPOCL1 = m_pcSlice->getRefPOC( REF_PIC_LIST_1, pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getRefIdx() );
2686        if (iRefPOCL0 == iRefPOCL1 && pcMvFieldNeighbours[(uiArrayAddr<<1)].getMv() == pcMvFieldNeighbours[(uiArrayAddr<<1)+1].getMv())
2687        {
2688          abCandIsInter[uiArrayAddr] = false;
2689        }
2690        else
2691        {
2692          uiArrayAddr++;
2693        }
2694      }
2695    }
2696  }
2697  // early termination
2698  if (uiArrayAddr == getSlice()->getMaxNumMergeCand()) 
2699  {
2700    return;
2701  }
2702  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);
2703  Int r = 0;
2704  Int refcnt = 0;
2705  while (uiArrayAddr < getSlice()->getMaxNumMergeCand())
2706  {
2707    abCandIsInter[uiArrayAddr] = true;
2708    puhInterDirNeighbours[uiArrayAddr] = 1;
2709    pcMvFieldNeighbours[uiArrayAddr << 1].setMvField( TComMv(0, 0), r);
2710
2711    if ( getSlice()->isInterB() )
2712    {
2713      puhInterDirNeighbours[uiArrayAddr] = 3;
2714      pcMvFieldNeighbours[(uiArrayAddr << 1) + 1].setMvField(TComMv(0, 0), r);
2715    }
2716    uiArrayAddr++;
2717    if ( refcnt == iNumRefIdx - 1 )
2718    {
2719      r = 0;
2720    }
2721    else
2722    {
2723      ++r;
2724      ++refcnt;
2725    }
2726  }
2727
2728  numValidMergeCand = uiArrayAddr;
2729}
2730
2731/** Check whether the current PU and a spatial neighboring PU are in a same ME region.
2732 * \param xN, xN   location of the upper-left corner pixel of a neighboring PU
2733 * \param xP, yP   location of the upper-left corner pixel of the current PU
2734 * \returns Bool
2735 */
2736Bool TComDataCU::isDiffMER(Int xN, Int yN, Int xP, Int yP)
2737{
2738
2739  UInt plevel = this->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() + 2;
2740  if ((xN>>plevel)!= (xP>>plevel))
2741  {
2742    return true;
2743  }
2744  if ((yN>>plevel)!= (yP>>plevel))
2745  {
2746    return true;
2747  }
2748  return false;
2749}
2750/** calculate the location of upper-left corner pixel and size of the current PU.
2751 * \param partIdx  PU index within a CU
2752 * \param xP, yP   location of the upper-left corner pixel of the current PU
2753 * \param PSW, nPSH    size of the curren PU
2754 * \returns Void
2755 */
2756Void TComDataCU::getPartPosition( UInt partIdx, Int& xP, Int& yP, Int& nPSW, Int& nPSH)
2757{
2758  UInt col = m_uiCUPelX;
2759  UInt row = m_uiCUPelY;
2760
2761  switch ( m_pePartSize[0] )
2762  {
2763  case SIZE_2NxN:
2764    nPSW = getWidth(0);     
2765    nPSH = getHeight(0) >> 1; 
2766    xP   = col;
2767    yP   = (partIdx ==0)? row: row + nPSH;
2768    break;
2769  case SIZE_Nx2N:
2770    nPSW = getWidth(0) >> 1; 
2771    nPSH = getHeight(0);     
2772    xP   = (partIdx ==0)? col: col + nPSW;
2773    yP   = row;
2774    break;
2775  case SIZE_NxN:
2776    nPSW = getWidth(0) >> 1; 
2777    nPSH = getHeight(0) >> 1; 
2778    xP   = col + (partIdx&0x1)*nPSW;
2779    yP   = row + (partIdx>>1)*nPSH;
2780    break;
2781  case SIZE_2NxnU:
2782    nPSW = getWidth(0);
2783    nPSH = ( partIdx == 0 ) ?  getHeight(0) >> 2 : ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 );
2784    xP   = col;
2785    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
2786
2787    break;
2788  case SIZE_2NxnD:
2789    nPSW = getWidth(0);
2790    nPSH = ( partIdx == 0 ) ?  ( getHeight(0) >> 2 ) + ( getHeight(0) >> 1 ) : getHeight(0) >> 2;
2791    xP   = col;
2792    yP   = (partIdx ==0)? row: row + getHeight(0) - nPSH;
2793    break;
2794  case SIZE_nLx2N:
2795    nPSW = ( partIdx == 0 ) ? getWidth(0) >> 2 : ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 );
2796    nPSH = getHeight(0);
2797    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
2798    yP   = row;
2799    break;
2800  case SIZE_nRx2N:
2801    nPSW = ( partIdx == 0 ) ? ( getWidth(0) >> 2 ) + ( getWidth(0) >> 1 ) : getWidth(0) >> 2;
2802    nPSH = getHeight(0);
2803    xP   = (partIdx ==0)? col: col + getWidth(0) - nPSW;
2804    yP   = row;
2805    break;
2806  default:
2807    assert ( m_pePartSize[0] == SIZE_2Nx2N );
2808    nPSW = getWidth(0);     
2809    nPSH = getHeight(0);     
2810    xP   = col ;
2811    yP   = row ;
2812
2813    break;
2814  }
2815}
2816
2817/** Constructs a list of candidates for AMVP
2818 * \param uiPartIdx
2819 * \param uiPartAddr
2820 * \param eRefPicList
2821 * \param iRefIdx
2822 * \param pInfo
2823 */
2824Void TComDataCU::fillMvpCand ( UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, AMVPInfo* pInfo )
2825{
2826  TComMv cMvPred;
2827  Bool bAddedSmvp = false;
2828
2829  pInfo->iN = 0; 
2830  if (iRefIdx < 0)
2831  {
2832    return;
2833  }
2834 
2835  //-- Get Spatial MV
2836  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
2837  UInt uiNumPartInCUWidth = m_pcPic->getNumPartInWidth();
2838  Bool bAdded = false;
2839 
2840  deriveLeftRightTopIdx( uiPartIdx, uiPartIdxLT, uiPartIdxRT );
2841  deriveLeftBottomIdx( uiPartIdx, uiPartIdxLB );
2842 
2843  TComDataCU* tmpCU = NULL;
2844  UInt idx;
2845  tmpCU = getPUBelowLeft(idx, uiPartIdxLB);
2846  bAddedSmvp = (tmpCU != NULL) && (tmpCU->getPredictionMode(idx) != MODE_INTRA);
2847
2848  if (!bAddedSmvp)
2849  {
2850    tmpCU = getPULeft(idx, uiPartIdxLB);
2851    bAddedSmvp = (tmpCU != NULL) && (tmpCU->getPredictionMode(idx) != MODE_INTRA);
2852  }
2853
2854  // Left predictor search
2855  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
2856  if (!bAdded) 
2857  {
2858    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
2859  }
2860 
2861  if(!bAdded)
2862  {
2863    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_BELOW_LEFT);
2864    if (!bAdded) 
2865    {
2866      xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLB, MD_LEFT );
2867    }
2868  }
2869 
2870  // Above predictor search
2871  bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
2872
2873  if (!bAdded) 
2874  {
2875    bAdded = xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
2876  }
2877
2878  if(!bAdded)
2879  {
2880    xAddMVPCand( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
2881  }
2882
2883  if (!bAddedSmvp)
2884  {
2885    bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE_RIGHT);
2886    if (!bAdded) 
2887    {
2888      bAdded = xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxRT, MD_ABOVE);
2889    }
2890
2891    if(!bAdded)
2892    {
2893      xAddMVPCandOrder( pInfo, eRefPicList, iRefIdx, uiPartIdxLT, MD_ABOVE_LEFT);
2894    }
2895  }
2896 
2897  if ( pInfo->iN == 2 )
2898  {
2899    if ( pInfo->m_acMvCand[ 0 ] == pInfo->m_acMvCand[ 1 ] )
2900    {
2901      pInfo->iN = 1;
2902    }
2903  }
2904
2905  if ( getSlice()->getEnableTMVPFlag() )
2906  {
2907    // Get Temporal Motion Predictor
2908    Int iRefIdx_Col = iRefIdx;
2909    TComMv cColMv;
2910    UInt uiPartIdxRB;
2911    UInt uiAbsPartIdx; 
2912    UInt uiAbsPartAddr;
2913
2914    deriveRightBottomIdx( uiPartIdx, uiPartIdxRB );
2915    uiAbsPartAddr = m_uiAbsIdxInLCU + uiPartAddr;
2916
2917    //----  co-located RightBottom Temporal Predictor (H) ---//
2918    uiAbsPartIdx = g_auiZscanToRaster[uiPartIdxRB];
2919    Int uiLCUIdx = -1;
2920#if REPN_FORMAT_IN_VPS
2921    if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdx] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getPicWidthInLumaSamples() )  // image boundary check
2922    {
2923    }
2924    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdx] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getPicHeightInLumaSamples() )
2925    {
2926    }
2927#else
2928    if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelX() + g_auiRasterToPelX[uiAbsPartIdx] + m_pcPic->getMinCUWidth() ) >= m_pcSlice->getSPS()->getPicWidthInLumaSamples() )  // image boundary check
2929    {
2930    }
2931    else if ( ( m_pcPic->getCU(m_uiCUAddr)->getCUPelY() + g_auiRasterToPelY[uiAbsPartIdx] + m_pcPic->getMinCUHeight() ) >= m_pcSlice->getSPS()->getPicHeightInLumaSamples() )
2932    {
2933    }
2934#endif
2935    else
2936    {
2937      if ( ( uiAbsPartIdx % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 ) &&           // is not at the last column of LCU
2938        ( uiAbsPartIdx / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) ) // is not at the last row    of LCU
2939      {
2940        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + uiNumPartInCUWidth + 1 ];
2941        uiLCUIdx = getAddr();
2942      }
2943      else if ( uiAbsPartIdx % uiNumPartInCUWidth < uiNumPartInCUWidth - 1 )           // is not at the last column of LCU But is last row of LCU
2944      {
2945        uiAbsPartAddr = g_auiRasterToZscan[ (uiAbsPartIdx + uiNumPartInCUWidth + 1) % m_pcPic->getNumPartInCU() ];
2946      }
2947      else if ( uiAbsPartIdx / uiNumPartInCUWidth < m_pcPic->getNumPartInHeight() - 1 ) // is not at the last row of LCU But is last column of LCU
2948      {
2949        uiAbsPartAddr = g_auiRasterToZscan[ uiAbsPartIdx + 1 ];
2950        uiLCUIdx = getAddr() + 1;
2951      }
2952      else //is the right bottom corner of LCU                       
2953      {
2954        uiAbsPartAddr = 0;
2955      }
2956    }
2957    if ( uiLCUIdx >= 0 && xGetColMVP( eRefPicList, uiLCUIdx, uiAbsPartAddr, cColMv, iRefIdx_Col ) )
2958    {
2959      pInfo->m_acMvCand[pInfo->iN++] = cColMv;
2960    }
2961    else 
2962    {
2963      UInt uiPartIdxCenter;
2964      UInt uiCurLCUIdx = getAddr();
2965      xDeriveCenterIdx( uiPartIdx, uiPartIdxCenter );
2966      if (xGetColMVP( eRefPicList, uiCurLCUIdx, uiPartIdxCenter,  cColMv, iRefIdx_Col ))
2967      {
2968        pInfo->m_acMvCand[pInfo->iN++] = cColMv;
2969      }
2970    }
2971    //----  co-located RightBottom Temporal Predictor  ---//
2972  }
2973
2974  if (pInfo->iN > AMVP_MAX_NUM_CANDS)
2975  {
2976    pInfo->iN = AMVP_MAX_NUM_CANDS;
2977  }
2978  while (pInfo->iN < AMVP_MAX_NUM_CANDS)
2979  {
2980      pInfo->m_acMvCand[pInfo->iN].set(0,0);
2981      pInfo->iN++;
2982  }
2983  return ;
2984}
2985
2986Bool TComDataCU::isBipredRestriction(UInt puIdx)
2987{
2988  Int width = 0;
2989  Int height = 0;
2990  UInt partAddr;
2991
2992  getPartIndexAndSize( puIdx, partAddr, width, height );
2993  if ( getWidth(0) == 8 && (width < 8 || height < 8) )
2994  {
2995    return true;
2996  }
2997  return false;
2998}
2999
3000Void TComDataCU::clipMv    (TComMv&  rcMv)
3001{
3002  Int  iMvShift = 2;
3003  Int iOffset = 8;
3004#if REPN_FORMAT_IN_VPS
3005  Int iHorMax = ( m_pcSlice->getPicWidthInLumaSamples() + iOffset - m_uiCUPelX - 1 ) << iMvShift;
3006#else
3007  Int iHorMax = ( m_pcSlice->getSPS()->getPicWidthInLumaSamples() + iOffset - m_uiCUPelX - 1 ) << iMvShift;
3008#endif
3009  Int iHorMin = (       -(Int)g_uiMaxCUWidth - iOffset - (Int)m_uiCUPelX + 1 ) << iMvShift;
3010 
3011#if REPN_FORMAT_IN_VPS
3012  Int iVerMax = ( m_pcSlice->getPicHeightInLumaSamples() + iOffset - m_uiCUPelY - 1 ) << iMvShift;
3013#else
3014  Int iVerMax = ( m_pcSlice->getSPS()->getPicHeightInLumaSamples() + iOffset - m_uiCUPelY - 1 ) << iMvShift;
3015#endif
3016  Int iVerMin = (       -(Int)g_uiMaxCUHeight - iOffset - (Int)m_uiCUPelY + 1 ) << iMvShift;
3017 
3018  rcMv.setHor( min (iHorMax, max (iHorMin, rcMv.getHor())) );
3019  rcMv.setVer( min (iVerMax, max (iVerMin, rcMv.getVer())) );
3020}
3021
3022UInt TComDataCU::getIntraSizeIdx(UInt uiAbsPartIdx)
3023{
3024  UInt uiShift = ( m_pePartSize[uiAbsPartIdx]==SIZE_NxN ? 1 : 0 );
3025 
3026  UChar uiWidth = m_puhWidth[uiAbsPartIdx]>>uiShift;
3027  UInt  uiCnt = 0;
3028  while( uiWidth )
3029  {
3030    uiCnt++;
3031    uiWidth>>=1;
3032  }
3033  uiCnt-=2;
3034  return uiCnt > 6 ? 6 : uiCnt;
3035}
3036
3037Void TComDataCU::clearCbf( UInt uiIdx, TextType eType, UInt uiNumParts )
3038{
3039  ::memset( &m_puhCbf[g_aucConvertTxtTypeToIdx[eType]][uiIdx], 0, sizeof(UChar)*uiNumParts);
3040}
3041
3042/** Set a I_PCM flag for all sub-partitions of a partition.
3043 * \param bIpcmFlag I_PCM flag
3044 * \param uiAbsPartIdx patition index
3045 * \param uiDepth CU depth
3046 * \returns Void
3047 */
3048Void TComDataCU::setIPCMFlagSubParts  (Bool bIpcmFlag, UInt uiAbsPartIdx, UInt uiDepth)
3049{
3050  UInt uiCurrPartNumb = m_pcPic->getNumPartInCU() >> (uiDepth << 1);
3051
3052  memset(m_pbIPCMFlag + uiAbsPartIdx, bIpcmFlag, sizeof(Bool)*uiCurrPartNumb );
3053}
3054
3055/** Test whether the current block is skipped
3056 * \param uiPartIdx Block index
3057 * \returns Flag indicating whether the block is skipped
3058 */
3059Bool TComDataCU::isSkipped( UInt uiPartIdx )
3060{
3061  return ( getSkipFlag( uiPartIdx ) );
3062}
3063
3064// ====================================================================================================================
3065// Protected member functions
3066// ====================================================================================================================
3067
3068Bool TComDataCU::xAddMVPCand( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
3069{
3070  TComDataCU* pcTmpCU = NULL;
3071  UInt uiIdx;
3072  switch( eDir )
3073  {
3074    case MD_LEFT:
3075    {
3076      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
3077      break;
3078    }
3079    case MD_ABOVE:
3080    {
3081      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx );
3082      break;
3083    }
3084    case MD_ABOVE_RIGHT:
3085    {
3086      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
3087      break;
3088    }
3089    case MD_BELOW_LEFT:
3090    {
3091      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
3092      break;
3093    }
3094    case MD_ABOVE_LEFT:
3095    {
3096      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
3097      break;
3098    }
3099    default:
3100    {
3101      break;
3102    }
3103  }
3104
3105  if ( pcTmpCU == NULL )
3106  {
3107    return false;
3108  }
3109 
3110  if ( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0 && m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC() == pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) ))
3111  {
3112    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
3113   
3114    pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
3115    return true;
3116  }
3117
3118  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
3119  if(       eRefPicList == REF_PIC_LIST_0 )
3120  {
3121    eRefPicList2nd = REF_PIC_LIST_1;
3122  }
3123  else if ( eRefPicList == REF_PIC_LIST_1)
3124  {
3125    eRefPicList2nd = REF_PIC_LIST_0;
3126  }
3127
3128
3129  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
3130  Int iNeibRefPOC;
3131
3132
3133  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0 )
3134  {
3135    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
3136    if( iNeibRefPOC == iCurrRefPOC ) // Same Reference Frame But Diff List//
3137    {
3138      TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
3139      pInfo->m_acMvCand[ pInfo->iN++] = cMvPred;
3140      return true;
3141    }
3142  }
3143  return false;
3144}
3145
3146/**
3147 * \param pInfo
3148 * \param eRefPicList
3149 * \param iRefIdx
3150 * \param uiPartUnitIdx
3151 * \param eDir
3152 * \returns Bool
3153 */
3154Bool TComDataCU::xAddMVPCandOrder( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir )
3155{
3156  TComDataCU* pcTmpCU = NULL;
3157  UInt uiIdx;
3158  switch( eDir )
3159  {
3160  case MD_LEFT:
3161    {
3162      pcTmpCU = getPULeft(uiIdx, uiPartUnitIdx);
3163      break;
3164    }
3165  case MD_ABOVE:
3166    {
3167      pcTmpCU = getPUAbove(uiIdx, uiPartUnitIdx);
3168      break;
3169    }
3170  case MD_ABOVE_RIGHT:
3171    {
3172      pcTmpCU = getPUAboveRight(uiIdx, uiPartUnitIdx);
3173      break;
3174    }
3175  case MD_BELOW_LEFT:
3176    {
3177      pcTmpCU = getPUBelowLeft(uiIdx, uiPartUnitIdx);
3178      break;
3179    }
3180  case MD_ABOVE_LEFT:
3181    {
3182      pcTmpCU = getPUAboveLeft(uiIdx, uiPartUnitIdx);
3183      break;
3184    }
3185  default:
3186    {
3187      break;
3188    }
3189  }
3190
3191  if ( pcTmpCU == NULL ) 
3192  {
3193    return false;
3194  }
3195 
3196  RefPicList eRefPicList2nd = REF_PIC_LIST_0;
3197  if(       eRefPicList == REF_PIC_LIST_0 )
3198  {
3199    eRefPicList2nd = REF_PIC_LIST_1;
3200  }
3201  else if ( eRefPicList == REF_PIC_LIST_1)
3202  {
3203    eRefPicList2nd = REF_PIC_LIST_0;
3204  }
3205
3206  Int iCurrPOC = m_pcSlice->getPOC();
3207  Int iCurrRefPOC = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getPOC();
3208  Int iNeibPOC = iCurrPOC;
3209  Int iNeibRefPOC;
3210
3211  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic( eRefPicList, iRefIdx)->getIsLongTerm();
3212  Bool bIsNeibRefLongTerm = false;
3213  //---------------  V1 (END) ------------------//
3214  if( pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) >= 0)
3215  {
3216    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) );
3217    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList)->getMv(uiIdx);
3218    TComMv rcMv;
3219
3220    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList, pcTmpCU->getCUMvField(eRefPicList)->getRefIdx(uiIdx) )->getIsLongTerm();
3221    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm ) 
3222    {
3223    if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
3224    {
3225      rcMv = cMvPred;
3226    }
3227    else
3228    {
3229      Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
3230      if ( iScale == 4096 )
3231      {
3232        rcMv = cMvPred;
3233      }
3234      else
3235      {
3236        rcMv = cMvPred.scaleMv( iScale );
3237      }
3238    }
3239    pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
3240    return true;
3241    }
3242  }
3243  //---------------------- V2(END) --------------------//
3244  if( pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) >= 0)
3245  {
3246    iNeibRefPOC = pcTmpCU->getSlice()->getRefPOC( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) );
3247    TComMv cMvPred = pcTmpCU->getCUMvField(eRefPicList2nd)->getMv(uiIdx);
3248    TComMv rcMv;
3249
3250    bIsNeibRefLongTerm = pcTmpCU->getSlice()->getRefPic( eRefPicList2nd, pcTmpCU->getCUMvField(eRefPicList2nd)->getRefIdx(uiIdx) )->getIsLongTerm();
3251    if ( bIsCurrRefLongTerm == bIsNeibRefLongTerm ) 
3252    {
3253    if ( bIsCurrRefLongTerm || bIsNeibRefLongTerm )
3254    {
3255      rcMv = cMvPred;
3256    }
3257    else
3258    {
3259      Int iScale = xGetDistScaleFactor( iCurrPOC, iCurrRefPOC, iNeibPOC, iNeibRefPOC );
3260      if ( iScale == 4096 )
3261      {
3262        rcMv = cMvPred;
3263      }
3264      else
3265      {
3266        rcMv = cMvPred.scaleMv( iScale );
3267      }
3268    }
3269    pInfo->m_acMvCand[ pInfo->iN++] = rcMv;
3270    return true;
3271    }
3272  }
3273  //---------------------- V3(END) --------------------//
3274  return false;
3275}
3276
3277/**
3278 * \param eRefPicList
3279 * \param uiCUAddr
3280 * \param uiPartUnitIdx
3281 * \param riRefIdx
3282 * \returns Bool
3283 */
3284Bool TComDataCU::xGetColMVP( RefPicList eRefPicList, Int uiCUAddr, Int uiPartUnitIdx, TComMv& rcMv, Int& riRefIdx )
3285{
3286  UInt uiAbsPartAddr = uiPartUnitIdx;
3287
3288  RefPicList  eColRefPicList;
3289  Int iColPOC, iColRefPOC, iCurrPOC, iCurrRefPOC, iScale;
3290  TComMv cColMv;
3291
3292  // use coldir.
3293  TComPic *pColPic = getSlice()->getRefPic( RefPicList(getSlice()->isInterB() ? 1-getSlice()->getColFromL0Flag() : 0), getSlice()->getColRefIdx());
3294  TComDataCU *pColCU = pColPic->getCU( uiCUAddr );
3295  if(pColCU->getPic()==0||pColCU->getPartitionSize(uiPartUnitIdx)==SIZE_NONE)
3296  {
3297    return false;
3298  }
3299  iCurrPOC = m_pcSlice->getPOC();   
3300  iColPOC = pColCU->getSlice()->getPOC(); 
3301
3302  if (pColCU->isIntra(uiAbsPartAddr))
3303  {
3304    return false;
3305  }
3306  eColRefPicList = getSlice()->getCheckLDC() ? eRefPicList : RefPicList(getSlice()->getColFromL0Flag());
3307
3308  Int iColRefIdx = pColCU->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
3309
3310  if (iColRefIdx < 0 )
3311  {
3312    eColRefPicList = RefPicList(1 - eColRefPicList);
3313    iColRefIdx = pColCU->getCUMvField(RefPicList(eColRefPicList))->getRefIdx(uiAbsPartAddr);
3314
3315    if (iColRefIdx < 0 )
3316    {
3317      return false;
3318    }
3319  }
3320
3321  // Scale the vector.
3322  iColRefPOC = pColCU->getSlice()->getRefPOC(eColRefPicList, iColRefIdx);
3323  cColMv = pColCU->getCUMvField(eColRefPicList)->getMv(uiAbsPartAddr);
3324
3325  iCurrRefPOC = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getPOC();
3326  Bool bIsCurrRefLongTerm = m_pcSlice->getRefPic(eRefPicList, riRefIdx)->getIsLongTerm();
3327  Bool bIsColRefLongTerm = pColCU->getSlice()->getIsUsedAsLongTerm(eColRefPicList, iColRefIdx);
3328
3329  if ( bIsCurrRefLongTerm != bIsColRefLongTerm ) 
3330  {
3331    return false;
3332  }
3333
3334  if ( bIsCurrRefLongTerm || bIsColRefLongTerm )
3335  {
3336    rcMv = cColMv;
3337  }
3338  else
3339  {
3340    iScale = xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iColPOC, iColRefPOC);
3341    if ( iScale == 4096 )
3342    {
3343      rcMv = cColMv;
3344    }
3345    else
3346    {
3347      rcMv = cColMv.scaleMv( iScale );
3348    }
3349  }
3350  return true;
3351}
3352
3353UInt TComDataCU::xGetMvdBits(TComMv cMvd)
3354{
3355  return ( xGetComponentBits(cMvd.getHor()) + xGetComponentBits(cMvd.getVer()) );
3356}
3357
3358UInt TComDataCU::xGetComponentBits(Int iVal)
3359{
3360  UInt uiLength = 1;
3361  UInt uiTemp   = ( iVal <= 0) ? (-iVal<<1)+1: (iVal<<1);
3362 
3363  assert ( uiTemp );
3364 
3365  while ( 1 != uiTemp )
3366  {
3367    uiTemp >>= 1;
3368    uiLength += 2;
3369  }
3370 
3371  return uiLength;
3372}
3373
3374
3375Int TComDataCU::xGetDistScaleFactor(Int iCurrPOC, Int iCurrRefPOC, Int iColPOC, Int iColRefPOC)
3376{
3377  Int iDiffPocD = iColPOC - iColRefPOC;
3378  Int iDiffPocB = iCurrPOC - iCurrRefPOC;
3379 
3380  if( iDiffPocD == iDiffPocB )
3381  {
3382    return 4096;
3383  }
3384  else
3385  {
3386    Int iTDB      = Clip3( -128, 127, iDiffPocB );
3387    Int iTDD      = Clip3( -128, 127, iDiffPocD );
3388    Int iX        = (0x4000 + abs(iTDD/2)) / iTDD;
3389    Int iScale    = Clip3( -4096, 4095, (iTDB * iX + 32) >> 6 );
3390    return iScale;
3391  }
3392}
3393
3394/**
3395 * \param eCUMode
3396 * \param uiPartIdx
3397 * \param ruiPartIdxCenter
3398 * \returns Void
3399 */
3400Void TComDataCU::xDeriveCenterIdx( UInt uiPartIdx, UInt& ruiPartIdxCenter )
3401{
3402  UInt uiPartAddr;
3403  Int  iPartWidth;
3404  Int  iPartHeight;
3405  getPartIndexAndSize( uiPartIdx, uiPartAddr, iPartWidth, iPartHeight);
3406 
3407  ruiPartIdxCenter = m_uiAbsIdxInLCU+uiPartAddr; // partition origin.
3408  ruiPartIdxCenter = g_auiRasterToZscan[ g_auiZscanToRaster[ ruiPartIdxCenter ]
3409                                        + ( iPartHeight/m_pcPic->getMinCUHeight()  )/2*m_pcPic->getNumPartInWidth()
3410                                        + ( iPartWidth/m_pcPic->getMinCUWidth()  )/2];
3411}
3412
3413Void TComDataCU::compressMV()
3414{
3415  Int scaleFactor = 4 * AMVP_DECIMATION_FACTOR / m_unitSize;
3416  if (scaleFactor > 0)
3417  {
3418    m_acCUMvField[0].compress(m_pePredMode, scaleFactor);
3419    m_acCUMvField[1].compress(m_pePredMode, scaleFactor);   
3420  }
3421}
3422
3423UInt TComDataCU::getCoefScanIdx(UInt uiAbsPartIdx, UInt uiWidth, Bool bIsLuma, Bool bIsIntra)
3424{
3425  UInt uiCTXIdx;
3426  UInt uiScanIdx;
3427  UInt uiDirMode;
3428
3429  if ( !bIsIntra ) 
3430  {
3431    uiScanIdx = SCAN_DIAG;
3432    return uiScanIdx;
3433  }
3434
3435  switch(uiWidth)
3436  {
3437    case  2: uiCTXIdx = 6; break;
3438    case  4: uiCTXIdx = 5; break;
3439    case  8: uiCTXIdx = 4; break;
3440    case 16: uiCTXIdx = 3; break;
3441    case 32: uiCTXIdx = 2; break;
3442    case 64: uiCTXIdx = 1; break;
3443    default: uiCTXIdx = 0; break;
3444  }
3445
3446  if ( bIsLuma )
3447  {
3448    uiDirMode = getLumaIntraDir(uiAbsPartIdx);
3449    uiScanIdx = SCAN_DIAG;
3450    if (uiCTXIdx >3 && uiCTXIdx < 6) //if multiple scans supported for transform size
3451    {
3452      uiScanIdx = abs((Int) uiDirMode - VER_IDX) < 5 ? SCAN_HOR : (abs((Int)uiDirMode - HOR_IDX) < 5 ? SCAN_VER : SCAN_DIAG);
3453    }
3454  }
3455  else
3456  {
3457    uiDirMode = getChromaIntraDir(uiAbsPartIdx);
3458    if( uiDirMode == DM_CHROMA_IDX )
3459    {
3460      // get number of partitions in current CU
3461      UInt depth = getDepth(uiAbsPartIdx);
3462      UInt numParts = getPic()->getNumPartInCU() >> (2 * depth);
3463     
3464      // get luma mode from upper-left corner of current CU
3465      uiDirMode = getLumaIntraDir((uiAbsPartIdx/numParts)*numParts);
3466    }
3467    uiScanIdx = SCAN_DIAG;
3468    if (uiCTXIdx >4 && uiCTXIdx < 7) //if multiple scans supported for transform size
3469    {
3470      uiScanIdx = abs((Int) uiDirMode - VER_IDX) < 5 ? SCAN_HOR : (abs((Int)uiDirMode - HOR_IDX) < 5 ? SCAN_VER : SCAN_DIAG);
3471    }
3472  }
3473
3474  return uiScanIdx;
3475}
3476
3477UInt TComDataCU::getSCUAddr()
3478{ 
3479  return getPic()->getPicSym()->getInverseCUOrderMap(m_uiCUAddr)*(1<<(m_pcSlice->getSPS()->getMaxCUDepth()<<1))+m_uiAbsIdxInLCU; 
3480}
3481
3482#if SVC_EXTENSION
3483TComDataCU*  TComDataCU::getBaseColCU( UInt refLayerIdc, UInt uiCuAbsPartIdx, UInt &uiCUAddrBase, UInt &uiAbsPartIdxBase, Int iMotionMapping )
3484{
3485  UInt uiPelX = getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiCuAbsPartIdx] ];
3486  UInt uiPelY = getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiCuAbsPartIdx] ];
3487
3488  return getBaseColCU( refLayerIdc, uiPelX, uiPelY, uiCUAddrBase, uiAbsPartIdxBase, iMotionMapping );
3489}
3490
3491TComDataCU*  TComDataCU::getBaseColCU( UInt refLayerIdc, UInt uiPelX, UInt uiPelY, UInt &uiCUAddrBase, UInt &uiAbsPartIdxBase, Int iMotionMapping )
3492{
3493  TComPic* baseColPic = m_pcSlice->getBaseColPic(refLayerIdc);
3494
3495  uiPelX = (UInt)Clip3<UInt>(0, m_pcPic->getPicYuvRec()->getWidth() - 1, uiPelX);
3496  uiPelY = (UInt)Clip3<UInt>(0, m_pcPic->getPicYuvRec()->getHeight() - 1, uiPelY);
3497
3498#if !LAYER_CTB
3499  UInt uiMinUnitSize = m_pcPic->getMinCUWidth();
3500#endif
3501
3502#if O0098_SCALED_REF_LAYER_ID
3503  Int leftStartL = baseColPic->getSlice(0)->getSPS()->getScaledRefLayerWindowForLayer(baseColPic->getSlice(0)->getVPS()->getRefLayerId(getSlice()->getLayerId(), refLayerIdc)).getWindowLeftOffset();
3504  Int topStartL  = baseColPic->getSlice(0)->getSPS()->getScaledRefLayerWindowForLayer(baseColPic->getSlice(0)->getVPS()->getRefLayerId(getSlice()->getLayerId(), refLayerIdc)).getWindowTopOffset();
3505#else
3506  Int leftStartL = baseColPic->getSlice(0)->getSPS()->getScaledRefLayerWindow(refLayerIdc).getWindowLeftOffset();
3507  Int topStartL  = baseColPic->getSlice(0)->getSPS()->getScaledRefLayerWindow(refLayerIdc).getWindowTopOffset();
3508#endif
3509
3510#if Q0200_CONFORMANCE_BL_SIZE
3511  Int chromaFormatIdc = baseColPic->getSlice(0)->getChromaFormatIdc();
3512  Int iBX = (((uiPelX - leftStartL)*g_posScalingFactor[refLayerIdc][0] + (1<<15)) >> 16) + baseColPic->getConformanceWindow().getWindowLeftOffset() * TComSPS::getWinUnitX( chromaFormatIdc );
3513  Int iBY = (((uiPelY - topStartL )*g_posScalingFactor[refLayerIdc][1] + (1<<15)) >> 16) + baseColPic->getConformanceWindow().getWindowTopOffset() * TComSPS::getWinUnitY( chromaFormatIdc );
3514#else
3515  Int iBX = ((uiPelX - leftStartL)*g_posScalingFactor[refLayerIdc][0] + (1<<15)) >> 16;
3516  Int iBY = ((uiPelY - topStartL )*g_posScalingFactor[refLayerIdc][1] + (1<<15)) >> 16;
3517#endif
3518
3519#if REF_IDX_MFM
3520  // offset for collocated block in the motion mapping
3521  if( iMotionMapping == 1 )
3522  {
3523    Bool unequalPictureSizeFlag = g_posScalingFactor[refLayerIdc][0] != 65536 || g_posScalingFactor[refLayerIdc][1] != 65536; //the condition should be updated according to the WD.
3524
3525    // actually, motion field compression is performed in the Void TComPic::compressMotion() function, but with (+4) the rounding may have effect on the picture boundary check.
3526    if( unequalPictureSizeFlag )
3527    {
3528      iBX = ( ( iBX + 4 ) >> 4 ) << 4;
3529      iBY = ( ( iBY + 4 ) >> 4 ) << 4;
3530    }
3531    else
3532    {
3533      iBX += 4;
3534      iBY += 4;
3535    }
3536  }
3537#endif
3538
3539  if ( iBX < 0 || iBX >= baseColPic->getPicYuvRec()->getWidth() || iBY < 0 || iBY >= baseColPic->getPicYuvRec()->getHeight() )
3540  {
3541    return NULL;
3542  }
3543
3544#if LAYER_CTB
3545  UInt baseMaxCUHeight = baseColPic->getPicSym()->getMaxCUHeight();
3546  UInt baseMaxCUWidth  = baseColPic->getPicSym()->getMaxCUWidth();
3547  UInt baseMinUnitSize = baseColPic->getMinCUWidth();
3548 
3549  uiCUAddrBase = ( iBY / baseMaxCUHeight ) * baseColPic->getFrameWidthInCU() + ( iBX / baseMaxCUWidth );
3550#else
3551  uiCUAddrBase = (iBY/g_uiMaxCUHeight)*baseColPic->getFrameWidthInCU() + (iBX/g_uiMaxCUWidth);
3552#endif
3553
3554  assert(uiCUAddrBase < baseColPic->getNumCUsInFrame());
3555
3556#if LAYER_CTB
3557  UInt uiRasterAddrBase = ( iBY - (iBY/baseMaxCUHeight)*baseMaxCUHeight ) / baseMinUnitSize * baseColPic->getNumPartInWidth() + ( iBX - (iBX/baseMaxCUWidth)*baseMaxCUWidth ) / baseMinUnitSize;
3558 
3559  uiAbsPartIdxBase = g_auiLayerRasterToZscan[baseColPic->getLayerId()][uiRasterAddrBase];
3560#else
3561  UInt uiRasterAddrBase = (iBY - (iBY/g_uiMaxCUHeight)*g_uiMaxCUHeight)/uiMinUnitSize*baseColPic->getNumPartInWidth()
3562    + (iBX - (iBX/g_uiMaxCUWidth)*g_uiMaxCUWidth)/uiMinUnitSize;
3563
3564  uiAbsPartIdxBase = g_auiRasterToZscan[uiRasterAddrBase];
3565#endif
3566
3567  return baseColPic->getCU(uiCUAddrBase);
3568}
3569
3570Void TComDataCU::scaleBaseMV( UInt refLayerIdc, TComMvField& rcMvFieldEnhance, TComMvField& rcMvFieldBase )
3571{
3572  TComMvField cMvFieldBase;
3573  TComMv cMv;
3574
3575  cMv = rcMvFieldBase.getMv().scaleMv( g_mvScalingFactor[refLayerIdc][0], g_mvScalingFactor[refLayerIdc][1] );
3576
3577  rcMvFieldEnhance.setMvField( cMv, rcMvFieldBase.getRefIdx() );
3578}
3579
3580#if FAST_INTRA_SHVC
3581/** generate limited set of remaining modes
3582*\param   uiAbsPartIdx
3583*\param   uiIntraDirPred  pointer to the array for MPM storage
3584*\returns Number of intra coding modes (nb of remaining modes + 3 MPMs)
3585*/
3586Int TComDataCU::reduceSetOfIntraModes( UInt uiAbsPartIdx, Int* uiIntraDirPred, Int &fullSetOfModes )
3587{
3588  // check BL mode
3589  UInt          uiCUAddrBase = 0, uiAbsPartAddrBase = 0;
3590  // the right reference layerIdc should be specified, currently it is set to m_layerId-1
3591  TComDataCU*   pcTempCU = getBaseColCU(m_layerId - 1, uiAbsPartIdx, uiCUAddrBase, uiAbsPartAddrBase, 0 );
3592
3593  if( pcTempCU->getPredictionMode( uiAbsPartAddrBase ) != MODE_INTRA )
3594  {
3595    return( NUM_INTRA_MODE-1 );
3596  }
3597
3598  // compute set of enabled modes g_reducedSetIntraModes[...]
3599  Int authorizedMode[NUM_INTRA_MODE-1]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
3600  Int nbModes;
3601  for (nbModes=0; nbModes<3; nbModes++)  // add 3 MPMs 1st
3602  {
3603    g_reducedSetIntraModes[nbModes] = uiIntraDirPred[nbModes];
3604    authorizedMode[ uiIntraDirPred[nbModes] ] = 0;
3605  }
3606
3607  Int iColBaseDir = pcTempCU->getLumaIntraDir( uiAbsPartAddrBase );
3608  if ( authorizedMode[iColBaseDir] )  //possibly add BL mode
3609  {
3610    g_reducedSetIntraModes[nbModes++] = iColBaseDir;
3611    authorizedMode[ iColBaseDir ] = 0;
3612  }
3613
3614  Int iRefMode = ( iColBaseDir > 1 ) ? iColBaseDir : uiIntraDirPred[0];
3615  if ( iRefMode > 1 )    //add neighboring modes of refMode
3616  {
3617    UInt Left  = iRefMode;
3618    UInt Right = iRefMode;
3619    while ( nbModes < NB_REMAIN_MODES+3 )
3620    {
3621      Left = ((Left + 29) % 32) + 2;
3622      Right = ((Right - 1 ) % 32) + 2;
3623      if ( authorizedMode[Left] )   g_reducedSetIntraModes[nbModes++] = Left;
3624      if ( authorizedMode[Right] )  g_reducedSetIntraModes[nbModes++] = Right;
3625    }
3626  }
3627  else      //add pre-defined modes
3628  {
3629    Int  idx = 0;
3630    while ( nbModes < NB_REMAIN_MODES+3 )
3631    {
3632      UInt mode = g_predefSetIntraModes[idx++];
3633      if ( authorizedMode[mode] )   g_reducedSetIntraModes[nbModes++] = mode;
3634    }
3635  }
3636
3637  fullSetOfModes = 0;
3638  return ( nbModes );
3639}
3640#endif
3641
3642#if REF_IDX_ME_ZEROMV
3643Bool TComDataCU::xCheckZeroMVILRMerge(UChar uhInterDir, TComMvField& cMvFieldL0, TComMvField& cMvFieldL1)
3644{
3645  Bool checkZeroMVILR = true;
3646
3647  if(uhInterDir&0x1)  //list0
3648  {
3649    Int refIdxL0 = cMvFieldL0.getRefIdx();
3650    TComPic* refPic = m_pcSlice->getRefPic(REF_PIC_LIST_0, refIdxL0);
3651
3652    if(refPic->isILR(m_layerId))
3653    {
3654      checkZeroMVILR &= (cMvFieldL0.getHor() == 0 && cMvFieldL0.getVer() == 0);
3655
3656      // It is a requirement of bitstream conformance that when the reference picture represented by the variable refIdxLX is an inter-layer reference picture,
3657      // VpsInterLayerSamplePredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture
3658      checkZeroMVILR &= m_pcSlice->getVPS()->isSamplePredictionType( m_layerId, refPic->getLayerId() );
3659    }
3660  }
3661  if(uhInterDir&0x2)  //list1
3662  {
3663    Int refIdxL1  = cMvFieldL1.getRefIdx();
3664    TComPic* refPic = m_pcSlice->getRefPic(REF_PIC_LIST_1, refIdxL1);
3665
3666    if(refPic->isILR(m_layerId))
3667    {
3668      checkZeroMVILR &= (cMvFieldL1.getHor() == 0 && cMvFieldL1.getVer() == 0);
3669
3670      // It is a requirement of bitstream conformance that when the reference picture represented by the variable refIdxLX is an inter-layer reference picture,
3671      // VpsInterLayerSamplePredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture
3672      checkZeroMVILR &= m_pcSlice->getVPS()->isSamplePredictionType( m_layerId, refPic->getLayerId() );
3673    }
3674  }
3675
3676  return checkZeroMVILR;
3677}
3678
3679Bool TComDataCU::xCheckZeroMVILRMvdL1Zero(Int iRefList, Int iRefIdx, Int MvpIdx)
3680{
3681  RefPicList eRefPicList = iRefList > 0? REF_PIC_LIST_1: REF_PIC_LIST_0;
3682  assert(eRefPicList == REF_PIC_LIST_1);
3683
3684  Bool checkZeroMVILR = true;
3685
3686  if(getSlice()->getRefPic(eRefPicList, iRefIdx)->isILR(m_layerId))
3687  {
3688    AMVPInfo* pcAMVPInfo = getCUMvField(eRefPicList)->getAMVPInfo();
3689    TComMv    cMv        = pcAMVPInfo->m_acMvCand[MvpIdx];
3690    checkZeroMVILR &= (cMv.getHor() == 0 && cMv.getVer() == 0);
3691  }
3692
3693  return checkZeroMVILR;
3694}
3695#endif
3696
3697#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3698Bool TComDataCU::isInterLayerReference(UChar uhInterDir, TComMvField& cMvFieldL0, TComMvField& cMvFieldL1)
3699{
3700  Bool checkILR = false;
3701
3702  if(uhInterDir&0x1)  //list0
3703  {
3704    Int refIdxL0 = cMvFieldL0.getRefIdx();
3705    checkILR = getSlice()->getRefPic(REF_PIC_LIST_0, refIdxL0)->isILR(m_layerId);
3706  }
3707  if(uhInterDir&0x2)  //list1
3708  {
3709    Int refIdxL1  = cMvFieldL1.getRefIdx();
3710    checkILR = checkILR || getSlice()->getRefPic(REF_PIC_LIST_1, refIdxL1)->isILR(m_layerId);
3711  }
3712
3713  return checkILR;
3714}
3715#endif
3716
3717#endif //SVC_EXTENSION
3718//! \}
Note: See TracBrowser for help on using the repository browser.