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