source: SHVCSoftware/branches/SHM-5.1-dev/source/Lib/TLibCommon/TComDataCU.cpp @ 614

Last change on this file since 614 was 595, checked in by seregin, 11 years ago

merge with SHM-5.0-dev branch

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