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