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

Last change on this file since 1263 was 1260, checked in by seregin, 9 years ago

port rev 4257

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