source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/TEncSearch.cpp @ 1353

Last change on this file since 1353 was 1335, checked in by seregin, 9 years ago

port rev 4413

  • Property svn:eol-style set to native
File size: 224.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2015, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncSearch.cpp
35 \brief    encoder search class
36 */
37
38#include "TLibCommon/CommonDef.h"
39#include "TLibCommon/TComRom.h"
40#include "TLibCommon/TComMotionInfo.h"
41#include "TEncSearch.h"
42#include "TLibCommon/TComTU.h"
43#include "TLibCommon/Debug.h"
44#include <math.h>
45#include <limits>
46
47
48//! \ingroup TLibEncoder
49//! \{
50
51static const TComMv s_acMvRefineH[9] =
52{
53  TComMv(  0,  0 ), // 0
54  TComMv(  0, -1 ), // 1
55  TComMv(  0,  1 ), // 2
56  TComMv( -1,  0 ), // 3
57  TComMv(  1,  0 ), // 4
58  TComMv( -1, -1 ), // 5
59  TComMv(  1, -1 ), // 6
60  TComMv( -1,  1 ), // 7
61  TComMv(  1,  1 )  // 8
62};
63
64static const TComMv s_acMvRefineQ[9] =
65{
66  TComMv(  0,  0 ), // 0
67  TComMv(  0, -1 ), // 1
68  TComMv(  0,  1 ), // 2
69  TComMv( -1, -1 ), // 5
70  TComMv(  1, -1 ), // 6
71  TComMv( -1,  0 ), // 3
72  TComMv(  1,  0 ), // 4
73  TComMv( -1,  1 ), // 7
74  TComMv(  1,  1 )  // 8
75};
76
77static const UInt s_auiDFilter[9] =
78{
79  0, 1, 0,
80  2, 3, 2,
81  0, 1, 0
82};
83
84static Void offsetSubTUCBFs(TComTU &rTu, const ComponentID compID)
85{
86        TComDataCU *pcCU              = rTu.getCU();
87  const UInt        uiTrDepth         = rTu.GetTransformDepthRel();
88  const UInt        uiAbsPartIdx      = rTu.GetAbsPartIdxTU(compID);
89  const UInt        partIdxesPerSubTU = rTu.GetAbsPartIdxNumParts(compID) >> 1;
90
91  //move the CBFs down a level and set the parent CBF
92
93  UChar subTUCBF[2];
94  UChar combinedSubTUCBF = 0;
95
96  for (UInt subTU = 0; subTU < 2; subTU++)
97  {
98    const UInt subTUAbsPartIdx = uiAbsPartIdx + (subTU * partIdxesPerSubTU);
99
100    subTUCBF[subTU]   = pcCU->getCbf(subTUAbsPartIdx, compID, uiTrDepth);
101    combinedSubTUCBF |= subTUCBF[subTU];
102  }
103
104  for (UInt subTU = 0; subTU < 2; subTU++)
105  {
106    const UInt subTUAbsPartIdx = uiAbsPartIdx + (subTU * partIdxesPerSubTU);
107    const UChar compositeCBF = (subTUCBF[subTU] << 1) | combinedSubTUCBF;
108
109    pcCU->setCbfPartRange((compositeCBF << uiTrDepth), compID, subTUAbsPartIdx, partIdxesPerSubTU);
110  }
111}
112
113
114TEncSearch::TEncSearch()
115{
116  for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
117  {
118    m_ppcQTTempCoeff[ch]                           = NULL;
119    m_pcQTTempCoeff[ch]                            = NULL;
120#if ADAPTIVE_QP_SELECTION
121    m_ppcQTTempArlCoeff[ch]                        = NULL;
122    m_pcQTTempArlCoeff[ch]                         = NULL;
123#endif
124    m_puhQTTempCbf[ch]                             = NULL;
125    m_phQTTempCrossComponentPredictionAlpha[ch]    = NULL;
126    m_pSharedPredTransformSkip[ch]                 = NULL;
127    m_pcQTTempTUCoeff[ch]                          = NULL;
128#if ADAPTIVE_QP_SELECTION
129    m_ppcQTTempTUArlCoeff[ch]                      = NULL;
130#endif
131    m_puhQTTempTransformSkipFlag[ch]               = NULL;
132  }
133  m_puhQTTempTrIdx                                 = NULL;
134  m_pcQTTempTComYuv                                = NULL;
135  m_pcEncCfg                                       = NULL;
136  m_pcEntropyCoder                                 = NULL;
137  m_pTempPel                                       = NULL;
138  setWpScalingDistParam( NULL, -1, REF_PIC_LIST_X );
139}
140
141
142
143
144TEncSearch::~TEncSearch()
145{
146  if ( m_pTempPel )
147  {
148    delete [] m_pTempPel;
149    m_pTempPel = NULL;
150  }
151
152  if ( m_pcEncCfg )
153  {
154    const UInt uiNumLayersAllocated = m_pcEncCfg->getQuadtreeTULog2MaxSize()-m_pcEncCfg->getQuadtreeTULog2MinSize()+1;
155
156    for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
157    {
158      for (UInt layer = 0; layer < uiNumLayersAllocated; layer++)
159      {
160        delete[] m_ppcQTTempCoeff[ch][layer];
161#if ADAPTIVE_QP_SELECTION
162        delete[] m_ppcQTTempArlCoeff[ch][layer];
163#endif
164      }
165      delete[] m_ppcQTTempCoeff[ch];
166      delete[] m_pcQTTempCoeff[ch];
167      delete[] m_puhQTTempCbf[ch];
168#if ADAPTIVE_QP_SELECTION
169      delete[] m_ppcQTTempArlCoeff[ch];
170      delete[] m_pcQTTempArlCoeff[ch];
171#endif
172    }
173
174    for( UInt layer = 0; layer < uiNumLayersAllocated; layer++ )
175    {
176      m_pcQTTempTComYuv[layer].destroy();
177    }
178  }
179
180  delete[] m_puhQTTempTrIdx;
181  delete[] m_pcQTTempTComYuv;
182
183  for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
184  {
185    delete[] m_pSharedPredTransformSkip[ch];
186    delete[] m_pcQTTempTUCoeff[ch];
187#if ADAPTIVE_QP_SELECTION
188    delete[] m_ppcQTTempTUArlCoeff[ch];
189#endif
190    delete[] m_phQTTempCrossComponentPredictionAlpha[ch];
191    delete[] m_puhQTTempTransformSkipFlag[ch];
192  }
193  m_pcQTTempTransformSkipTComYuv.destroy();
194
195  m_tmpYuvPred.destroy();
196}
197
198
199
200
201Void TEncSearch::init(TEncCfg*      pcEncCfg,
202                      TComTrQuant*  pcTrQuant,
203                      Int           iSearchRange,
204                      Int           bipredSearchRange,
205                      Int           iFastSearch,
206                      const UInt    maxCUWidth,
207                      const UInt    maxCUHeight,
208                      const UInt    maxTotalCUDepth,
209                      TEncEntropy*  pcEntropyCoder,
210                      TComRdCost*   pcRdCost,
211                      TEncSbac*** pppcRDSbacCoder,
212                      TEncSbac*   pcRDGoOnSbacCoder
213                      )
214{
215  m_pcEncCfg             = pcEncCfg;
216  m_pcTrQuant            = pcTrQuant;
217  m_iSearchRange         = iSearchRange;
218  m_bipredSearchRange    = bipredSearchRange;
219  m_iFastSearch          = iFastSearch;
220  m_pcEntropyCoder       = pcEntropyCoder;
221  m_pcRdCost             = pcRdCost;
222
223  m_pppcRDSbacCoder     = pppcRDSbacCoder;
224  m_pcRDGoOnSbacCoder   = pcRDGoOnSbacCoder;
225
226  for (UInt iDir = 0; iDir < MAX_NUM_REF_LIST_ADAPT_SR; iDir++)
227  {
228    for (UInt iRefIdx = 0; iRefIdx < MAX_IDX_ADAPT_SR; iRefIdx++)
229    {
230      m_aaiAdaptSR[iDir][iRefIdx] = iSearchRange;
231    }
232  }
233
234  m_puiDFilter = s_auiDFilter + 4;
235
236  // initialize motion cost
237  for( Int iNum = 0; iNum < AMVP_MAX_NUM_CANDS+1; iNum++)
238  {
239    for( Int iIdx = 0; iIdx < AMVP_MAX_NUM_CANDS; iIdx++)
240    {
241      if (iIdx < iNum)
242      {
243        m_auiMVPIdxCost[iIdx][iNum] = xGetMvpIdxBits(iIdx, iNum);
244      }
245      else
246      {
247        m_auiMVPIdxCost[iIdx][iNum] = MAX_INT;
248      }
249    }
250  }
251
252  const ChromaFormat cform=pcEncCfg->getChromaFormatIdc();
253  initTempBuff(cform);
254
255  m_pTempPel = new Pel[maxCUWidth*maxCUHeight];
256
257  const UInt uiNumLayersToAllocate = pcEncCfg->getQuadtreeTULog2MaxSize()-pcEncCfg->getQuadtreeTULog2MinSize()+1;
258  const UInt uiNumPartitions = 1<<(maxTotalCUDepth<<1);
259  for (UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
260  {
261    const UInt csx=::getComponentScaleX(ComponentID(ch), cform);
262    const UInt csy=::getComponentScaleY(ComponentID(ch), cform);
263    m_ppcQTTempCoeff[ch] = new TCoeff* [uiNumLayersToAllocate];
264    m_pcQTTempCoeff[ch]   = new TCoeff [(maxCUWidth*maxCUHeight)>>(csx+csy)   ];
265#if ADAPTIVE_QP_SELECTION
266    m_ppcQTTempArlCoeff[ch]  = new TCoeff*[uiNumLayersToAllocate];
267    m_pcQTTempArlCoeff[ch]   = new TCoeff [(maxCUWidth*maxCUHeight)>>(csx+csy)   ];
268#endif
269    m_puhQTTempCbf[ch] = new UChar  [uiNumPartitions];
270
271    for (UInt layer = 0; layer < uiNumLayersToAllocate; layer++)
272    {
273      m_ppcQTTempCoeff[ch][layer] = new TCoeff[(maxCUWidth*maxCUHeight)>>(csx+csy)];
274#if ADAPTIVE_QP_SELECTION
275      m_ppcQTTempArlCoeff[ch][layer]  = new TCoeff[(maxCUWidth*maxCUHeight)>>(csx+csy) ];
276#endif
277    }
278
279    m_phQTTempCrossComponentPredictionAlpha[ch]    = new Char  [uiNumPartitions];
280    m_pSharedPredTransformSkip[ch]                 = new Pel   [MAX_CU_SIZE*MAX_CU_SIZE];
281    m_pcQTTempTUCoeff[ch]                          = new TCoeff[MAX_CU_SIZE*MAX_CU_SIZE];
282#if ADAPTIVE_QP_SELECTION
283    m_ppcQTTempTUArlCoeff[ch]                      = new TCoeff[MAX_CU_SIZE*MAX_CU_SIZE];
284#endif
285    m_puhQTTempTransformSkipFlag[ch]               = new UChar [uiNumPartitions];
286  }
287  m_puhQTTempTrIdx   = new UChar  [uiNumPartitions];
288  m_pcQTTempTComYuv  = new TComYuv[uiNumLayersToAllocate];
289  for( UInt ui = 0; ui < uiNumLayersToAllocate; ++ui )
290  {
291    m_pcQTTempTComYuv[ui].create( maxCUWidth, maxCUHeight, pcEncCfg->getChromaFormatIdc() );
292  }
293  m_pcQTTempTransformSkipTComYuv.create( maxCUWidth, maxCUHeight, pcEncCfg->getChromaFormatIdc() );
294  m_tmpYuvPred.create(MAX_CU_SIZE, MAX_CU_SIZE, pcEncCfg->getChromaFormatIdc());
295}
296
297#define TZ_SEARCH_CONFIGURATION                                                                                 \
298const Int  iRaster                  = 5;  /* TZ soll von aussen ?ergeben werden */                            \
299const Bool bTestOtherPredictedMV    = 0;                                                                      \
300const Bool bTestZeroVector          = 1;                                                                      \
301const Bool bTestZeroVectorStart     = 0;                                                                      \
302const Bool bTestZeroVectorStop      = 0;                                                                      \
303const Bool bFirstSearchDiamond      = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
304const Bool bFirstSearchStop         = m_pcEncCfg->getFastMEAssumingSmootherMVEnabled();                       \
305const UInt uiFirstSearchRounds      = 3;  /* first search stop X rounds after best match (must be >=1) */     \
306const Bool bEnableRasterSearch      = 1;                                                                      \
307const Bool bAlwaysRasterSearch      = 0;  /* ===== 1: BETTER but factor 2 slower ===== */                     \
308const Bool bRasterRefinementEnable  = 0;  /* enable either raster refinement or star refinement */            \
309const Bool bRasterRefinementDiamond = 0;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
310const Bool bStarRefinementEnable    = 1;  /* enable either star refinement or raster refinement */            \
311const Bool bStarRefinementDiamond   = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
312const Bool bStarRefinementStop      = 0;                                                                      \
313const UInt uiStarRefinementRounds   = 2;  /* star refinement stop X rounds after best match (must be >=1) */  \
314
315
316#define SEL_SEARCH_CONFIGURATION                                                                                 \
317  const Bool bTestOtherPredictedMV    = 1;                                                                       \
318  const Bool bTestZeroVector          = 1;                                                                       \
319  const Bool bEnableRasterSearch      = 1;                                                                       \
320  const Bool bAlwaysRasterSearch      = 0;  /* ===== 1: BETTER but factor 15x slower ===== */                    \
321  const Bool bStarRefinementEnable    = 1;  /* enable either star refinement or raster refinement */             \
322  const Bool bStarRefinementDiamond   = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */         \
323  const Bool bStarRefinementStop      = 0;                                                                       \
324  const UInt uiStarRefinementRounds   = 2;  /* star refinement stop X rounds after best match (must be >=1) */   \
325  const UInt uiSearchRange            = m_iSearchRange;                                                          \
326  const Int  uiSearchRangeInitial     = m_iSearchRange >> 2;                                                     \
327  const Int  uiSearchStep             = 4;                                                                       \
328  const Int  iMVDistThresh            = 8;                                                                       \
329
330
331
332__inline Void TEncSearch::xTZSearchHelp( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance )
333{
334  Distortion  uiSad = 0;
335
336  Pel*  piRefSrch;
337
338  piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;
339
340  //-- jclee for using the SAD function pointer
341  m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );
342
343  if(m_pcEncCfg->getFastSearch() != SELECTIVE)
344  {
345    // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
346    if ( m_pcEncCfg->getUseFastEnc() )
347    {
348      if ( m_cDistParam.iRows > 8 )
349      {
350        m_cDistParam.iSubShift = 1;
351      }
352    }
353  }
354
355  setDistParamComp(COMPONENT_Y);
356
357  // distortion
358  m_cDistParam.bitDepth = pcPatternKey->getBitDepthY();
359  if(m_pcEncCfg->getFastSearch() == SELECTIVE)
360  {
361    Int isubShift = 0;
362    // motion cost
363    Distortion uiBitCost = m_pcRdCost->getCost( iSearchX, iSearchY );
364
365    if ( m_cDistParam.iRows > 32 )
366    {
367      m_cDistParam.iSubShift = 4;
368    }
369    else if ( m_cDistParam.iRows > 16 )
370    {
371      m_cDistParam.iSubShift = 3;
372    }
373    else if ( m_cDistParam.iRows > 8 )
374    {
375      m_cDistParam.iSubShift = 2;
376    }
377    else
378    {
379      m_cDistParam.iSubShift = 1;
380    }
381
382    Distortion uiTempSad = m_cDistParam.DistFunc( &m_cDistParam );
383    if((uiTempSad + uiBitCost) < rcStruct.uiBestSad)
384    {
385      uiSad += uiTempSad >>  m_cDistParam.iSubShift;
386      while(m_cDistParam.iSubShift > 0)
387      {
388        isubShift         = m_cDistParam.iSubShift -1;
389        m_cDistParam.pOrg = pcPatternKey->getROIY() + (pcPatternKey->getPatternLStride() << isubShift);
390        m_cDistParam.pCur = piRefSrch + (rcStruct.iYStride << isubShift);
391        uiTempSad = m_cDistParam.DistFunc( &m_cDistParam );
392        uiSad += uiTempSad >>  m_cDistParam.iSubShift;
393        if(((uiSad << isubShift) + uiBitCost) > rcStruct.uiBestSad)
394        {
395          break;
396        }
397
398        m_cDistParam.iSubShift--;
399      }
400
401      if(m_cDistParam.iSubShift == 0)
402      {
403        uiSad += uiBitCost;
404        if( uiSad < rcStruct.uiBestSad )
405        {
406          rcStruct.uiBestSad      = uiSad;
407          rcStruct.iBestX         = iSearchX;
408          rcStruct.iBestY         = iSearchY;
409          rcStruct.uiBestDistance = uiDistance;
410          rcStruct.uiBestRound    = 0;
411          rcStruct.ucPointNr      = ucPointNr;
412        }
413      }
414    }
415  }
416  else
417  {
418    uiSad = m_cDistParam.DistFunc( &m_cDistParam );
419
420    // motion cost
421    uiSad += m_pcRdCost->getCost( iSearchX, iSearchY );
422
423    if( uiSad < rcStruct.uiBestSad )
424    {
425      rcStruct.uiBestSad      = uiSad;
426      rcStruct.iBestX         = iSearchX;
427      rcStruct.iBestY         = iSearchY;
428      rcStruct.uiBestDistance = uiDistance;
429      rcStruct.uiBestRound    = 0;
430      rcStruct.ucPointNr      = ucPointNr;
431    }
432  }
433}
434
435
436
437
438__inline Void TEncSearch::xTZ2PointSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB )
439{
440  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
441  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
442  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
443  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
444
445  // 2 point search,                   //   1 2 3
446  // check only the 2 untested points  //   4 0 5
447  // around the start point            //   6 7 8
448  Int iStartX = rcStruct.iBestX;
449  Int iStartY = rcStruct.iBestY;
450  switch( rcStruct.ucPointNr )
451  {
452    case 1:
453    {
454      if ( (iStartX - 1) >= iSrchRngHorLeft )
455      {
456        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY, 0, 2 );
457      }
458      if ( (iStartY - 1) >= iSrchRngVerTop )
459      {
460        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
461      }
462    }
463      break;
464    case 2:
465    {
466      if ( (iStartY - 1) >= iSrchRngVerTop )
467      {
468        if ( (iStartX - 1) >= iSrchRngHorLeft )
469        {
470          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
471        }
472        if ( (iStartX + 1) <= iSrchRngHorRight )
473        {
474          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
475        }
476      }
477    }
478      break;
479    case 3:
480    {
481      if ( (iStartY - 1) >= iSrchRngVerTop )
482      {
483        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
484      }
485      if ( (iStartX + 1) <= iSrchRngHorRight )
486      {
487        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
488      }
489    }
490      break;
491    case 4:
492    {
493      if ( (iStartX - 1) >= iSrchRngHorLeft )
494      {
495        if ( (iStartY + 1) <= iSrchRngVerBottom )
496        {
497          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
498        }
499        if ( (iStartY - 1) >= iSrchRngVerTop )
500        {
501          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
502        }
503      }
504    }
505      break;
506    case 5:
507    {
508      if ( (iStartX + 1) <= iSrchRngHorRight )
509      {
510        if ( (iStartY - 1) >= iSrchRngVerTop )
511        {
512          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
513        }
514        if ( (iStartY + 1) <= iSrchRngVerBottom )
515        {
516          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
517        }
518      }
519    }
520      break;
521    case 6:
522    {
523      if ( (iStartX - 1) >= iSrchRngHorLeft )
524      {
525        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY , 0, 2 );
526      }
527      if ( (iStartY + 1) <= iSrchRngVerBottom )
528      {
529        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
530      }
531    }
532      break;
533    case 7:
534    {
535      if ( (iStartY + 1) <= iSrchRngVerBottom )
536      {
537        if ( (iStartX - 1) >= iSrchRngHorLeft )
538        {
539          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
540        }
541        if ( (iStartX + 1) <= iSrchRngHorRight )
542        {
543          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
544        }
545      }
546    }
547      break;
548    case 8:
549    {
550      if ( (iStartX + 1) <= iSrchRngHorRight )
551      {
552        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
553      }
554      if ( (iStartY + 1) <= iSrchRngVerBottom )
555      {
556        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
557      }
558    }
559      break;
560    default:
561    {
562      assert( false );
563    }
564      break;
565  } // switch( rcStruct.ucPointNr )
566}
567
568
569
570
571__inline Void TEncSearch::xTZ8PointSquareSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
572{
573  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
574  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
575  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
576  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
577
578  // 8 point search,                   //   1 2 3
579  // search around the start point     //   4 0 5
580  // with the required  distance       //   6 7 8
581  assert( iDist != 0 );
582  const Int iTop        = iStartY - iDist;
583  const Int iBottom     = iStartY + iDist;
584  const Int iLeft       = iStartX - iDist;
585  const Int iRight      = iStartX + iDist;
586  rcStruct.uiBestRound += 1;
587
588  if ( iTop >= iSrchRngVerTop ) // check top
589  {
590    if ( iLeft >= iSrchRngHorLeft ) // check top left
591    {
592      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iTop, 1, iDist );
593    }
594    // top middle
595    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
596
597    if ( iRight <= iSrchRngHorRight ) // check top right
598    {
599      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iTop, 3, iDist );
600    }
601  } // check top
602  if ( iLeft >= iSrchRngHorLeft ) // check middle left
603  {
604    xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
605  }
606  if ( iRight <= iSrchRngHorRight ) // check middle right
607  {
608    xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
609  }
610  if ( iBottom <= iSrchRngVerBottom ) // check bottom
611  {
612    if ( iLeft >= iSrchRngHorLeft ) // check bottom left
613    {
614      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iBottom, 6, iDist );
615    }
616    // check bottom middle
617    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
618
619    if ( iRight <= iSrchRngHorRight ) // check bottom right
620    {
621      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iBottom, 8, iDist );
622    }
623  } // check bottom
624}
625
626
627
628
629__inline Void TEncSearch::xTZ8PointDiamondSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
630{
631  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
632  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
633  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
634  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
635
636  // 8 point search,                   //   1 2 3
637  // search around the start point     //   4 0 5
638  // with the required  distance       //   6 7 8
639  assert ( iDist != 0 );
640  const Int iTop        = iStartY - iDist;
641  const Int iBottom     = iStartY + iDist;
642  const Int iLeft       = iStartX - iDist;
643  const Int iRight      = iStartX + iDist;
644  rcStruct.uiBestRound += 1;
645
646  if ( iDist == 1 ) // iDist == 1
647  {
648    if ( iTop >= iSrchRngVerTop ) // check top
649    {
650      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
651    }
652    if ( iLeft >= iSrchRngHorLeft ) // check middle left
653    {
654      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
655    }
656    if ( iRight <= iSrchRngHorRight ) // check middle right
657    {
658      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
659    }
660    if ( iBottom <= iSrchRngVerBottom ) // check bottom
661    {
662      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
663    }
664  }
665  else // if (iDist != 1)
666  {
667    if ( iDist <= 8 )
668    {
669      const Int iTop_2      = iStartY - (iDist>>1);
670      const Int iBottom_2   = iStartY + (iDist>>1);
671      const Int iLeft_2     = iStartX - (iDist>>1);
672      const Int iRight_2    = iStartX + (iDist>>1);
673
674      if (  iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
675          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
676      {
677        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iTop,      2, iDist    );
678        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iTop_2,    1, iDist>>1 );
679        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2,    3, iDist>>1 );
680        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,    iStartY,   4, iDist    );
681        xTZSearchHelp( pcPatternKey, rcStruct, iRight,   iStartY,   5, iDist    );
682        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iBottom_2, 6, iDist>>1 );
683        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, iDist>>1 );
684        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iBottom,   7, iDist    );
685      }
686      else // check border
687      {
688        if ( iTop >= iSrchRngVerTop ) // check top
689        {
690          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
691        }
692        if ( iTop_2 >= iSrchRngVerTop ) // check half top
693        {
694          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
695          {
696            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iTop_2, 1, (iDist>>1) );
697          }
698          if ( iRight_2 <= iSrchRngHorRight ) // check half right
699          {
700            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2, 3, (iDist>>1) );
701          }
702        } // check half top
703        if ( iLeft >= iSrchRngHorLeft ) // check left
704        {
705          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
706        }
707        if ( iRight <= iSrchRngHorRight ) // check right
708        {
709          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
710        }
711        if ( iBottom_2 <= iSrchRngVerBottom ) // check half bottom
712        {
713          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
714          {
715            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iBottom_2, 6, (iDist>>1) );
716          }
717          if ( iRight_2 <= iSrchRngHorRight ) // check half right
718          {
719            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, (iDist>>1) );
720          }
721        } // check half bottom
722        if ( iBottom <= iSrchRngVerBottom ) // check bottom
723        {
724          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
725        }
726      } // check border
727    }
728    else // iDist > 8
729    {
730      if ( iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
731          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
732      {
733        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop,    0, iDist );
734        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,   iStartY, 0, iDist );
735        xTZSearchHelp( pcPatternKey, rcStruct, iRight,  iStartY, 0, iDist );
736        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
737        for ( Int index = 1; index < 4; index++ )
738        {
739          Int iPosYT = iTop    + ((iDist>>2) * index);
740          Int iPosYB = iBottom - ((iDist>>2) * index);
741          Int iPosXL = iStartX - ((iDist>>2) * index);
742          Int iPosXR = iStartX + ((iDist>>2) * index);
743          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
744          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
745          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
746          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
747        }
748      }
749      else // check border
750      {
751        if ( iTop >= iSrchRngVerTop ) // check top
752        {
753          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 0, iDist );
754        }
755        if ( iLeft >= iSrchRngHorLeft ) // check left
756        {
757          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 0, iDist );
758        }
759        if ( iRight <= iSrchRngHorRight ) // check right
760        {
761          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 0, iDist );
762        }
763        if ( iBottom <= iSrchRngVerBottom ) // check bottom
764        {
765          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
766        }
767        for ( Int index = 1; index < 4; index++ )
768        {
769          Int iPosYT = iTop    + ((iDist>>2) * index);
770          Int iPosYB = iBottom - ((iDist>>2) * index);
771          Int iPosXL = iStartX - ((iDist>>2) * index);
772          Int iPosXR = iStartX + ((iDist>>2) * index);
773
774          if ( iPosYT >= iSrchRngVerTop ) // check top
775          {
776            if ( iPosXL >= iSrchRngHorLeft ) // check left
777            {
778              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
779            }
780            if ( iPosXR <= iSrchRngHorRight ) // check right
781            {
782              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
783            }
784          } // check top
785          if ( iPosYB <= iSrchRngVerBottom ) // check bottom
786          {
787            if ( iPosXL >= iSrchRngHorLeft ) // check left
788            {
789              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
790            }
791            if ( iPosXR <= iSrchRngHorRight ) // check right
792            {
793              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
794            }
795          } // check bottom
796        } // for ...
797      } // check border
798    } // iDist <= 8
799  } // iDist == 1
800}
801
802
803
804
805
806//<--
807
808Distortion TEncSearch::xPatternRefinement( TComPattern* pcPatternKey,
809                                           TComMv baseRefMv,
810                                           Int iFrac, TComMv& rcMvFrac,
811                                           Bool bAllowUseOfHadamard
812                                         )
813{
814  Distortion  uiDist;
815  Distortion  uiDistBest  = std::numeric_limits<Distortion>::max();
816  UInt        uiDirecBest = 0;
817
818  Pel*  piRefPos;
819  Int iRefStride = m_filteredBlock[0][0].getStride(COMPONENT_Y);
820
821  m_pcRdCost->setDistParam( pcPatternKey, m_filteredBlock[0][0].getAddr(COMPONENT_Y), iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME() && bAllowUseOfHadamard );
822
823  const TComMv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
824
825  for (UInt i = 0; i < 9; i++)
826  {
827    TComMv cMvTest = pcMvRefine[i];
828    cMvTest += baseRefMv;
829
830    Int horVal = cMvTest.getHor() * iFrac;
831    Int verVal = cMvTest.getVer() * iFrac;
832    piRefPos = m_filteredBlock[ verVal & 3 ][ horVal & 3 ].getAddr(COMPONENT_Y);
833    if ( horVal == 2 && ( verVal & 1 ) == 0 )
834    {
835      piRefPos += 1;
836    }
837    if ( ( horVal & 1 ) == 0 && verVal == 2 )
838    {
839      piRefPos += iRefStride;
840    }
841    cMvTest = pcMvRefine[i];
842    cMvTest += rcMvFrac;
843
844    setDistParamComp(COMPONENT_Y);
845
846    m_cDistParam.pCur = piRefPos;
847    m_cDistParam.bitDepth = pcPatternKey->getBitDepthY();
848    uiDist = m_cDistParam.DistFunc( &m_cDistParam );
849    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
850
851    if ( uiDist < uiDistBest )
852    {
853      uiDistBest  = uiDist;
854      uiDirecBest = i;
855    }
856  }
857
858  rcMvFrac = pcMvRefine[uiDirecBest];
859
860  return uiDistBest;
861}
862
863
864
865Void
866TEncSearch::xEncSubdivCbfQT(TComTU      &rTu,
867                            Bool         bLuma,
868                            Bool         bChroma )
869{
870  TComDataCU* pcCU=rTu.getCU();
871  const UInt uiAbsPartIdx         = rTu.GetAbsPartIdxTU();
872  const UInt uiTrDepth            = rTu.GetTransformDepthRel();
873  const UInt uiTrMode             = pcCU->getTransformIdx( uiAbsPartIdx );
874  const UInt uiSubdiv             = ( uiTrMode > uiTrDepth ? 1 : 0 );
875  const UInt uiLog2LumaTrafoSize  = rTu.GetLog2LumaTrSize();
876
877  if( pcCU->isIntra(0) && pcCU->getPartitionSize(0) == SIZE_NxN && uiTrDepth == 0 )
878  {
879    assert( uiSubdiv );
880  }
881  else if( uiLog2LumaTrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
882  {
883    assert( uiSubdiv );
884  }
885  else if( uiLog2LumaTrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
886  {
887    assert( !uiSubdiv );
888  }
889  else if( uiLog2LumaTrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
890  {
891    assert( !uiSubdiv );
892  }
893  else
894  {
895    assert( uiLog2LumaTrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
896    if( bLuma )
897    {
898      m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, 5 - uiLog2LumaTrafoSize );
899    }
900  }
901
902  if ( bChroma )
903  {
904    const UInt numberValidComponents = getNumberValidComponents(rTu.GetChromaFormat());
905    for (UInt ch=COMPONENT_Cb; ch<numberValidComponents; ch++)
906    {
907      const ComponentID compID=ComponentID(ch);
908      if( rTu.ProcessingAllQuadrants(compID) && (uiTrDepth==0 || pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepth-1 ) ))
909      {
910        m_pcEntropyCoder->encodeQtCbf(rTu, compID, (uiSubdiv == 0));
911      }
912    }
913  }
914
915  if( uiSubdiv )
916  {
917    TComTURecurse tuRecurse(rTu, false);
918    do
919    {
920      xEncSubdivCbfQT( tuRecurse, bLuma, bChroma );
921    } while (tuRecurse.nextSection(rTu));
922  }
923  else
924  {
925    //===== Cbfs =====
926    if( bLuma )
927    {
928      m_pcEntropyCoder->encodeQtCbf( rTu, COMPONENT_Y, true );
929    }
930  }
931}
932
933
934
935
936Void
937TEncSearch::xEncCoeffQT(TComTU &rTu,
938                        const ComponentID  component,
939                        Bool         bRealCoeff )
940{
941  TComDataCU* pcCU=rTu.getCU();
942  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
943  const UInt uiTrDepth=rTu.GetTransformDepthRel();
944
945  const UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
946  const UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
947
948  if( uiSubdiv )
949  {
950    TComTURecurse tuRecurseChild(rTu, false);
951    do
952    {
953      xEncCoeffQT( tuRecurseChild, component, bRealCoeff );
954    } while (tuRecurseChild.nextSection(rTu) );
955  }
956  else if (rTu.ProcessComponentSection(component))
957  {
958    //===== coefficients =====
959    const UInt  uiLog2TrafoSize = rTu.GetLog2LumaTrSize();
960    UInt    uiCoeffOffset   = rTu.getCoefficientOffset(component);
961    UInt    uiQTLayer       = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrafoSize;
962    TCoeff* pcCoeff         = bRealCoeff ? pcCU->getCoeff(component) : m_ppcQTTempCoeff[component][uiQTLayer];
963
964    if (isChroma(component) && (pcCU->getCbf( rTu.GetAbsPartIdxTU(), COMPONENT_Y, uiTrMode ) != 0) && pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag() )
965    {
966      m_pcEntropyCoder->encodeCrossComponentPrediction( rTu, component );
967    }
968
969    m_pcEntropyCoder->encodeCoeffNxN( rTu, pcCoeff+uiCoeffOffset, component );
970  }
971}
972
973
974
975
976Void
977TEncSearch::xEncIntraHeader( TComDataCU*  pcCU,
978                            UInt         uiTrDepth,
979                            UInt         uiAbsPartIdx,
980                            Bool         bLuma,
981                            Bool         bChroma )
982{
983  if( bLuma )
984  {
985    // CU header
986    if( uiAbsPartIdx == 0 )
987    {
988      if( !pcCU->getSlice()->isIntra() )
989      {
990        if (pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
991        {
992          m_pcEntropyCoder->encodeCUTransquantBypassFlag( pcCU, 0, true );
993        }
994        m_pcEntropyCoder->encodeSkipFlag( pcCU, 0, true );
995        m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
996      }
997      m_pcEntropyCoder  ->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
998
999      if (pcCU->isIntra(0) && pcCU->getPartitionSize(0) == SIZE_2Nx2N )
1000      {
1001        m_pcEntropyCoder->encodeIPCMInfo( pcCU, 0, true );
1002
1003        if ( pcCU->getIPCMFlag (0))
1004        {
1005          return;
1006        }
1007      }
1008    }
1009    // luma prediction mode
1010    if( pcCU->getPartitionSize(0) == SIZE_2Nx2N )
1011    {
1012      if (uiAbsPartIdx==0)
1013      {
1014        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, 0 );
1015      }
1016    }
1017    else
1018    {
1019      UInt uiQNumParts = pcCU->getTotalNumPart() >> 2;
1020      if (uiTrDepth>0 && (uiAbsPartIdx%uiQNumParts)==0)
1021      {
1022        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiAbsPartIdx );
1023      }
1024    }
1025  }
1026
1027  if( bChroma )
1028  {
1029    if( pcCU->getPartitionSize(0) == SIZE_2Nx2N || !enable4ChromaPUsInIntraNxNCU(pcCU->getPic()->getChromaFormat()))
1030    {
1031      if(uiAbsPartIdx==0)
1032      {
1033         m_pcEntropyCoder->encodeIntraDirModeChroma ( pcCU, uiAbsPartIdx );
1034      }
1035    }
1036    else
1037    {
1038      UInt uiQNumParts = pcCU->getTotalNumPart() >> 2;
1039      assert(uiTrDepth>0);
1040      if ((uiAbsPartIdx%uiQNumParts)==0)
1041      {
1042        m_pcEntropyCoder->encodeIntraDirModeChroma ( pcCU, uiAbsPartIdx );
1043      }
1044    }
1045  }
1046}
1047
1048
1049
1050
1051UInt
1052TEncSearch::xGetIntraBitsQT(TComTU &rTu,
1053                            Bool         bLuma,
1054                            Bool         bChroma,
1055                            Bool         bRealCoeff /* just for test */ )
1056{
1057  TComDataCU* pcCU=rTu.getCU();
1058  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
1059  const UInt uiTrDepth=rTu.GetTransformDepthRel();
1060  m_pcEntropyCoder->resetBits();
1061  xEncIntraHeader ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
1062  xEncSubdivCbfQT ( rTu, bLuma, bChroma );
1063
1064  if( bLuma )
1065  {
1066    xEncCoeffQT   ( rTu, COMPONENT_Y,      bRealCoeff );
1067  }
1068  if( bChroma )
1069  {
1070    xEncCoeffQT   ( rTu, COMPONENT_Cb,  bRealCoeff );
1071    xEncCoeffQT   ( rTu, COMPONENT_Cr,  bRealCoeff );
1072  }
1073  UInt   uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
1074
1075  return uiBits;
1076}
1077
1078UInt TEncSearch::xGetIntraBitsQTChroma(TComTU &rTu,
1079                                       ComponentID compID,
1080                                       Bool         bRealCoeff /* just for test */ )
1081{
1082  m_pcEntropyCoder->resetBits();
1083  xEncCoeffQT   ( rTu, compID,  bRealCoeff );
1084  UInt   uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
1085  return uiBits;
1086}
1087
1088Void TEncSearch::xIntraCodingTUBlock(       TComYuv*    pcOrgYuv,
1089                                            TComYuv*    pcPredYuv,
1090                                            TComYuv*    pcResiYuv,
1091                                            Pel         resiLuma[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE],
1092                                      const Bool        checkCrossCPrediction,
1093                                            Distortion& ruiDist,
1094                                      const ComponentID compID,
1095                                            TComTU&     rTu
1096                                      DEBUG_STRING_FN_DECLARE(sDebug)
1097                                           ,Int         default0Save1Load2
1098                                     )
1099{
1100  if (!rTu.ProcessComponentSection(compID))
1101  {
1102    return;
1103  }
1104  const Bool           bIsLuma          = isLuma(compID);
1105  const TComRectangle &rect             = rTu.getRect(compID);
1106        TComDataCU    *pcCU             = rTu.getCU();
1107  const UInt           uiAbsPartIdx     = rTu.GetAbsPartIdxTU();
1108  const TComSPS       &sps              = *(pcCU->getSlice()->getSPS());
1109
1110  const UInt           uiTrDepth        = rTu.GetTransformDepthRelAdj(compID);
1111  const UInt           uiFullDepth      = rTu.GetTransformDepthTotal();
1112  const UInt           uiLog2TrSize     = rTu.GetLog2LumaTrSize();
1113  const ChromaFormat   chFmt            = pcOrgYuv->getChromaFormat();
1114  const ChannelType    chType           = toChannelType(compID);
1115#if SVC_EXTENSION
1116  const Int            bitDepth         = pcCU->getSlice()->getBitDepth(chType);
1117#else
1118  const Int            bitDepth         = sps.getBitDepth(chType);
1119#endif
1120
1121  const UInt           uiWidth          = rect.width;
1122  const UInt           uiHeight         = rect.height;
1123  const UInt           uiStride         = pcOrgYuv ->getStride (compID);
1124        Pel           *piOrg            = pcOrgYuv ->getAddr( compID, uiAbsPartIdx );
1125        Pel           *piPred           = pcPredYuv->getAddr( compID, uiAbsPartIdx );
1126        Pel           *piResi           = pcResiYuv->getAddr( compID, uiAbsPartIdx );
1127        Pel           *piReco           = pcPredYuv->getAddr( compID, uiAbsPartIdx );
1128  const UInt           uiQTLayer        = sps.getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1129        Pel           *piRecQt          = m_pcQTTempTComYuv[ uiQTLayer ].getAddr( compID, uiAbsPartIdx );
1130  const UInt           uiRecQtStride    = m_pcQTTempTComYuv[ uiQTLayer ].getStride(compID);
1131  const UInt           uiZOrder         = pcCU->getZorderIdxInCtu() + uiAbsPartIdx;
1132        Pel           *piRecIPred       = pcCU->getPic()->getPicYuvRec()->getAddr( compID, pcCU->getCtuRsAddr(), uiZOrder );
1133        UInt           uiRecIPredStride = pcCU->getPic()->getPicYuvRec()->getStride  ( compID );
1134        TCoeff        *pcCoeff          = m_ppcQTTempCoeff[compID][uiQTLayer] + rTu.getCoefficientOffset(compID);
1135        Bool           useTransformSkip = pcCU->getTransformSkip(uiAbsPartIdx, compID);
1136
1137#if ADAPTIVE_QP_SELECTION
1138        TCoeff        *pcArlCoeff       = m_ppcQTTempArlCoeff[compID][ uiQTLayer ] + rTu.getCoefficientOffset(compID);
1139#endif
1140
1141  const UInt           uiChPredMode     = pcCU->getIntraDir( chType, uiAbsPartIdx );
1142  const UInt           partsPerMinCU    = 1<<(2*(sps.getMaxTotalCUDepth() - sps.getLog2DiffMaxMinCodingBlockSize()));
1143  const UInt           uiChCodedMode    = (uiChPredMode==DM_CHROMA_IDX && !bIsLuma) ? pcCU->getIntraDir(CHANNEL_TYPE_LUMA, getChromasCorrespondingPULumaIdx(uiAbsPartIdx, chFmt, partsPerMinCU)) : uiChPredMode;
1144  const UInt           uiChFinalMode    = ((chFmt == CHROMA_422)       && !bIsLuma) ? g_chroma422IntraAngleMappingTable[uiChCodedMode] : uiChCodedMode;
1145
1146  const Int            blkX                                 = g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
1147  const Int            blkY                                 = g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
1148  const Int            bufferOffset                         = blkX + (blkY * MAX_CU_SIZE);
1149        Pel  *const    encoderLumaResidual                  = resiLuma[RESIDUAL_ENCODER_SIDE ] + bufferOffset;
1150        Pel  *const    reconstructedLumaResidual            = resiLuma[RESIDUAL_RECONSTRUCTED] + bufferOffset;
1151  const Bool           bUseCrossCPrediction                 = isChroma(compID) && (uiChPredMode == DM_CHROMA_IDX) && checkCrossCPrediction;
1152  const Bool           bUseReconstructedResidualForEstimate = m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate();
1153        Pel *const     lumaResidualForEstimate              = bUseReconstructedResidualForEstimate ? reconstructedLumaResidual : encoderLumaResidual;
1154
1155#if DEBUG_STRING
1156  const Int debugPredModeMask=DebugStringGetPredModeMask(MODE_INTRA);
1157#endif
1158
1159  //===== init availability pattern =====
1160  Bool  bAboveAvail = false;
1161  Bool  bLeftAvail  = false;
1162
1163  DEBUG_STRING_NEW(sTemp)
1164
1165#if !DEBUG_STRING
1166  if( default0Save1Load2 != 2 )
1167#endif
1168  {
1169    const Bool bUseFilteredPredictions=TComPrediction::filteringIntraReferenceSamples(compID, uiChFinalMode, uiWidth, uiHeight, chFmt, sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag());
1170
1171    initIntraPatternChType( rTu, bAboveAvail, bLeftAvail, compID, bUseFilteredPredictions DEBUG_STRING_PASS_INTO(sDebug) );
1172
1173    //===== get prediction signal =====
1174    predIntraAng( compID, uiChFinalMode, piOrg, uiStride, piPred, uiStride, rTu, bAboveAvail, bLeftAvail, bUseFilteredPredictions );
1175
1176    // save prediction
1177    if( default0Save1Load2 == 1 )
1178    {
1179      Pel*  pPred   = piPred;
1180      Pel*  pPredBuf = m_pSharedPredTransformSkip[compID];
1181      Int k = 0;
1182      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1183      {
1184        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1185        {
1186          pPredBuf[ k ++ ] = pPred[ uiX ];
1187        }
1188        pPred += uiStride;
1189      }
1190    }
1191  }
1192#if !DEBUG_STRING
1193  else
1194  {
1195    // load prediction
1196    Pel*  pPred   = piPred;
1197    Pel*  pPredBuf = m_pSharedPredTransformSkip[compID];
1198    Int k = 0;
1199    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1200    {
1201      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1202      {
1203        pPred[ uiX ] = pPredBuf[ k ++ ];
1204      }
1205      pPred += uiStride;
1206    }
1207  }
1208#endif
1209
1210  //===== get residual signal =====
1211  {
1212    // get residual
1213    Pel*  pOrg    = piOrg;
1214    Pel*  pPred   = piPred;
1215    Pel*  pResi   = piResi;
1216
1217    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1218    {
1219      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1220      {
1221        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1222      }
1223
1224      pOrg  += uiStride;
1225      pResi += uiStride;
1226      pPred += uiStride;
1227    }
1228  }
1229
1230  if (pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag())
1231  {
1232    if (bUseCrossCPrediction)
1233    {
1234      if (xCalcCrossComponentPredictionAlpha( rTu, compID, lumaResidualForEstimate, piResi, uiWidth, uiHeight, MAX_CU_SIZE, uiStride ) == 0)
1235      {
1236        return;
1237      }
1238      TComTrQuant::crossComponentPrediction ( rTu, compID, reconstructedLumaResidual, piResi, piResi, uiWidth, uiHeight, MAX_CU_SIZE, uiStride, uiStride, false );
1239    }
1240    else if (isLuma(compID) && !bUseReconstructedResidualForEstimate)
1241    {
1242      xStoreCrossComponentPredictionResult( encoderLumaResidual, piResi, rTu, 0, 0, MAX_CU_SIZE, uiStride );
1243    }
1244  }
1245
1246  //===== transform and quantization =====
1247  //--- init rate estimation arrays for RDOQ ---
1248  if( useTransformSkip ? m_pcEncCfg->getUseRDOQTS() : m_pcEncCfg->getUseRDOQ() )
1249  {
1250    m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, uiHeight, chType );
1251  }
1252
1253  //--- transform and quantization ---
1254  TCoeff uiAbsSum = 0;
1255  if (bIsLuma)
1256  {
1257    pcCU       ->setTrIdxSubParts ( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1258  }
1259
1260  const QpParam cQP(*pcCU, compID);
1261
1262#if RDOQ_CHROMA_LAMBDA
1263  m_pcTrQuant->selectLambda     (compID);
1264#endif
1265
1266  m_pcTrQuant->transformNxN     ( rTu, compID, piResi, uiStride, pcCoeff,
1267#if ADAPTIVE_QP_SELECTION
1268    pcArlCoeff,
1269#endif
1270    uiAbsSum, cQP
1271    );
1272
1273  //--- inverse transform ---
1274
1275#if DEBUG_STRING
1276  if ( (uiAbsSum > 0) || (DebugOptionList::DebugString_InvTran.getInt()&debugPredModeMask) )
1277#else
1278  if ( uiAbsSum > 0 )
1279#endif
1280  {
1281    m_pcTrQuant->invTransformNxN ( rTu, compID, piResi, uiStride, pcCoeff, cQP DEBUG_STRING_PASS_INTO_OPTIONAL(&sDebug, (DebugOptionList::DebugString_InvTran.getInt()&debugPredModeMask)) );
1282  }
1283  else
1284  {
1285    Pel* pResi = piResi;
1286    memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );
1287    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1288    {
1289      memset( pResi, 0, sizeof( Pel ) * uiWidth );
1290      pResi += uiStride;
1291    }
1292  }
1293
1294
1295  //===== reconstruction =====
1296  {
1297    Pel* pPred      = piPred;
1298    Pel* pResi      = piResi;
1299    Pel* pReco      = piReco;
1300    Pel* pRecQt     = piRecQt;
1301    Pel* pRecIPred  = piRecIPred;
1302
1303    if (pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag())
1304    {
1305      if (bUseCrossCPrediction)
1306      {
1307        TComTrQuant::crossComponentPrediction( rTu, compID, reconstructedLumaResidual, piResi, piResi, uiWidth, uiHeight, MAX_CU_SIZE, uiStride, uiStride, true );
1308      }
1309      else if (isLuma(compID))
1310      {
1311        xStoreCrossComponentPredictionResult( reconstructedLumaResidual, piResi, rTu, 0, 0, MAX_CU_SIZE, uiStride );
1312      }
1313    }
1314
1315 #if DEBUG_STRING
1316    std::stringstream ss(stringstream::out);
1317    const Bool bDebugPred=((DebugOptionList::DebugString_Pred.getInt()&debugPredModeMask) && DEBUG_STRING_CHANNEL_CONDITION(compID));
1318    const Bool bDebugResi=((DebugOptionList::DebugString_Resi.getInt()&debugPredModeMask) && DEBUG_STRING_CHANNEL_CONDITION(compID));
1319    const Bool bDebugReco=((DebugOptionList::DebugString_Reco.getInt()&debugPredModeMask) && DEBUG_STRING_CHANNEL_CONDITION(compID));
1320
1321    if (bDebugPred || bDebugResi || bDebugReco)
1322    {
1323      ss << "###: " << "CompID: " << compID << " pred mode (ch/fin): " << uiChPredMode << "/" << uiChFinalMode << " absPartIdx: " << rTu.GetAbsPartIdxTU() << "\n";
1324      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1325      {
1326        ss << "###: ";
1327        if (bDebugPred)
1328        {
1329          ss << " - pred: ";
1330          for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1331          {
1332            ss << pPred[ uiX ] << ", ";
1333          }
1334        }
1335        if (bDebugResi)
1336        {
1337          ss << " - resi: ";
1338        }
1339        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1340        {
1341          if (bDebugResi)
1342          {
1343            ss << pResi[ uiX ] << ", ";
1344          }
1345          pReco    [ uiX ] = Pel(ClipBD<Int>( Int(pPred[uiX]) + Int(pResi[uiX]), bitDepth ));
1346          pRecQt   [ uiX ] = pReco[ uiX ];
1347          pRecIPred[ uiX ] = pReco[ uiX ];
1348        }
1349        if (bDebugReco)
1350        {
1351          ss << " - reco: ";
1352          for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1353          {
1354            ss << pReco[ uiX ] << ", ";
1355          }
1356        }
1357        pPred     += uiStride;
1358        pResi     += uiStride;
1359        pReco     += uiStride;
1360        pRecQt    += uiRecQtStride;
1361        pRecIPred += uiRecIPredStride;
1362        ss << "\n";
1363      }
1364      DEBUG_STRING_APPEND(sDebug, ss.str())
1365    }
1366    else
1367#endif
1368    {
1369
1370      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1371      {
1372        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1373        {
1374          pReco    [ uiX ] = Pel(ClipBD<Int>( Int(pPred[uiX]) + Int(pResi[uiX]), bitDepth ));
1375          pRecQt   [ uiX ] = pReco[ uiX ];
1376          pRecIPred[ uiX ] = pReco[ uiX ];
1377        }
1378        pPred     += uiStride;
1379        pResi     += uiStride;
1380        pReco     += uiStride;
1381        pRecQt    += uiRecQtStride;
1382        pRecIPred += uiRecIPredStride;
1383      }
1384    }
1385  }
1386
1387  //===== update distortion =====
1388  ruiDist += m_pcRdCost->getDistPart( bitDepth, piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight, compID );
1389}
1390
1391
1392
1393
1394Void
1395TEncSearch::xRecurIntraCodingLumaQT(TComYuv*    pcOrgYuv,
1396                                    TComYuv*    pcPredYuv,
1397                                    TComYuv*    pcResiYuv,
1398                                    Pel         resiLuma[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE],
1399                                    Distortion& ruiDistY,
1400#if HHI_RQT_INTRA_SPEEDUP
1401                                    Bool        bCheckFirst,
1402#endif
1403                                    Double&     dRDCost,
1404                                    TComTU&     rTu
1405                                    DEBUG_STRING_FN_DECLARE(sDebug))
1406{
1407  TComDataCU   *pcCU          = rTu.getCU();
1408  const UInt    uiAbsPartIdx  = rTu.GetAbsPartIdxTU();
1409  const UInt    uiFullDepth   = rTu.GetTransformDepthTotal();
1410  const UInt    uiTrDepth     = rTu.GetTransformDepthRel();
1411  const UInt    uiLog2TrSize  = rTu.GetLog2LumaTrSize();
1412        Bool    bCheckFull    = ( uiLog2TrSize  <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
1413        Bool    bCheckSplit   = ( uiLog2TrSize  >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
1414
1415        Pel     resiLumaSplit [NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE];
1416        Pel     resiLumaSingle[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE];
1417
1418        Bool    bMaintainResidual[NUMBER_OF_STORED_RESIDUAL_TYPES];
1419        for (UInt residualTypeIndex = 0; residualTypeIndex < NUMBER_OF_STORED_RESIDUAL_TYPES; residualTypeIndex++)
1420        {
1421          bMaintainResidual[residualTypeIndex] = true; //assume true unless specified otherwise
1422        }
1423
1424        bMaintainResidual[RESIDUAL_ENCODER_SIDE] = !(m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate());
1425
1426#if HHI_RQT_INTRA_SPEEDUP
1427  Int maxTuSize = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize();
1428  Int isIntraSlice = (pcCU->getSlice()->getSliceType() == I_SLICE);
1429  // don't check split if TU size is less or equal to max TU size
1430  Bool noSplitIntraMaxTuSize = bCheckFull;
1431  if(m_pcEncCfg->getRDpenalty() && ! isIntraSlice)
1432  {
1433    // in addition don't check split if TU size is less or equal to 16x16 TU size for non-intra slice
1434    noSplitIntraMaxTuSize = ( uiLog2TrSize  <= min(maxTuSize,4) );
1435
1436    // if maximum RD-penalty don't check TU size 32x32
1437    if(m_pcEncCfg->getRDpenalty()==2)
1438    {
1439      bCheckFull    = ( uiLog2TrSize  <= min(maxTuSize,4));
1440    }
1441  }
1442  if( bCheckFirst && noSplitIntraMaxTuSize )
1443
1444  {
1445    bCheckSplit = false;
1446  }
1447#else
1448  Int maxTuSize = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize();
1449  Int isIntraSlice = (pcCU->getSlice()->getSliceType() == I_SLICE);
1450  // if maximum RD-penalty don't check TU size 32x32
1451  if((m_pcEncCfg->getRDpenalty()==2)  && !isIntraSlice)
1452  {
1453    bCheckFull    = ( uiLog2TrSize  <= min(maxTuSize,4));
1454  }
1455#endif
1456  Double     dSingleCost                        = MAX_DOUBLE;
1457  Distortion uiSingleDistLuma                   = 0;
1458  UInt       uiSingleCbfLuma                    = 0;
1459  Bool       checkTransformSkip  = pcCU->getSlice()->getPPS()->getUseTransformSkip();
1460  Int        bestModeId[MAX_NUM_COMPONENT] = { 0, 0, 0};
1461  checkTransformSkip           &= TUCompRectHasAssociatedTransformSkipFlag(rTu.getRect(COMPONENT_Y), pcCU->getSlice()->getPPS()->getPpsRangeExtension().getLog2MaxTransformSkipBlockSize());
1462  checkTransformSkip           &= (!pcCU->getCUTransquantBypass(0));
1463
1464  if ( m_pcEncCfg->getUseTransformSkipFast() )
1465  {
1466    checkTransformSkip       &= (pcCU->getPartitionSize(uiAbsPartIdx)==SIZE_NxN);
1467  }
1468
1469  if( bCheckFull )
1470  {
1471    if(checkTransformSkip == true)
1472    {
1473      //----- store original entropy coding status -----
1474      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1475
1476      Distortion singleDistTmpLuma                    = 0;
1477      UInt       singleCbfTmpLuma                     = 0;
1478      Double     singleCostTmp                        = 0;
1479      Int        firstCheckId                         = 0;
1480
1481      for(Int modeId = firstCheckId; modeId < 2; modeId ++)
1482      {
1483        DEBUG_STRING_NEW(sModeString)
1484        Int  default0Save1Load2 = 0;
1485        singleDistTmpLuma=0;
1486        if(modeId == firstCheckId)
1487        {
1488          default0Save1Load2 = 1;
1489        }
1490        else
1491        {
1492          default0Save1Load2 = 2;
1493        }
1494
1495        if (rTu.ProcessComponentSection(COMPONENT_Y))
1496        {
1497          const UInt totalAdjustedDepthChan = rTu.GetTransformDepthTotalAdj(COMPONENT_Y);
1498          pcCU->setTransformSkipSubParts ( modeId, COMPONENT_Y, uiAbsPartIdx, totalAdjustedDepthChan );
1499
1500          xIntraCodingTUBlock( pcOrgYuv, pcPredYuv, pcResiYuv, resiLumaSingle, false, singleDistTmpLuma, COMPONENT_Y, rTu DEBUG_STRING_PASS_INTO(sModeString), default0Save1Load2 );
1501        }
1502        singleCbfTmpLuma = pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, uiTrDepth );
1503
1504        //----- determine rate and r-d cost -----
1505        if(modeId == 1 && singleCbfTmpLuma == 0)
1506        {
1507          //In order not to code TS flag when cbf is zero, the case for TS with cbf being zero is forbidden.
1508          singleCostTmp = MAX_DOUBLE;
1509        }
1510        else
1511        {
1512          UInt uiSingleBits = xGetIntraBitsQT( rTu, true, false, false );
1513          singleCostTmp     = m_pcRdCost->calcRdCost( uiSingleBits, singleDistTmpLuma );
1514        }
1515        if(singleCostTmp < dSingleCost)
1516        {
1517          DEBUG_STRING_SWAP(sDebug, sModeString)
1518          dSingleCost   = singleCostTmp;
1519          uiSingleDistLuma = singleDistTmpLuma;
1520          uiSingleCbfLuma = singleCbfTmpLuma;
1521
1522          bestModeId[COMPONENT_Y] = modeId;
1523          if(bestModeId[COMPONENT_Y] == firstCheckId)
1524          {
1525            xStoreIntraResultQT(COMPONENT_Y, rTu );
1526            m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
1527          }
1528
1529          if (pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag())
1530          {
1531            const Int xOffset = rTu.getRect( COMPONENT_Y ).x0;
1532            const Int yOffset = rTu.getRect( COMPONENT_Y ).y0;
1533            for (UInt storedResidualIndex = 0; storedResidualIndex < NUMBER_OF_STORED_RESIDUAL_TYPES; storedResidualIndex++)
1534            {
1535              if (bMaintainResidual[storedResidualIndex])
1536              {
1537                xStoreCrossComponentPredictionResult(resiLuma[storedResidualIndex], resiLumaSingle[storedResidualIndex], rTu, xOffset, yOffset, MAX_CU_SIZE, MAX_CU_SIZE);
1538              }
1539            }
1540          }
1541        }
1542        if (modeId == firstCheckId)
1543        {
1544          m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1545        }
1546      }
1547
1548      if (rTu.ProcessComponentSection(COMPONENT_Y))
1549      {
1550        const UInt totalAdjustedDepthChan   = rTu.GetTransformDepthTotalAdj(COMPONENT_Y);
1551        pcCU ->setTransformSkipSubParts ( bestModeId[COMPONENT_Y], COMPONENT_Y, uiAbsPartIdx, totalAdjustedDepthChan );
1552      }
1553
1554      if(bestModeId[COMPONENT_Y] == firstCheckId)
1555      {
1556        xLoadIntraResultQT(COMPONENT_Y, rTu );
1557        if (rTu.ProcessComponentSection(COMPONENT_Y))
1558        {
1559          pcCU->setCbfSubParts  ( uiSingleCbfLuma << uiTrDepth, COMPONENT_Y, uiAbsPartIdx, rTu.GetTransformDepthTotalAdj(COMPONENT_Y) );
1560        }
1561
1562        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
1563      }
1564    }
1565    else
1566    {
1567      //----- store original entropy coding status -----
1568      if( bCheckSplit )
1569      {
1570        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1571      }
1572      //----- code luma/chroma block with given intra prediction mode and store Cbf-----
1573      dSingleCost   = 0.0;
1574      if (rTu.ProcessComponentSection(COMPONENT_Y))
1575      {
1576        const UInt totalAdjustedDepthChan   = rTu.GetTransformDepthTotalAdj(COMPONENT_Y);
1577        pcCU ->setTransformSkipSubParts ( 0, COMPONENT_Y, uiAbsPartIdx, totalAdjustedDepthChan );
1578      }
1579
1580      xIntraCodingTUBlock( pcOrgYuv, pcPredYuv, pcResiYuv, resiLumaSingle, false, uiSingleDistLuma, COMPONENT_Y, rTu DEBUG_STRING_PASS_INTO(sDebug));
1581
1582      if( bCheckSplit )
1583      {
1584        uiSingleCbfLuma = pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, uiTrDepth );
1585      }
1586      //----- determine rate and r-d cost -----
1587      UInt uiSingleBits = xGetIntraBitsQT( rTu, true, false, false );
1588
1589      if(m_pcEncCfg->getRDpenalty() && (uiLog2TrSize==5) && !isIntraSlice)
1590      {
1591        uiSingleBits=uiSingleBits*4;
1592      }
1593
1594      dSingleCost       = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDistLuma );
1595
1596      if (pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag())
1597      {
1598        const Int xOffset = rTu.getRect( COMPONENT_Y ).x0;
1599        const Int yOffset = rTu.getRect( COMPONENT_Y ).y0;
1600        for (UInt storedResidualIndex = 0; storedResidualIndex < NUMBER_OF_STORED_RESIDUAL_TYPES; storedResidualIndex++)
1601        {
1602          if (bMaintainResidual[storedResidualIndex])
1603          {
1604            xStoreCrossComponentPredictionResult(resiLuma[storedResidualIndex], resiLumaSingle[storedResidualIndex], rTu, xOffset, yOffset, MAX_CU_SIZE, MAX_CU_SIZE);
1605          }
1606        }
1607      }
1608    }
1609  }
1610
1611  if( bCheckSplit )
1612  {
1613    //----- store full entropy coding status, load original entropy coding status -----
1614    if( bCheckFull )
1615    {
1616      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1617      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1618    }
1619    else
1620    {
1621      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1622    }
1623    //----- code splitted block -----
1624    Double     dSplitCost      = 0.0;
1625    Distortion uiSplitDistLuma = 0;
1626    UInt       uiSplitCbfLuma  = 0;
1627
1628    TComTURecurse tuRecurseChild(rTu, false);
1629    DEBUG_STRING_NEW(sSplit)
1630    do
1631    {
1632      DEBUG_STRING_NEW(sChild)
1633#if HHI_RQT_INTRA_SPEEDUP
1634      xRecurIntraCodingLumaQT( pcOrgYuv, pcPredYuv, pcResiYuv, resiLumaSplit, uiSplitDistLuma, bCheckFirst, dSplitCost, tuRecurseChild DEBUG_STRING_PASS_INTO(sChild) );
1635#else
1636      xRecurIntraCodingLumaQT( pcOrgYuv, pcPredYuv, pcResiYuv, resiLumaSplit, uiSplitDistLuma, dSplitCost, tuRecurseChild DEBUG_STRING_PASS_INTO(sChild) );
1637#endif
1638      DEBUG_STRING_APPEND(sSplit, sChild)
1639      uiSplitCbfLuma |= pcCU->getCbf( tuRecurseChild.GetAbsPartIdxTU(), COMPONENT_Y, tuRecurseChild.GetTransformDepthRel() );
1640    } while (tuRecurseChild.nextSection(rTu) );
1641
1642    UInt    uiPartsDiv     = rTu.GetAbsPartIdxNumParts();
1643    {
1644      if (uiSplitCbfLuma)
1645      {
1646        const UInt flag=1<<uiTrDepth;
1647        UChar *pBase=pcCU->getCbf( COMPONENT_Y );
1648        for( UInt uiOffs = 0; uiOffs < uiPartsDiv; uiOffs++ )
1649        {
1650          pBase[ uiAbsPartIdx + uiOffs ] |= flag;
1651        }
1652      }
1653    }
1654    //----- restore context states -----
1655    m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1656   
1657    //----- determine rate and r-d cost -----
1658    UInt uiSplitBits = xGetIntraBitsQT( rTu, true, false, false );
1659    dSplitCost       = m_pcRdCost->calcRdCost( uiSplitBits, uiSplitDistLuma );
1660
1661    //===== compare and set best =====
1662    if( dSplitCost < dSingleCost )
1663    {
1664      //--- update cost ---
1665      DEBUG_STRING_SWAP(sSplit, sDebug)
1666      ruiDistY += uiSplitDistLuma;
1667      dRDCost  += dSplitCost;
1668
1669      if (pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag())
1670      {
1671        const Int xOffset = rTu.getRect( COMPONENT_Y ).x0;
1672        const Int yOffset = rTu.getRect( COMPONENT_Y ).y0;
1673        for (UInt storedResidualIndex = 0; storedResidualIndex < NUMBER_OF_STORED_RESIDUAL_TYPES; storedResidualIndex++)
1674        {
1675          if (bMaintainResidual[storedResidualIndex])
1676          {
1677            xStoreCrossComponentPredictionResult(resiLuma[storedResidualIndex], resiLumaSplit[storedResidualIndex], rTu, xOffset, yOffset, MAX_CU_SIZE, MAX_CU_SIZE);
1678          }
1679        }
1680      }
1681
1682      return;
1683    }
1684
1685    //----- set entropy coding status -----
1686    m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1687
1688    //--- set transform index and Cbf values ---
1689    pcCU->setTrIdxSubParts( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1690    const TComRectangle &tuRect=rTu.getRect(COMPONENT_Y);
1691    const UInt totalAdjustedDepthChan   = rTu.GetTransformDepthTotalAdj(COMPONENT_Y);
1692    pcCU->setCbfSubParts  ( uiSingleCbfLuma << uiTrDepth, COMPONENT_Y, uiAbsPartIdx, totalAdjustedDepthChan );
1693    pcCU ->setTransformSkipSubParts  ( bestModeId[COMPONENT_Y], COMPONENT_Y, uiAbsPartIdx, totalAdjustedDepthChan );
1694
1695    //--- set reconstruction for next intra prediction blocks ---
1696    const UInt  uiQTLayer   = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1697    const UInt  uiZOrder    = pcCU->getZorderIdxInCtu() + uiAbsPartIdx;
1698    const UInt  uiWidth     = tuRect.width;
1699    const UInt  uiHeight    = tuRect.height;
1700    Pel*  piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getAddr( COMPONENT_Y, uiAbsPartIdx );
1701    UInt  uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ( COMPONENT_Y );
1702    Pel*  piDes       = pcCU->getPic()->getPicYuvRec()->getAddr( COMPONENT_Y, pcCU->getCtuRsAddr(), uiZOrder );
1703    UInt  uiDesStride = pcCU->getPic()->getPicYuvRec()->getStride  ( COMPONENT_Y );
1704
1705    for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1706    {
1707      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1708      {
1709        piDes[ uiX ] = piSrc[ uiX ];
1710      }
1711    }
1712  }
1713  ruiDistY += uiSingleDistLuma;
1714  dRDCost  += dSingleCost;
1715}
1716
1717
1718Void
1719TEncSearch::xSetIntraResultLumaQT(TComYuv* pcRecoYuv, TComTU &rTu)
1720{
1721  TComDataCU *pcCU        = rTu.getCU();
1722  const UInt uiTrDepth    = rTu.GetTransformDepthRel();
1723  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
1724  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1725  if(  uiTrMode == uiTrDepth )
1726  {
1727    UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
1728    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1729
1730    //===== copy transform coefficients =====
1731
1732    const TComRectangle &tuRect=rTu.getRect(COMPONENT_Y);
1733    const UInt coeffOffset = rTu.getCoefficientOffset(COMPONENT_Y);
1734    const UInt numCoeffInBlock = tuRect.width * tuRect.height;
1735
1736    if (numCoeffInBlock!=0)
1737    {
1738      const TCoeff* srcCoeff = m_ppcQTTempCoeff[COMPONENT_Y][uiQTLayer] + coeffOffset;
1739      TCoeff* destCoeff      = pcCU->getCoeff(COMPONENT_Y) + coeffOffset;
1740      ::memcpy( destCoeff, srcCoeff, sizeof(TCoeff)*numCoeffInBlock );
1741#if ADAPTIVE_QP_SELECTION
1742      const TCoeff* srcArlCoeff = m_ppcQTTempArlCoeff[COMPONENT_Y][ uiQTLayer ] + coeffOffset;
1743      TCoeff* destArlCoeff      = pcCU->getArlCoeff (COMPONENT_Y)               + coeffOffset;
1744      ::memcpy( destArlCoeff, srcArlCoeff, sizeof( TCoeff ) * numCoeffInBlock );
1745#endif
1746      m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartComponent( COMPONENT_Y, pcRecoYuv, uiAbsPartIdx, tuRect.width, tuRect.height );
1747    }
1748
1749  }
1750  else
1751  {
1752    TComTURecurse tuRecurseChild(rTu, false);
1753    do
1754    {
1755      xSetIntraResultLumaQT( pcRecoYuv, tuRecurseChild );
1756    } while (tuRecurseChild.nextSection(rTu));
1757  }
1758}
1759
1760
1761Void
1762TEncSearch::xStoreIntraResultQT(const ComponentID compID, TComTU &rTu )
1763{
1764  TComDataCU *pcCU=rTu.getCU();
1765  const UInt uiTrDepth = rTu.GetTransformDepthRel();
1766  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
1767  const UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1768  if ( compID==COMPONENT_Y || uiTrMode == uiTrDepth )
1769  {
1770    assert(uiTrMode == uiTrDepth);
1771    const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
1772    const UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1773
1774    if (rTu.ProcessComponentSection(compID))
1775    {
1776      const TComRectangle &tuRect=rTu.getRect(compID);
1777
1778      //===== copy transform coefficients =====
1779      const UInt uiNumCoeff    = tuRect.width * tuRect.height;
1780      TCoeff* pcCoeffSrc = m_ppcQTTempCoeff[compID] [ uiQTLayer ] + rTu.getCoefficientOffset(compID);
1781      TCoeff* pcCoeffDst = m_pcQTTempTUCoeff[compID];
1782
1783      ::memcpy( pcCoeffDst, pcCoeffSrc, sizeof( TCoeff ) * uiNumCoeff );
1784#if ADAPTIVE_QP_SELECTION
1785      TCoeff* pcArlCoeffSrc = m_ppcQTTempArlCoeff[compID] [ uiQTLayer ] + rTu.getCoefficientOffset(compID);
1786      TCoeff* pcArlCoeffDst = m_ppcQTTempTUArlCoeff[compID];
1787      ::memcpy( pcArlCoeffDst, pcArlCoeffSrc, sizeof( TCoeff ) * uiNumCoeff );
1788#endif
1789      //===== copy reconstruction =====
1790      m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartComponent( compID, &m_pcQTTempTransformSkipTComYuv, uiAbsPartIdx, tuRect.width, tuRect.height );
1791    }
1792  }
1793}
1794
1795
1796Void
1797TEncSearch::xLoadIntraResultQT(const ComponentID compID, TComTU &rTu)
1798{
1799  TComDataCU *pcCU=rTu.getCU();
1800  const UInt uiTrDepth = rTu.GetTransformDepthRel();
1801  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
1802  const UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1803  if ( compID==COMPONENT_Y || uiTrMode == uiTrDepth )
1804  {
1805    assert(uiTrMode == uiTrDepth);
1806    const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
1807    const UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1808    const UInt uiZOrder     = pcCU->getZorderIdxInCtu() + uiAbsPartIdx;
1809
1810    if (rTu.ProcessComponentSection(compID))
1811    {
1812      const TComRectangle &tuRect=rTu.getRect(compID);
1813
1814      //===== copy transform coefficients =====
1815      const UInt uiNumCoeff = tuRect.width * tuRect.height;
1816      TCoeff* pcCoeffDst = m_ppcQTTempCoeff[compID] [ uiQTLayer ] + rTu.getCoefficientOffset(compID);
1817      TCoeff* pcCoeffSrc = m_pcQTTempTUCoeff[compID];
1818
1819      ::memcpy( pcCoeffDst, pcCoeffSrc, sizeof( TCoeff ) * uiNumCoeff );
1820#if ADAPTIVE_QP_SELECTION
1821      TCoeff* pcArlCoeffDst = m_ppcQTTempArlCoeff[compID] [ uiQTLayer ] + rTu.getCoefficientOffset(compID);
1822      TCoeff* pcArlCoeffSrc = m_ppcQTTempTUArlCoeff[compID];
1823      ::memcpy( pcArlCoeffDst, pcArlCoeffSrc, sizeof( TCoeff ) * uiNumCoeff );
1824#endif
1825      //===== copy reconstruction =====
1826      m_pcQTTempTransformSkipTComYuv.copyPartToPartComponent( compID, &m_pcQTTempTComYuv[ uiQTLayer ], uiAbsPartIdx, tuRect.width, tuRect.height );
1827
1828      Pel*    piRecIPred        = pcCU->getPic()->getPicYuvRec()->getAddr( compID, pcCU->getCtuRsAddr(), uiZOrder );
1829      UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getStride (compID);
1830      Pel*    piRecQt           = m_pcQTTempTComYuv[ uiQTLayer ].getAddr( compID, uiAbsPartIdx );
1831      UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getStride  (compID);
1832      UInt    uiWidth           = tuRect.width;
1833      UInt    uiHeight          = tuRect.height;
1834      Pel* pRecQt               = piRecQt;
1835      Pel* pRecIPred            = piRecIPred;
1836      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1837      {
1838        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1839        {
1840          pRecIPred[ uiX ] = pRecQt   [ uiX ];
1841        }
1842        pRecQt    += uiRecQtStride;
1843        pRecIPred += uiRecIPredStride;
1844      }
1845    }
1846  }
1847}
1848
1849Void
1850TEncSearch::xStoreCrossComponentPredictionResult(       Pel    *pResiDst,
1851                                                  const Pel    *pResiSrc,
1852                                                        TComTU &rTu,
1853                                                  const Int     xOffset,
1854                                                  const Int     yOffset,
1855                                                  const Int     strideDst,
1856                                                  const Int     strideSrc )
1857{
1858  const Pel *pSrc = pResiSrc + yOffset * strideSrc + xOffset;
1859        Pel *pDst = pResiDst + yOffset * strideDst + xOffset;
1860
1861  for( Int y = 0; y < rTu.getRect( COMPONENT_Y ).height; y++ )
1862  {
1863    ::memcpy( pDst, pSrc, sizeof(Pel) * rTu.getRect( COMPONENT_Y ).width );
1864    pDst += strideDst;
1865    pSrc += strideSrc;
1866  }
1867}
1868
1869Char
1870TEncSearch::xCalcCrossComponentPredictionAlpha(       TComTU &rTu,
1871                                                const ComponentID compID,
1872                                                const Pel*        piResiL,
1873                                                const Pel*        piResiC,
1874                                                const Int         width,
1875                                                const Int         height,
1876                                                const Int         strideL,
1877                                                const Int         strideC )
1878{
1879  const Pel *pResiL = piResiL;
1880  const Pel *pResiC = piResiC;
1881
1882        TComDataCU *pCU = rTu.getCU();
1883  const Int  absPartIdx = rTu.GetAbsPartIdxTU( compID );
1884  const Int diffBitDepth = pCU->getSlice()->getSPS()->getDifferentialLumaChromaBitDepth();
1885
1886  Char alpha = 0;
1887  Int SSxy  = 0;
1888  Int SSxx  = 0;
1889
1890  for( UInt uiY = 0; uiY < height; uiY++ )
1891  {
1892    for( UInt uiX = 0; uiX < width; uiX++ )
1893    {
1894      const Pel scaledResiL = rightShift( pResiL[ uiX ], diffBitDepth );
1895      SSxy += ( scaledResiL * pResiC[ uiX ] );
1896      SSxx += ( scaledResiL * scaledResiL   );
1897    }
1898
1899    pResiL += strideL;
1900    pResiC += strideC;
1901  }
1902
1903  if( SSxx != 0 )
1904  {
1905    Double dAlpha = SSxy / Double( SSxx );
1906    alpha = Char(Clip3<Int>(-16, 16, (Int)(dAlpha * 16)));
1907
1908    static const Char alphaQuant[17] = {0, 1, 1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8};
1909
1910    alpha = (alpha < 0) ? -alphaQuant[Int(-alpha)] : alphaQuant[Int(alpha)];
1911  }
1912  pCU->setCrossComponentPredictionAlphaPartRange( alpha, compID, absPartIdx, rTu.GetAbsPartIdxNumParts( compID ) );
1913
1914  return alpha;
1915}
1916
1917Void
1918TEncSearch::xRecurIntraChromaCodingQT(TComYuv*    pcOrgYuv,
1919                                      TComYuv*    pcPredYuv,
1920                                      TComYuv*    pcResiYuv,
1921                                      Pel         resiLuma[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE],
1922                                      Distortion& ruiDist,
1923                                      TComTU&     rTu
1924                                      DEBUG_STRING_FN_DECLARE(sDebug))
1925{
1926  TComDataCU         *pcCU                  = rTu.getCU();
1927  const UInt          uiTrDepth             = rTu.GetTransformDepthRel();
1928  const UInt          uiAbsPartIdx          = rTu.GetAbsPartIdxTU();
1929  const ChromaFormat  format                = rTu.GetChromaFormat();
1930  UInt                uiTrMode              = pcCU->getTransformIdx( uiAbsPartIdx );
1931  const UInt          numberValidComponents = getNumberValidComponents(format);
1932
1933  if(  uiTrMode == uiTrDepth )
1934  {
1935    if (!rTu.ProcessChannelSection(CHANNEL_TYPE_CHROMA))
1936    {
1937      return;
1938    }
1939
1940    const UInt uiFullDepth = rTu.GetTransformDepthTotal();
1941
1942    Bool checkTransformSkip = pcCU->getSlice()->getPPS()->getUseTransformSkip();
1943    checkTransformSkip &= TUCompRectHasAssociatedTransformSkipFlag(rTu.getRect(COMPONENT_Cb), pcCU->getSlice()->getPPS()->getPpsRangeExtension().getLog2MaxTransformSkipBlockSize());
1944
1945    if ( m_pcEncCfg->getUseTransformSkipFast() )
1946    {
1947      checkTransformSkip &= TUCompRectHasAssociatedTransformSkipFlag(rTu.getRect(COMPONENT_Y), pcCU->getSlice()->getPPS()->getPpsRangeExtension().getLog2MaxTransformSkipBlockSize());
1948
1949      if (checkTransformSkip)
1950      {
1951        Int nbLumaSkip = 0;
1952        const UInt maxAbsPartIdxSub=uiAbsPartIdx + (rTu.ProcessingAllQuadrants(COMPONENT_Cb)?1:4);
1953        for(UInt absPartIdxSub = uiAbsPartIdx; absPartIdxSub < maxAbsPartIdxSub; absPartIdxSub ++)
1954        {
1955          nbLumaSkip += pcCU->getTransformSkip(absPartIdxSub, COMPONENT_Y);
1956        }
1957        checkTransformSkip &= (nbLumaSkip > 0);
1958      }
1959    }
1960
1961
1962    for (UInt ch=COMPONENT_Cb; ch<numberValidComponents; ch++)
1963    {
1964      const ComponentID compID = ComponentID(ch);
1965      DEBUG_STRING_NEW(sDebugBestMode)
1966
1967      //use RDO to decide whether Cr/Cb takes TS
1968      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[uiFullDepth][CI_QT_TRAFO_ROOT] );
1969
1970      const Bool splitIntoSubTUs = rTu.getRect(compID).width != rTu.getRect(compID).height;
1971
1972      TComTURecurse TUIterator(rTu, false, (splitIntoSubTUs ? TComTU::VERTICAL_SPLIT : TComTU::DONT_SPLIT), true, compID);
1973
1974      const UInt partIdxesPerSubTU = TUIterator.GetAbsPartIdxNumParts(compID);
1975
1976      do
1977      {
1978        const UInt subTUAbsPartIdx   = TUIterator.GetAbsPartIdxTU(compID);
1979
1980        Double     dSingleCost               = MAX_DOUBLE;
1981        Int        bestModeId                = 0;
1982        Distortion singleDistC               = 0;
1983        UInt       singleCbfC                = 0;
1984        Distortion singleDistCTmp            = 0;
1985        Double     singleCostTmp             = 0;
1986        UInt       singleCbfCTmp             = 0;
1987        Char       bestCrossCPredictionAlpha = 0;
1988        Int        bestTransformSkipMode     = 0;
1989
1990        const Bool checkCrossComponentPrediction =    (pcCU->getIntraDir(CHANNEL_TYPE_CHROMA, subTUAbsPartIdx) == DM_CHROMA_IDX)
1991                                                   &&  pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag()
1992                                                   && (pcCU->getCbf(subTUAbsPartIdx,  COMPONENT_Y, uiTrDepth) != 0);
1993
1994        const Int  crossCPredictionModesToTest = checkCrossComponentPrediction ? 2 : 1;
1995        const Int  transformSkipModesToTest    = checkTransformSkip            ? 2 : 1;
1996        const Int  totalModesToTest            = crossCPredictionModesToTest * transformSkipModesToTest;
1997              Int  currModeId                  = 0;
1998              Int  default0Save1Load2          = 0;
1999
2000        for(Int transformSkipModeId = 0; transformSkipModeId < transformSkipModesToTest; transformSkipModeId++)
2001        {
2002          for(Int crossCPredictionModeId = 0; crossCPredictionModeId < crossCPredictionModesToTest; crossCPredictionModeId++)
2003          {
2004            pcCU->setCrossComponentPredictionAlphaPartRange(0, compID, subTUAbsPartIdx, partIdxesPerSubTU);
2005            DEBUG_STRING_NEW(sDebugMode)
2006            pcCU->setTransformSkipPartRange( transformSkipModeId, compID, subTUAbsPartIdx, partIdxesPerSubTU );
2007            currModeId++;
2008
2009            const Bool isOneMode  = (totalModesToTest == 1);
2010            const Bool isLastMode = (currModeId == totalModesToTest); // currModeId is indexed from 1
2011
2012            if (isOneMode)
2013            {
2014              default0Save1Load2 = 0;
2015            }
2016            else if (!isOneMode && (transformSkipModeId == 0) && (crossCPredictionModeId == 0))
2017            {
2018              default0Save1Load2 = 1; //save prediction on first mode
2019            }
2020            else
2021            {
2022              default0Save1Load2 = 2; //load it on subsequent modes
2023            }
2024
2025            singleDistCTmp = 0;
2026
2027            xIntraCodingTUBlock( pcOrgYuv, pcPredYuv, pcResiYuv, resiLuma, (crossCPredictionModeId != 0), singleDistCTmp, compID, TUIterator DEBUG_STRING_PASS_INTO(sDebugMode), default0Save1Load2);
2028            singleCbfCTmp = pcCU->getCbf( subTUAbsPartIdx, compID, uiTrDepth);
2029
2030            if (  ((crossCPredictionModeId == 1) && (pcCU->getCrossComponentPredictionAlpha(subTUAbsPartIdx, compID) == 0))
2031               || ((transformSkipModeId    == 1) && (singleCbfCTmp == 0))) //In order not to code TS flag when cbf is zero, the case for TS with cbf being zero is forbidden.
2032            {
2033              singleCostTmp = MAX_DOUBLE;
2034            }
2035            else if (!isOneMode)
2036            {
2037              UInt bitsTmp = xGetIntraBitsQTChroma( TUIterator, compID, false );
2038              singleCostTmp  = m_pcRdCost->calcRdCost( bitsTmp, singleDistCTmp);
2039            }
2040
2041            if(singleCostTmp < dSingleCost)
2042            {
2043              DEBUG_STRING_SWAP(sDebugBestMode, sDebugMode)
2044              dSingleCost               = singleCostTmp;
2045              singleDistC               = singleDistCTmp;
2046              bestCrossCPredictionAlpha = (crossCPredictionModeId != 0) ? pcCU->getCrossComponentPredictionAlpha(subTUAbsPartIdx, compID) : 0;
2047              bestTransformSkipMode     = transformSkipModeId;
2048              bestModeId                = currModeId;
2049              singleCbfC                = singleCbfCTmp;
2050
2051              if (!isOneMode && !isLastMode)
2052              {
2053                xStoreIntraResultQT(compID, TUIterator);
2054                m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
2055              }
2056            }
2057
2058            if (!isOneMode && !isLastMode)
2059            {
2060              m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
2061            }
2062          }
2063        }
2064
2065        if(bestModeId < totalModesToTest)
2066        {
2067          xLoadIntraResultQT(compID, TUIterator);
2068          pcCU->setCbfPartRange( singleCbfC << uiTrDepth, compID, subTUAbsPartIdx, partIdxesPerSubTU );
2069
2070          m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
2071        }
2072
2073        DEBUG_STRING_APPEND(sDebug, sDebugBestMode)
2074        pcCU ->setTransformSkipPartRange                ( bestTransformSkipMode,     compID, subTUAbsPartIdx, partIdxesPerSubTU );
2075        pcCU ->setCrossComponentPredictionAlphaPartRange( bestCrossCPredictionAlpha, compID, subTUAbsPartIdx, partIdxesPerSubTU );
2076        ruiDist += singleDistC;
2077      } while (TUIterator.nextSection(rTu));
2078
2079      if (splitIntoSubTUs)
2080      {
2081        offsetSubTUCBFs(rTu, compID);
2082      }
2083    }
2084  }
2085  else
2086  {
2087    UInt    uiSplitCbf[MAX_NUM_COMPONENT] = {0,0,0};
2088
2089    TComTURecurse tuRecurseChild(rTu, false);
2090    const UInt uiTrDepthChild   = tuRecurseChild.GetTransformDepthRel();
2091    do
2092    {
2093      DEBUG_STRING_NEW(sChild)
2094
2095      xRecurIntraChromaCodingQT( pcOrgYuv, pcPredYuv, pcResiYuv, resiLuma, ruiDist, tuRecurseChild DEBUG_STRING_PASS_INTO(sChild) );
2096
2097      DEBUG_STRING_APPEND(sDebug, sChild)
2098      const UInt uiAbsPartIdxSub=tuRecurseChild.GetAbsPartIdxTU();
2099
2100      for(UInt ch=COMPONENT_Cb; ch<numberValidComponents; ch++)
2101      {
2102        uiSplitCbf[ch] |= pcCU->getCbf( uiAbsPartIdxSub, ComponentID(ch), uiTrDepthChild );
2103      }
2104    } while ( tuRecurseChild.nextSection(rTu) );
2105
2106
2107    UInt uiPartsDiv = rTu.GetAbsPartIdxNumParts();
2108    for(UInt ch=COMPONENT_Cb; ch<numberValidComponents; ch++)
2109    {
2110      if (uiSplitCbf[ch])
2111      {
2112        const UInt flag=1<<uiTrDepth;
2113        ComponentID compID=ComponentID(ch);
2114        UChar *pBase=pcCU->getCbf( compID );
2115        for( UInt uiOffs = 0; uiOffs < uiPartsDiv; uiOffs++ )
2116        {
2117          pBase[ uiAbsPartIdx + uiOffs ] |= flag;
2118        }
2119      }
2120    }
2121  }
2122}
2123
2124
2125
2126
2127Void
2128TEncSearch::xSetIntraResultChromaQT(TComYuv*    pcRecoYuv, TComTU &rTu)
2129{
2130  if (!rTu.ProcessChannelSection(CHANNEL_TYPE_CHROMA))
2131  {
2132    return;
2133  }
2134  TComDataCU *pcCU=rTu.getCU();
2135  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
2136  const UInt uiTrDepth   = rTu.GetTransformDepthRel();
2137  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
2138  if(  uiTrMode == uiTrDepth )
2139  {
2140    UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
2141    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
2142
2143    //===== copy transform coefficients =====
2144    const TComRectangle &tuRectCb=rTu.getRect(COMPONENT_Cb);
2145    UInt uiNumCoeffC    = tuRectCb.width*tuRectCb.height;//( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
2146    const UInt offset = rTu.getCoefficientOffset(COMPONENT_Cb);
2147
2148    const UInt numberValidComponents = getNumberValidComponents(rTu.GetChromaFormat());
2149    for (UInt ch=COMPONENT_Cb; ch<numberValidComponents; ch++)
2150    {
2151      const ComponentID component = ComponentID(ch);
2152      const TCoeff* src           = m_ppcQTTempCoeff[component][uiQTLayer] + offset;//(uiNumCoeffIncC*uiAbsPartIdx);
2153      TCoeff* dest                = pcCU->getCoeff(component) + offset;//(uiNumCoeffIncC*uiAbsPartIdx);
2154      ::memcpy( dest, src, sizeof(TCoeff)*uiNumCoeffC );
2155#if ADAPTIVE_QP_SELECTION
2156      TCoeff* pcArlCoeffSrc = m_ppcQTTempArlCoeff[component][ uiQTLayer ] + offset;//( uiNumCoeffIncC * uiAbsPartIdx );
2157      TCoeff* pcArlCoeffDst = pcCU->getArlCoeff(component)                + offset;//( uiNumCoeffIncC * uiAbsPartIdx );
2158      ::memcpy( pcArlCoeffDst, pcArlCoeffSrc, sizeof( TCoeff ) * uiNumCoeffC );
2159#endif
2160    }
2161
2162    //===== copy reconstruction =====
2163
2164    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartComponent( COMPONENT_Cb, pcRecoYuv, uiAbsPartIdx, tuRectCb.width, tuRectCb.height );
2165    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartComponent( COMPONENT_Cr, pcRecoYuv, uiAbsPartIdx, tuRectCb.width, tuRectCb.height );
2166  }
2167  else
2168  {
2169    TComTURecurse tuRecurseChild(rTu, false);
2170    do
2171    {
2172      xSetIntraResultChromaQT( pcRecoYuv, tuRecurseChild );
2173    } while (tuRecurseChild.nextSection(rTu));
2174  }
2175}
2176
2177
2178
2179Void
2180TEncSearch::estIntraPredLumaQT(TComDataCU* pcCU,
2181                               TComYuv*    pcOrgYuv,
2182                               TComYuv*    pcPredYuv,
2183                               TComYuv*    pcResiYuv,
2184                               TComYuv*    pcRecoYuv,
2185                               Pel         resiLuma[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE]
2186                               DEBUG_STRING_FN_DECLARE(sDebug))
2187{
2188  const UInt         uiDepth               = pcCU->getDepth(0);
2189  const UInt         uiInitTrDepth         = pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1;
2190  const UInt         uiNumPU               = 1<<(2*uiInitTrDepth);
2191  const UInt         uiQNumParts           = pcCU->getTotalNumPart() >> 2;
2192  const UInt         uiWidthBit            = pcCU->getIntraSizeIdx(0);
2193  const ChromaFormat chFmt                 = pcCU->getPic()->getChromaFormat();
2194  const UInt         numberValidComponents = getNumberValidComponents(chFmt);
2195  const TComSPS     &sps                   = *(pcCU->getSlice()->getSPS());
2196  const TComPPS     &pps                   = *(pcCU->getSlice()->getPPS());
2197        Distortion   uiOverallDistY        = 0;
2198        UInt         CandNum;
2199        Double       CandCostList[ FAST_UDI_MAX_RDMODE_NUM ];
2200        Pel          resiLumaPU[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE];
2201
2202        Bool    bMaintainResidual[NUMBER_OF_STORED_RESIDUAL_TYPES];
2203        for (UInt residualTypeIndex = 0; residualTypeIndex < NUMBER_OF_STORED_RESIDUAL_TYPES; residualTypeIndex++)
2204        {
2205          bMaintainResidual[residualTypeIndex] = true; //assume true unless specified otherwise
2206        }
2207
2208        bMaintainResidual[RESIDUAL_ENCODER_SIDE] = !(m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate());
2209
2210  // Lambda calculation at equivalent Qp of 4 is recommended because at that Qp, the quantisation divisor is 1.
2211#if FULL_NBIT
2212  const Double sqrtLambdaForFirstPass= (m_pcEncCfg->getCostMode()==COST_MIXED_LOSSLESS_LOSSY_CODING && pcCU->getCUTransquantBypass(0)) ?
2213                sqrt(0.57 * pow(2.0, ((LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP_PRIME - 12) / 3.0)))
2214              : m_pcRdCost->getSqrtLambda();
2215#else
2216  const Double sqrtLambdaForFirstPass= (m_pcEncCfg->getCostMode()==COST_MIXED_LOSSLESS_LOSSY_CODING && pcCU->getCUTransquantBypass(0)) ?
2217#if SVC_EXTENSION
2218                sqrt(0.57 * pow(2.0, ((LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP_PRIME - 12 - 6 * (pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA) - 8)) / 3.0)))
2219#else
2220                sqrt(0.57 * pow(2.0, ((LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP_PRIME - 12 - 6 * (sps.getBitDepth(CHANNEL_TYPE_LUMA) - 8)) / 3.0)))
2221#endif
2222              : m_pcRdCost->getSqrtLambda();
2223#endif
2224
2225  //===== set QP and clear Cbf =====
2226  if ( pps.getUseDQP() == true)
2227  {
2228    pcCU->setQPSubParts( pcCU->getQP(0), 0, uiDepth );
2229  }
2230  else
2231  {
2232    pcCU->setQPSubParts( pcCU->getSlice()->getSliceQp(), 0, uiDepth );
2233  }
2234
2235  //===== loop over partitions =====
2236  TComTURecurse tuRecurseCU(pcCU, 0);
2237  TComTURecurse tuRecurseWithPU(tuRecurseCU, false, (uiInitTrDepth==0)?TComTU::DONT_SPLIT : TComTU::QUAD_SPLIT);
2238
2239  do
2240  {
2241    const UInt uiPartOffset=tuRecurseWithPU.GetAbsPartIdxTU();
2242//  for( UInt uiPU = 0, uiPartOffset=0; uiPU < uiNumPU; uiPU++, uiPartOffset += uiQNumParts )
2243  //{
2244    //===== init pattern for luma prediction =====
2245    Bool bAboveAvail = false;
2246    Bool bLeftAvail  = false;
2247    DEBUG_STRING_NEW(sTemp2)
2248
2249    //===== determine set of modes to be tested (using prediction signal only) =====
2250    Int numModesAvailable     = 35; //total number of Intra modes
2251    UInt uiRdModeList[FAST_UDI_MAX_RDMODE_NUM];
2252    Int numModesForFullRD = m_pcEncCfg->getFastUDIUseMPMEnabled()?g_aucIntraModeNumFast_UseMPM[ uiWidthBit ] : g_aucIntraModeNumFast_NotUseMPM[ uiWidthBit ];
2253
2254    if (tuRecurseWithPU.ProcessComponentSection(COMPONENT_Y))
2255    {
2256      initIntraPatternChType( tuRecurseWithPU, bAboveAvail, bLeftAvail, COMPONENT_Y, true DEBUG_STRING_PASS_INTO(sTemp2) );
2257    }
2258
2259    Bool doFastSearch = (numModesForFullRD != numModesAvailable);
2260    if (doFastSearch)
2261    {
2262      assert(numModesForFullRD < numModesAvailable);
2263#if FAST_INTRA_SHVC
2264      Int   uiPreds[3] = {-1, -1, -1};
2265      Int   iMode = -1;
2266      Bool  skipFastHAD = false;
2267      pcCU->getIntraDirPredictor( uiPartOffset, uiPreds, COMPONENT_Y, &iMode );
2268
2269      if( m_pcEncCfg->getUseFastIntraScalable() && pcCU->getLayerId() > 0 )
2270      {
2271        numModesAvailable = pcCU->reduceSetOfIntraModes(uiPartOffset, uiPreds, iMode );
2272        if( numModesForFullRD > numModesAvailable ) //fast HAD can be skipped
2273        {
2274          skipFastHAD = true;
2275          numModesForFullRD = numModesAvailable;
2276          for( Int i=0; i < numModesForFullRD; i++ )
2277          {
2278            uiRdModeList[ i ] = g_reducedSetIntraModes[ i ];
2279          }
2280        }
2281      }
2282#endif
2283
2284      for( Int i=0; i < numModesForFullRD; i++ )
2285      {
2286        CandCostList[ i ] = MAX_DOUBLE;
2287      }
2288      CandNum = 0;
2289
2290      const TComRectangle &puRect=tuRecurseWithPU.getRect(COMPONENT_Y);
2291      const UInt uiAbsPartIdx=tuRecurseWithPU.GetAbsPartIdxTU();
2292
2293      Pel* piOrg         = pcOrgYuv ->getAddr( COMPONENT_Y, uiAbsPartIdx );
2294      Pel* piPred        = pcPredYuv->getAddr( COMPONENT_Y, uiAbsPartIdx );
2295      UInt uiStride      = pcPredYuv->getStride( COMPONENT_Y );
2296      DistParam distParam;
2297      const Bool bUseHadamard=pcCU->getCUTransquantBypass(0) == 0;
2298#if SVC_EXTENSION
2299      m_pcRdCost->setDistParam(distParam, pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA), piOrg, uiStride, piPred, uiStride, puRect.width, puRect.height, bUseHadamard);
2300#else
2301      m_pcRdCost->setDistParam(distParam, sps.getBitDepth(CHANNEL_TYPE_LUMA), piOrg, uiStride, piPred, uiStride, puRect.width, puRect.height, bUseHadamard);
2302#endif
2303      distParam.bApplyWeight = false;
2304      for( Int modeIdx = 0; modeIdx < numModesAvailable; modeIdx++ )
2305      {
2306        UInt       uiMode = modeIdx;
2307        Distortion uiSad  = 0;
2308#if FAST_INTRA_SHVC
2309        if ( m_pcEncCfg->getUseFastIntraScalable() )
2310        {
2311          if( skipFastHAD )//indicates that fast HAD can be skipped
2312          {
2313            break;
2314          }
2315          uiMode = ( iMode==0 ) ? g_reducedSetIntraModes[modeIdx] : uiMode; //(iMode=0) indicates reduced set of modes
2316        }
2317#endif
2318
2319        const Bool bUseFilter=TComPrediction::filteringIntraReferenceSamples(COMPONENT_Y, uiMode, puRect.width, puRect.height, chFmt, sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag());
2320
2321        predIntraAng( COMPONENT_Y, uiMode, piOrg, uiStride, piPred, uiStride, tuRecurseWithPU, bAboveAvail, bLeftAvail, bUseFilter, TComPrediction::UseDPCMForFirstPassIntraEstimation(tuRecurseWithPU, uiMode) );
2322
2323        // use hadamard transform here
2324        uiSad+=distParam.DistFunc(&distParam);
2325
2326        UInt   iModeBits = 0;
2327
2328        // NB xModeBitsIntra will not affect the mode for chroma that may have already been pre-estimated.
2329        iModeBits+=xModeBitsIntra( pcCU, uiMode, uiPartOffset, uiDepth, CHANNEL_TYPE_LUMA );
2330
2331        Double cost      = (Double)uiSad + (Double)iModeBits * sqrtLambdaForFirstPass;
2332
2333#if DEBUG_INTRA_SEARCH_COSTS
2334        std::cout << "1st pass mode " << uiMode << " SAD = " << uiSad << ", mode bits = " << iModeBits << ", cost = " << cost << "\n";
2335#endif
2336
2337        CandNum += xUpdateCandList( uiMode, cost, numModesForFullRD, uiRdModeList, CandCostList );
2338      }
2339
2340      if (m_pcEncCfg->getFastUDIUseMPMEnabled())
2341      {
2342#if FAST_INTRA_SHVC == 0
2343        Int uiPreds[NUM_MOST_PROBABLE_MODES] = {-1, -1, -1};
2344
2345        Int iMode = -1;
2346        pcCU->getIntraDirPredictor( uiPartOffset, uiPreds, COMPONENT_Y, &iMode );
2347#endif
2348        const Int numCand = ( iMode >= 0 ) ? iMode : Int(NUM_MOST_PROBABLE_MODES);
2349
2350        for( Int j=0; j < numCand; j++)
2351        {
2352          Bool mostProbableModeIncluded = false;
2353          Int mostProbableMode = uiPreds[j];
2354
2355          for( Int i=0; i < numModesForFullRD; i++)
2356          {
2357            mostProbableModeIncluded |= (mostProbableMode == uiRdModeList[i]);
2358          }
2359          if (!mostProbableModeIncluded)
2360          {
2361            uiRdModeList[numModesForFullRD++] = mostProbableMode;
2362          }
2363        }
2364      }
2365    }
2366    else
2367    {
2368      for( Int i=0; i < numModesForFullRD; i++)
2369      {
2370        uiRdModeList[i] = i;
2371      }
2372    }
2373
2374    //===== check modes (using r-d costs) =====
2375#if HHI_RQT_INTRA_SPEEDUP_MOD
2376    UInt   uiSecondBestMode  = MAX_UINT;
2377    Double dSecondBestPUCost = MAX_DOUBLE;
2378#endif
2379    DEBUG_STRING_NEW(sPU)
2380    UInt       uiBestPUMode  = 0;
2381    Distortion uiBestPUDistY = 0;
2382    Double     dBestPUCost   = MAX_DOUBLE;
2383
2384#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
2385    UInt max=numModesForFullRD;
2386
2387    if (DebugOptionList::ForceLumaMode.isSet())
2388    {
2389      max=0;  // we are forcing a direction, so don't bother with mode check
2390    }
2391    for ( UInt uiMode = 0; uiMode < max; uiMode++)
2392#else
2393    for( UInt uiMode = 0; uiMode < numModesForFullRD; uiMode++ )
2394#endif
2395    {
2396      // set luma prediction mode
2397      UInt uiOrgMode = uiRdModeList[uiMode];
2398
2399      pcCU->setIntraDirSubParts ( CHANNEL_TYPE_LUMA, uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2400
2401      DEBUG_STRING_NEW(sMode)
2402      // set context models
2403      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2404
2405      // determine residual for partition
2406      Distortion uiPUDistY = 0;
2407      Double     dPUCost   = 0.0;
2408#if HHI_RQT_INTRA_SPEEDUP
2409      xRecurIntraCodingLumaQT( pcOrgYuv, pcPredYuv, pcResiYuv, resiLumaPU, uiPUDistY, true, dPUCost, tuRecurseWithPU DEBUG_STRING_PASS_INTO(sMode) );
2410#else
2411      xRecurIntraCodingLumaQT( pcOrgYuv, pcPredYuv, pcResiYuv, resiLumaPU, uiPUDistY, dPUCost, tuRecurseWithPU DEBUG_STRING_PASS_INTO(sMode) );
2412#endif
2413
2414#if DEBUG_INTRA_SEARCH_COSTS
2415      std::cout << "2nd pass [luma,chroma] mode [" << Int(pcCU->getIntraDir(CHANNEL_TYPE_LUMA, uiPartOffset)) << "," << Int(pcCU->getIntraDir(CHANNEL_TYPE_CHROMA, uiPartOffset)) << "] cost = " << dPUCost << "\n";
2416#endif
2417
2418      // check r-d cost
2419      if( dPUCost < dBestPUCost )
2420      {
2421        DEBUG_STRING_SWAP(sPU, sMode)
2422#if HHI_RQT_INTRA_SPEEDUP_MOD
2423        uiSecondBestMode  = uiBestPUMode;
2424        dSecondBestPUCost = dBestPUCost;
2425#endif
2426        uiBestPUMode  = uiOrgMode;
2427        uiBestPUDistY = uiPUDistY;
2428        dBestPUCost   = dPUCost;
2429
2430        xSetIntraResultLumaQT( pcRecoYuv, tuRecurseWithPU );
2431
2432        if (pps.getPpsRangeExtension().getCrossComponentPredictionEnabledFlag())
2433        {
2434          const Int xOffset = tuRecurseWithPU.getRect( COMPONENT_Y ).x0;
2435          const Int yOffset = tuRecurseWithPU.getRect( COMPONENT_Y ).y0;
2436          for (UInt storedResidualIndex = 0; storedResidualIndex < NUMBER_OF_STORED_RESIDUAL_TYPES; storedResidualIndex++)
2437          {
2438            if (bMaintainResidual[storedResidualIndex])
2439            {
2440              xStoreCrossComponentPredictionResult(resiLuma[storedResidualIndex], resiLumaPU[storedResidualIndex], tuRecurseWithPU, xOffset, yOffset, MAX_CU_SIZE, MAX_CU_SIZE );
2441            }
2442          }
2443        }
2444
2445        UInt uiQPartNum = tuRecurseWithPU.GetAbsPartIdxNumParts();
2446
2447        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2448        for (UInt component = 0; component < numberValidComponents; component++)
2449        {
2450          const ComponentID compID = ComponentID(component);
2451          ::memcpy( m_puhQTTempCbf[compID], pcCU->getCbf( compID  ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2452          ::memcpy( m_puhQTTempTransformSkipFlag[compID],  pcCU->getTransformSkip(compID)  + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2453        }
2454      }
2455#if HHI_RQT_INTRA_SPEEDUP_MOD
2456      else if( dPUCost < dSecondBestPUCost )
2457      {
2458        uiSecondBestMode  = uiOrgMode;
2459        dSecondBestPUCost = dPUCost;
2460      }
2461#endif
2462    } // Mode loop
2463
2464#if HHI_RQT_INTRA_SPEEDUP
2465#if HHI_RQT_INTRA_SPEEDUP_MOD
2466    for( UInt ui =0; ui < 2; ++ui )
2467#endif
2468    {
2469#if HHI_RQT_INTRA_SPEEDUP_MOD
2470      UInt uiOrgMode   = ui ? uiSecondBestMode  : uiBestPUMode;
2471      if( uiOrgMode == MAX_UINT )
2472      {
2473        break;
2474      }
2475#else
2476      UInt uiOrgMode = uiBestPUMode;
2477#endif
2478
2479#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
2480      if (DebugOptionList::ForceLumaMode.isSet())
2481      {
2482        uiOrgMode = DebugOptionList::ForceLumaMode.getInt();
2483      }
2484#endif
2485
2486      pcCU->setIntraDirSubParts ( CHANNEL_TYPE_LUMA, uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2487      DEBUG_STRING_NEW(sModeTree)
2488
2489      // set context models
2490      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2491
2492      // determine residual for partition
2493      Distortion uiPUDistY = 0;
2494      Double     dPUCost   = 0.0;
2495
2496      xRecurIntraCodingLumaQT( pcOrgYuv, pcPredYuv, pcResiYuv, resiLumaPU, uiPUDistY, false, dPUCost, tuRecurseWithPU DEBUG_STRING_PASS_INTO(sModeTree));
2497
2498      // check r-d cost
2499      if( dPUCost < dBestPUCost )
2500      {
2501        DEBUG_STRING_SWAP(sPU, sModeTree)
2502        uiBestPUMode  = uiOrgMode;
2503        uiBestPUDistY = uiPUDistY;
2504        dBestPUCost   = dPUCost;
2505
2506        xSetIntraResultLumaQT( pcRecoYuv, tuRecurseWithPU );
2507
2508        if (pps.getPpsRangeExtension().getCrossComponentPredictionEnabledFlag())
2509        {
2510          const Int xOffset = tuRecurseWithPU.getRect( COMPONENT_Y ).x0;
2511          const Int yOffset = tuRecurseWithPU.getRect( COMPONENT_Y ).y0;
2512          for (UInt storedResidualIndex = 0; storedResidualIndex < NUMBER_OF_STORED_RESIDUAL_TYPES; storedResidualIndex++)
2513          {
2514            if (bMaintainResidual[storedResidualIndex])
2515            {
2516              xStoreCrossComponentPredictionResult(resiLuma[storedResidualIndex], resiLumaPU[storedResidualIndex], tuRecurseWithPU, xOffset, yOffset, MAX_CU_SIZE, MAX_CU_SIZE );
2517            }
2518          }
2519        }
2520
2521        const UInt uiQPartNum = tuRecurseWithPU.GetAbsPartIdxNumParts();
2522        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2523
2524        for (UInt component = 0; component < numberValidComponents; component++)
2525        {
2526          const ComponentID compID = ComponentID(component);
2527          ::memcpy( m_puhQTTempCbf[compID], pcCU->getCbf( compID  ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2528          ::memcpy( m_puhQTTempTransformSkipFlag[compID],  pcCU->getTransformSkip(compID)  + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2529        }
2530      }
2531    } // Mode loop
2532#endif
2533
2534    DEBUG_STRING_APPEND(sDebug, sPU)
2535
2536    //--- update overall distortion ---
2537    uiOverallDistY += uiBestPUDistY;
2538
2539    //--- update transform index and cbf ---
2540    const UInt uiQPartNum = tuRecurseWithPU.GetAbsPartIdxNumParts();
2541    ::memcpy( pcCU->getTransformIdx()       + uiPartOffset, m_puhQTTempTrIdx,  uiQPartNum * sizeof( UChar ) );
2542    for (UInt component = 0; component < numberValidComponents; component++)
2543    {
2544      const ComponentID compID = ComponentID(component);
2545      ::memcpy( pcCU->getCbf( compID  ) + uiPartOffset, m_puhQTTempCbf[compID], uiQPartNum * sizeof( UChar ) );
2546      ::memcpy( pcCU->getTransformSkip( compID  ) + uiPartOffset, m_puhQTTempTransformSkipFlag[compID ], uiQPartNum * sizeof( UChar ) );
2547    }
2548
2549    //--- set reconstruction for next intra prediction blocks ---
2550    if( !tuRecurseWithPU.IsLastSection() )
2551    {
2552      const TComRectangle &puRect=tuRecurseWithPU.getRect(COMPONENT_Y);
2553      const UInt  uiCompWidth   = puRect.width;
2554      const UInt  uiCompHeight  = puRect.height;
2555
2556      const UInt  uiZOrder      = pcCU->getZorderIdxInCtu() + uiPartOffset;
2557            Pel*  piDes         = pcCU->getPic()->getPicYuvRec()->getAddr( COMPONENT_Y, pcCU->getCtuRsAddr(), uiZOrder );
2558      const UInt  uiDesStride   = pcCU->getPic()->getPicYuvRec()->getStride( COMPONENT_Y);
2559      const Pel*  piSrc         = pcRecoYuv->getAddr( COMPONENT_Y, uiPartOffset );
2560      const UInt  uiSrcStride   = pcRecoYuv->getStride( COMPONENT_Y);
2561
2562      for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2563      {
2564        for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2565        {
2566          piDes[ uiX ] = piSrc[ uiX ];
2567        }
2568      }
2569    }
2570
2571    //=== update PU data ====
2572    pcCU->setIntraDirSubParts     ( CHANNEL_TYPE_LUMA, uiBestPUMode, uiPartOffset, uiDepth + uiInitTrDepth );
2573  } while (tuRecurseWithPU.nextSection(tuRecurseCU));
2574
2575
2576  if( uiNumPU > 1 )
2577  { // set Cbf for all blocks
2578    UInt uiCombCbfY = 0;
2579    UInt uiCombCbfU = 0;
2580    UInt uiCombCbfV = 0;
2581    UInt uiPartIdx  = 0;
2582    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += uiQNumParts )
2583    {
2584      uiCombCbfY |= pcCU->getCbf( uiPartIdx, COMPONENT_Y,  1 );
2585      uiCombCbfU |= pcCU->getCbf( uiPartIdx, COMPONENT_Cb, 1 );
2586      uiCombCbfV |= pcCU->getCbf( uiPartIdx, COMPONENT_Cr, 1 );
2587    }
2588    for( UInt uiOffs = 0; uiOffs < 4 * uiQNumParts; uiOffs++ )
2589    {
2590      pcCU->getCbf( COMPONENT_Y  )[ uiOffs ] |= uiCombCbfY;
2591      pcCU->getCbf( COMPONENT_Cb )[ uiOffs ] |= uiCombCbfU;
2592      pcCU->getCbf( COMPONENT_Cr )[ uiOffs ] |= uiCombCbfV;
2593    }
2594  }
2595
2596  //===== reset context models =====
2597  m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2598
2599  //===== set distortion (rate and r-d costs are determined later) =====
2600  pcCU->getTotalDistortion() = uiOverallDistY;
2601}
2602
2603
2604
2605
2606Void
2607TEncSearch::estIntraPredChromaQT(TComDataCU* pcCU,
2608                                 TComYuv*    pcOrgYuv,
2609                                 TComYuv*    pcPredYuv,
2610                                 TComYuv*    pcResiYuv,
2611                                 TComYuv*    pcRecoYuv,
2612                                 Pel         resiLuma[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE]
2613                                 DEBUG_STRING_FN_DECLARE(sDebug))
2614{
2615  const UInt    uiInitTrDepth  = pcCU->getPartitionSize(0) != SIZE_2Nx2N && enable4ChromaPUsInIntraNxNCU(pcOrgYuv->getChromaFormat()) ? 1 : 0;
2616
2617  TComTURecurse tuRecurseCU(pcCU, 0);
2618  TComTURecurse tuRecurseWithPU(tuRecurseCU, false, (uiInitTrDepth==0)?TComTU::DONT_SPLIT : TComTU::QUAD_SPLIT);
2619  const UInt    uiQNumParts    = tuRecurseWithPU.GetAbsPartIdxNumParts();
2620  const UInt    uiDepthCU=tuRecurseWithPU.getCUDepth();
2621  const UInt    numberValidComponents = pcCU->getPic()->getNumberValidComponents();
2622
2623  do
2624  {
2625    UInt       uiBestMode  = 0;
2626    Distortion uiBestDist  = 0;
2627    Double     dBestCost   = MAX_DOUBLE;
2628
2629    //----- init mode list -----
2630    if (tuRecurseWithPU.ProcessChannelSection(CHANNEL_TYPE_CHROMA))
2631    {
2632      UInt uiModeList[FAST_UDI_MAX_RDMODE_NUM];
2633      const UInt  uiQPartNum     = uiQNumParts;
2634      const UInt  uiPartOffset   = tuRecurseWithPU.GetAbsPartIdxTU();
2635      {
2636        UInt  uiMinMode = 0;
2637        UInt  uiMaxMode = NUM_CHROMA_MODE;
2638
2639        //----- check chroma modes -----
2640        pcCU->getAllowedChromaDir( uiPartOffset, uiModeList );
2641
2642#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
2643        if (DebugOptionList::ForceChromaMode.isSet())
2644        {
2645          uiMinMode=DebugOptionList::ForceChromaMode.getInt();
2646          if (uiModeList[uiMinMode]==34)
2647          {
2648            uiMinMode=4; // if the fixed mode has been renumbered because DM_CHROMA covers it, use DM_CHROMA.
2649          }
2650          uiMaxMode=uiMinMode+1;
2651        }
2652#endif
2653
2654        DEBUG_STRING_NEW(sPU)
2655
2656        for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )
2657        {
2658          //----- restore context models -----
2659          m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepthCU][CI_CURR_BEST] );
2660         
2661          DEBUG_STRING_NEW(sMode)
2662          //----- chroma coding -----
2663          Distortion uiDist = 0;
2664          pcCU->setIntraDirSubParts  ( CHANNEL_TYPE_CHROMA, uiModeList[uiMode], uiPartOffset, uiDepthCU+uiInitTrDepth );
2665          xRecurIntraChromaCodingQT       ( pcOrgYuv, pcPredYuv, pcResiYuv, resiLuma, uiDist, tuRecurseWithPU DEBUG_STRING_PASS_INTO(sMode) );
2666
2667          if( pcCU->getSlice()->getPPS()->getUseTransformSkip() )
2668          {
2669            m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepthCU][CI_CURR_BEST] );
2670          }
2671
2672          UInt    uiBits = xGetIntraBitsQT( tuRecurseWithPU, false, true, false );
2673          Double  dCost  = m_pcRdCost->calcRdCost( uiBits, uiDist );
2674
2675          //----- compare -----
2676          if( dCost < dBestCost )
2677          {
2678            DEBUG_STRING_SWAP(sPU, sMode);
2679            dBestCost   = dCost;
2680            uiBestDist  = uiDist;
2681            uiBestMode  = uiModeList[uiMode];
2682
2683            xSetIntraResultChromaQT( pcRecoYuv, tuRecurseWithPU );
2684            for (UInt componentIndex = COMPONENT_Cb; componentIndex < numberValidComponents; componentIndex++)
2685            {
2686              const ComponentID compID = ComponentID(componentIndex);
2687              ::memcpy( m_puhQTTempCbf[compID], pcCU->getCbf( compID )+uiPartOffset, uiQPartNum * sizeof( UChar ) );
2688              ::memcpy( m_puhQTTempTransformSkipFlag[compID], pcCU->getTransformSkip( compID )+uiPartOffset, uiQPartNum * sizeof( UChar ) );
2689              ::memcpy( m_phQTTempCrossComponentPredictionAlpha[compID], pcCU->getCrossComponentPredictionAlpha(compID)+uiPartOffset, uiQPartNum * sizeof( Char ) );
2690            }
2691          }
2692        }
2693
2694        DEBUG_STRING_APPEND(sDebug, sPU)
2695
2696        //----- set data -----
2697        for (UInt componentIndex = COMPONENT_Cb; componentIndex < numberValidComponents; componentIndex++)
2698        {
2699          const ComponentID compID = ComponentID(componentIndex);
2700          ::memcpy( pcCU->getCbf( compID )+uiPartOffset, m_puhQTTempCbf[compID], uiQPartNum * sizeof( UChar ) );
2701          ::memcpy( pcCU->getTransformSkip( compID )+uiPartOffset, m_puhQTTempTransformSkipFlag[compID], uiQPartNum * sizeof( UChar ) );
2702          ::memcpy( pcCU->getCrossComponentPredictionAlpha(compID)+uiPartOffset, m_phQTTempCrossComponentPredictionAlpha[compID], uiQPartNum * sizeof( Char ) );
2703        }
2704      }
2705
2706      if( ! tuRecurseWithPU.IsLastSection() )
2707      {
2708        for (UInt ch=COMPONENT_Cb; ch<numberValidComponents; ch++)
2709        {
2710          const ComponentID compID    = ComponentID(ch);
2711          const TComRectangle &tuRect = tuRecurseWithPU.getRect(compID);
2712          const UInt  uiCompWidth     = tuRect.width;
2713          const UInt  uiCompHeight    = tuRect.height;
2714          const UInt  uiZOrder        = pcCU->getZorderIdxInCtu() + tuRecurseWithPU.GetAbsPartIdxTU();
2715                Pel*  piDes           = pcCU->getPic()->getPicYuvRec()->getAddr( compID, pcCU->getCtuRsAddr(), uiZOrder );
2716          const UInt  uiDesStride     = pcCU->getPic()->getPicYuvRec()->getStride( compID);
2717          const Pel*  piSrc           = pcRecoYuv->getAddr( compID, uiPartOffset );
2718          const UInt  uiSrcStride     = pcRecoYuv->getStride( compID);
2719
2720          for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2721          {
2722            for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2723            {
2724              piDes[ uiX ] = piSrc[ uiX ];
2725            }
2726          }
2727        }
2728      }
2729
2730      pcCU->setIntraDirSubParts( CHANNEL_TYPE_CHROMA, uiBestMode, uiPartOffset, uiDepthCU+uiInitTrDepth );
2731      pcCU->getTotalDistortion      () += uiBestDist;
2732    }
2733
2734  } while (tuRecurseWithPU.nextSection(tuRecurseCU));
2735
2736  //----- restore context models -----
2737
2738  if( uiInitTrDepth != 0 )
2739  { // set Cbf for all blocks
2740    UInt uiCombCbfU = 0;
2741    UInt uiCombCbfV = 0;
2742    UInt uiPartIdx  = 0;
2743    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += uiQNumParts )
2744    {
2745      uiCombCbfU |= pcCU->getCbf( uiPartIdx, COMPONENT_Cb, 1 );
2746      uiCombCbfV |= pcCU->getCbf( uiPartIdx, COMPONENT_Cr, 1 );
2747    }
2748    for( UInt uiOffs = 0; uiOffs < 4 * uiQNumParts; uiOffs++ )
2749    {
2750      pcCU->getCbf( COMPONENT_Cb )[ uiOffs ] |= uiCombCbfU;
2751      pcCU->getCbf( COMPONENT_Cr )[ uiOffs ] |= uiCombCbfV;
2752    }
2753  }
2754
2755  m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepthCU][CI_CURR_BEST] );
2756}
2757
2758
2759
2760
2761/** Function for encoding and reconstructing luma/chroma samples of a PCM mode CU.
2762 * \param pcCU pointer to current CU
2763 * \param uiAbsPartIdx part index
2764 * \param pOrg pointer to original sample arrays
2765 * \param pPCM pointer to PCM code arrays
2766 * \param pPred pointer to prediction signal arrays
2767 * \param pResi pointer to residual signal arrays
2768 * \param pReco pointer to reconstructed sample arrays
2769 * \param uiStride stride of the original/prediction/residual sample arrays
2770 * \param uiWidth block width
2771 * \param uiHeight block height
2772 * \param compID texture component type
2773 */
2774Void TEncSearch::xEncPCM (TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* pOrg, Pel* pPCM, Pel* pPred, Pel* pResi, Pel* pReco, UInt uiStride, UInt uiWidth, UInt uiHeight, const ComponentID compID )
2775{
2776  const UInt uiReconStride   = pcCU->getPic()->getPicYuvRec()->getStride(compID);
2777  const UInt uiPCMBitDepth   = pcCU->getSlice()->getSPS()->getPCMBitDepth(toChannelType(compID));
2778#if SVC_EXTENSION
2779  const Int  channelBitDepth = pcCU->getSlice()->getBitDepth(toChannelType(compID));
2780#else
2781  const Int  channelBitDepth = pcCU->getSlice()->getSPS()->getBitDepth(toChannelType(compID));
2782#endif
2783  Pel* pRecoPic = pcCU->getPic()->getPicYuvRec()->getAddr(compID, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu()+uiAbsPartIdx);
2784
2785  const Int pcmShiftRight=(channelBitDepth - Int(uiPCMBitDepth));
2786
2787  assert(pcmShiftRight >= 0);
2788
2789  for( UInt uiY = 0; uiY < uiHeight; uiY++ )
2790  {
2791    for( UInt uiX = 0; uiX < uiWidth; uiX++ )
2792    {
2793      // Reset pred and residual
2794      pPred[uiX] = 0;
2795      pResi[uiX] = 0;
2796      // Encode
2797      pPCM[uiX] = (pOrg[uiX]>>pcmShiftRight);
2798      // Reconstruction
2799      pReco   [uiX] = (pPCM[uiX]<<(pcmShiftRight));
2800      pRecoPic[uiX] = pReco[uiX];
2801    }
2802    pPred += uiStride;
2803    pResi += uiStride;
2804    pPCM += uiWidth;
2805    pOrg += uiStride;
2806    pReco += uiStride;
2807    pRecoPic += uiReconStride;
2808  }
2809}
2810
2811
2812//!  Function for PCM mode estimation.
2813Void TEncSearch::IPCMSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv )
2814{
2815  UInt        uiDepth      = pcCU->getDepth(0);
2816  const UInt  uiDistortion = 0;
2817  UInt        uiBits;
2818
2819  Double dCost;
2820
2821  for (UInt ch=0; ch < pcCU->getPic()->getNumberValidComponents(); ch++)
2822  {
2823    const ComponentID compID  = ComponentID(ch);
2824    const UInt width  = pcCU->getWidth(0)  >> pcCU->getPic()->getComponentScaleX(compID);
2825    const UInt height = pcCU->getHeight(0) >> pcCU->getPic()->getComponentScaleY(compID);
2826    const UInt stride = pcPredYuv->getStride(compID);
2827
2828    Pel * pOrig    = pcOrgYuv->getAddr  (compID, 0, width);
2829    Pel * pResi    = pcResiYuv->getAddr(compID, 0, width);
2830    Pel * pPred    = pcPredYuv->getAddr(compID, 0, width);
2831    Pel * pReco    = pcRecoYuv->getAddr(compID, 0, width);
2832    Pel * pPCM     = pcCU->getPCMSample (compID);
2833
2834    xEncPCM ( pcCU, 0, pOrig, pPCM, pPred, pResi, pReco, stride, width, height, compID );
2835
2836  }
2837
2838  m_pcEntropyCoder->resetBits();
2839  xEncIntraHeader ( pcCU, uiDepth, 0, true, false);
2840  uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
2841
2842  dCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
2843
2844  m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2845
2846  pcCU->getTotalBits()       = uiBits;
2847  pcCU->getTotalCost()       = dCost;
2848  pcCU->getTotalDistortion() = uiDistortion;
2849
2850  pcCU->copyToPic(uiDepth);
2851}
2852
2853
2854
2855
2856Void TEncSearch::xGetInterPredictionError( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, Distortion& ruiErr, Bool /*bHadamard*/ )
2857{
2858  motionCompensation( pcCU, &m_tmpYuvPred, REF_PIC_LIST_X, iPartIdx );
2859
2860  UInt uiAbsPartIdx = 0;
2861  Int iWidth = 0;
2862  Int iHeight = 0;
2863  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2864
2865  DistParam cDistParam;
2866
2867  cDistParam.bApplyWeight = false;
2868
2869
2870#if SVC_EXTENSION
2871  m_pcRdCost->setDistParam( cDistParam, pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA),
2872#else
2873  m_pcRdCost->setDistParam( cDistParam, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA),
2874#endif
2875                            pcYuvOrg->getAddr( COMPONENT_Y, uiAbsPartIdx ), pcYuvOrg->getStride(COMPONENT_Y),
2876                            m_tmpYuvPred .getAddr( COMPONENT_Y, uiAbsPartIdx ), m_tmpYuvPred.getStride(COMPONENT_Y),
2877                            iWidth, iHeight, m_pcEncCfg->getUseHADME() && (pcCU->getCUTransquantBypass(iPartIdx) == 0) );
2878
2879  ruiErr = cDistParam.DistFunc( &cDistParam );
2880}
2881
2882//! estimation of best merge coding
2883Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, Distortion& ruiCost, TComMvField* cMvFieldNeighbours, UChar* uhInterDirNeighbours, Int& numValidMergeCand )
2884{
2885  UInt uiAbsPartIdx = 0;
2886  Int iWidth = 0;
2887  Int iHeight = 0;
2888
2889  pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
2890  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
2891
2892  PartSize partSize = pcCU->getPartitionSize( 0 );
2893  if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && partSize != SIZE_2Nx2N && pcCU->getWidth( 0 ) <= 8 )
2894  {
2895    if ( iPUIdx == 0 )
2896    {
2897      pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth ); // temporarily set
2898      pcCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
2899      pcCU->setPartSizeSubParts( partSize, 0, uiDepth ); // restore
2900    }
2901  }
2902  else
2903  {
2904    pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
2905  }
2906
2907  xRestrictBipredMergeCand( pcCU, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
2908
2909  ruiCost = std::numeric_limits<Distortion>::max();
2910  for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
2911  {
2912#if REF_IDX_ME_ZEROMV
2913    Bool bZeroMVILR = pcCU->xCheckZeroMVILRMerge(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]);
2914    if(bZeroMVILR)
2915    {
2916#endif
2917#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
2918    if (!(pcCU->isInterLayerReference(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]) && m_disableILP))
2919    {
2920#endif
2921    Distortion uiCostCand = std::numeric_limits<Distortion>::max();
2922    UInt       uiBitsCand = 0;
2923
2924    PartSize ePartSize = pcCU->getPartitionSize( 0 );
2925
2926    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
2927    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
2928
2929    xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2930    uiBitsCand = uiMergeCand + 1;
2931    if (uiMergeCand == m_pcEncCfg->getMaxNumMergeCand() -1)
2932    {
2933        uiBitsCand--;
2934    }
2935    uiCostCand = uiCostCand + m_pcRdCost->getCost( uiBitsCand );
2936    if ( uiCostCand < ruiCost )
2937    {
2938      ruiCost = uiCostCand;
2939      pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
2940      pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
2941      uiInterDir = uhInterDirNeighbours[uiMergeCand];
2942      uiMergeIndex = uiMergeCand;
2943    }
2944#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
2945    }
2946#endif
2947#if REF_IDX_ME_ZEROMV
2948    }
2949#endif
2950  }
2951}
2952
2953/** convert bi-pred merge candidates to uni-pred
2954 * \param pcCU
2955 * \param puIdx
2956 * \param mvFieldNeighbours
2957 * \param interDirNeighbours
2958 * \param numValidMergeCand
2959 * \returns Void
2960 */
2961Void TEncSearch::xRestrictBipredMergeCand( TComDataCU* pcCU, UInt puIdx, TComMvField* mvFieldNeighbours, UChar* interDirNeighbours, Int numValidMergeCand )
2962{
2963  if ( pcCU->isBipredRestriction(puIdx) )
2964  {
2965    for( UInt mergeCand = 0; mergeCand < numValidMergeCand; ++mergeCand )
2966    {
2967      if ( interDirNeighbours[mergeCand] == 3 )
2968      {
2969        interDirNeighbours[mergeCand] = 1;
2970        mvFieldNeighbours[(mergeCand << 1) + 1].setMvField(TComMv(0,0), -1);
2971      }
2972    }
2973  }
2974}
2975
2976//! search of the best candidate for inter prediction
2977#if SVC_EXTENSION
2978#if AMP_MRG
2979Bool TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseRes, Bool bUseMRG )
2980#else
2981Bool TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv, Bool bUseRes )
2982#endif
2983#else
2984#if AMP_MRG
2985Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseRes, Bool bUseMRG )
2986#else
2987Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv, Bool bUseRes )
2988#endif
2989#endif
2990{
2991  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
2992  {
2993    m_acYuvPred[i].clear();
2994  }
2995  m_cYuvPredTemp.clear();
2996  pcPredYuv->clear();
2997
2998  if ( !bUseRes )
2999  {
3000    pcResiYuv->clear();
3001  }
3002
3003  pcRecoYuv->clear();
3004
3005  TComMv       cMvSrchRngLT;
3006  TComMv       cMvSrchRngRB;
3007
3008  TComMv       cMvZero;
3009  TComMv       TempMv; //kolya
3010
3011  TComMv       cMv[2];
3012  TComMv       cMvBi[2];
3013  TComMv       cMvTemp[2][33];
3014
3015  Int          iNumPart    = pcCU->getNumPartitions();
3016  Int          iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
3017
3018  TComMv       cMvPred[2][33];
3019
3020  TComMv       cMvPredBi[2][33];
3021  Int          aaiMvpIdxBi[2][33];
3022
3023  Int          aaiMvpIdx[2][33];
3024  Int          aaiMvpNum[2][33];
3025
3026  AMVPInfo     aacAMVPInfo[2][33];
3027
3028  Int          iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
3029  Int          iRefIdxBi[2];
3030
3031  UInt         uiPartAddr;
3032  Int          iRoiWidth, iRoiHeight;
3033
3034  UInt         uiMbBits[3] = {1, 1, 0};
3035
3036  UInt         uiLastMode = 0;
3037  Int          iRefStart, iRefEnd;
3038
3039  PartSize     ePartSize = pcCU->getPartitionSize( 0 );
3040
3041  Int          bestBiPRefIdxL1 = 0;
3042  Int          bestBiPMvpL1 = 0;
3043  Distortion   biPDistTemp = std::numeric_limits<Distortion>::max();
3044
3045  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
3046  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
3047  Int numValidMergeCand = 0 ;
3048
3049  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3050  {
3051    Distortion   uiCost[2] = { std::numeric_limits<Distortion>::max(), std::numeric_limits<Distortion>::max() };
3052    Distortion   uiCostBi  =   std::numeric_limits<Distortion>::max();
3053    Distortion   uiCostTemp;
3054
3055    UInt         uiBits[3];
3056    UInt         uiBitsTemp;
3057    Distortion   bestBiPDist = std::numeric_limits<Distortion>::max();
3058
3059    Distortion   uiCostTempL0[MAX_NUM_REF];
3060    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++)
3061    {
3062      uiCostTempL0[iNumRef] = std::numeric_limits<Distortion>::max();
3063    }
3064    UInt         uiBitsTempL0[MAX_NUM_REF];
3065
3066    TComMv       mvValidList1;
3067    Int          refIdxValidList1 = 0;
3068    UInt         bitsValidList1 = MAX_UINT;
3069    Distortion   costValidList1 = std::numeric_limits<Distortion>::max();
3070
3071    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
3072
3073    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3074
3075#if AMP_MRG
3076    Bool bTestNormalMC = true;
3077
3078    if ( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 )
3079    {
3080      bTestNormalMC = false;
3081    }
3082
3083    if (bTestNormalMC)
3084    {
3085#endif
3086
3087#if SVC_EXTENSION
3088      Bool doneUniPred = false;
3089#endif
3090
3091    //  Uni-directional prediction
3092    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
3093    {
3094      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3095
3096      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
3097      {
3098#if SVC_EXTENSION
3099        TComPic* pcPic = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxTemp );
3100       
3101        // motion search only for the ILRP with sample prediction type
3102        if( pcPic->isILR( pcCU->getLayerId() ) && !pcCU->getSlice()->getVPS()->isSamplePredictionType( pcCU->getLayerIdx(), pcPic->getLayerIdx() ) )
3103        {
3104          continue;
3105        }
3106
3107#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3108        if( pcPic->isILR(pcCU->getLayerId()) && m_disableILP )
3109        {
3110          continue;
3111        }
3112#endif
3113#if ENCODER_FAST_MODE       
3114        if( pcPic->isILR(pcCU->getLayerId()) && (ePartSize == SIZE_2Nx2N) ) 
3115        {
3116          continue;
3117        }
3118#endif
3119        doneUniPred = true;
3120#endif
3121
3122        uiBitsTemp = uiMbBits[iRefList];
3123        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3124        {
3125          uiBitsTemp += iRefIdxTemp+1;
3126          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 )
3127          {
3128            uiBitsTemp--;
3129          }
3130        }
3131        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
3132        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
3133        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
3134
3135        if(pcCU->getSlice()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
3136        {
3137#if REF_IDX_ME_ZEROMV
3138          Bool bZeroMVILR = pcCU->xCheckZeroMVILRMvdL1Zero(iRefList, iRefIdxTemp, aaiMvpIdx[iRefList][iRefIdxTemp]);
3139          if(bZeroMVILR)
3140          {
3141#endif
3142          bestBiPDist = biPDistTemp;
3143          bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
3144          bestBiPRefIdxL1 = iRefIdxTemp;
3145#if REF_IDX_ME_ZEROMV
3146          }
3147#endif
3148        }
3149
3150        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3151
3152        if ( m_pcEncCfg->getFastMEForGenBLowDelayEnabled() && iRefList == 1 )    // list 1
3153        {
3154          if ( pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 )
3155          {
3156            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3157            uiCostTemp = uiCostTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3158            /*first subtract the bit-rate part of the cost of the other list*/
3159            uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )] );
3160            /*correct the bit-rate part of the current ref*/
3161            m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
3162            uiBitsTemp += m_pcRdCost->getBits( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
3163            /*calculate the correct cost*/
3164            uiCostTemp += m_pcRdCost->getCost( uiBitsTemp );
3165          }
3166          else
3167          {
3168            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3169          }
3170        }
3171        else
3172        {
3173          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3174        }
3175        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
3176        xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3177
3178        if ( iRefList == 0 )
3179        {
3180          uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3181          uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
3182        }
3183        if ( uiCostTemp < uiCost[iRefList] )
3184        {
3185          uiCost[iRefList] = uiCostTemp;
3186          uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3187
3188          // set motion
3189          cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3190          iRefIdx[iRefList] = iRefIdxTemp;
3191        }
3192
3193        if ( iRefList == 1 && uiCostTemp < costValidList1 && pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
3194        {
3195          costValidList1 = uiCostTemp;
3196          bitsValidList1 = uiBitsTemp;
3197
3198          // set motion
3199          mvValidList1     = cMvTemp[iRefList][iRefIdxTemp];
3200          refIdxValidList1 = iRefIdxTemp;
3201        }
3202      }
3203    }
3204
3205#if SVC_EXTENSION
3206    if( pcCU->getLayerId() && !doneUniPred )
3207    {
3208      // there is no valid reference pictures for inter prediction
3209      return false;
3210    }
3211#endif
3212
3213    //  Bi-directional prediction
3214#if REF_IDX_ME_ZEROMV
3215    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) && !(pcCU->getSlice()->getMvdL1ZeroFlag() && bestBiPDist == MAX_INT) )
3216#else
3217    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
3218#endif
3219    {
3220
3221      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
3222      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
3223
3224      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
3225      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
3226
3227      UInt uiMotBits[2];
3228
3229      if(pcCU->getSlice()->getMvdL1ZeroFlag())
3230      {
3231        xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3232        pcCU->setMVPIdxSubParts( bestBiPMvpL1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3233        aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1;
3234        cMvPredBi[1][bestBiPRefIdxL1]   = pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()->m_acMvCand[bestBiPMvpL1];
3235
3236        cMvBi[1] = cMvPredBi[1][bestBiPRefIdxL1];
3237        iRefIdxBi[1] = bestBiPRefIdxL1;
3238        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3239        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3240        TComYuv* pcYuvPred = &m_acYuvPred[REF_PIC_LIST_1];
3241        motionCompensation( pcCU, pcYuvPred, REF_PIC_LIST_1, iPartIdx );
3242
3243        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3244        uiMotBits[1] = uiMbBits[1];
3245
3246        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3247        {
3248          uiMotBits[1] += bestBiPRefIdxL1+1;
3249          if ( bestBiPRefIdxL1 == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 )
3250          {
3251            uiMotBits[1]--;
3252          }
3253        }
3254
3255        uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS];
3256
3257        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3258
3259        cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1];
3260      }
3261      else
3262      {
3263        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3264        uiMotBits[1] = uiBits[1] - uiMbBits[1];
3265        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3266      }
3267
3268      // 4-times iteration (default)
3269      Int iNumIter = 4;
3270
3271      // fast encoder setting: only one iteration
3272      if ( m_pcEncCfg->getUseFastEnc() || pcCU->getSlice()->getMvdL1ZeroFlag())
3273      {
3274        iNumIter = 1;
3275      }
3276
3277      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3278      {
3279        Int         iRefList    = iIter % 2;
3280
3281        if ( m_pcEncCfg->getUseFastEnc() )
3282        {
3283          if( uiCost[0] <= uiCost[1] )
3284          {
3285            iRefList = 1;
3286          }
3287          else
3288          {
3289            iRefList = 0;
3290          }
3291        }
3292        else if ( iIter == 0 )
3293        {
3294          iRefList = 0;
3295        }
3296        if ( iIter == 0 && !pcCU->getSlice()->getMvdL1ZeroFlag())
3297        {
3298          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllMv( cMv[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3299          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllRefIdx( iRefIdx[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3300          TComYuv*  pcYuvPred = &m_acYuvPred[1-iRefList];
3301          motionCompensation ( pcCU, pcYuvPred, RefPicList(1-iRefList), iPartIdx );
3302        }
3303
3304        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3305
3306        if(pcCU->getSlice()->getMvdL1ZeroFlag())
3307        {
3308          iRefList = 0;
3309          eRefPicList = REF_PIC_LIST_0;
3310        }
3311
3312        Bool bChanged = false;
3313       
3314#if ENCODER_FAST_MODE
3315        Bool     testIter = true;
3316        TComPic* pcPic    = pcCU->getSlice()->getRefPic( RefPicList(1 - iRefList), iRefIdxBi[1 - iRefList] );
3317        if(pcPic->isILR(pcCU->getLayerId()) && (ePartSize == SIZE_2Nx2N))
3318        {
3319          testIter = false;  //the fixed part is ILR, skip this iteration       
3320        }
3321#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3322        if (pcPic->isILR(pcCU->getLayerId()) && m_disableILP)
3323        {
3324          testIter = false;
3325        }
3326#endif
3327        if(testIter)
3328        {
3329#endif
3330        iRefStart = 0;
3331        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3332
3333        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3334        {
3335#if ENCODER_FAST_MODE
3336          Bool testRefIdx = true;
3337          pcPic = pcCU->getSlice()->getRefPic( RefPicList(iRefList) , iRefIdxTemp );
3338
3339          // motion search only for the ILRP with sample prediction type
3340          if( pcPic->isILR( pcCU->getLayerId() ) && !pcCU->getSlice()->getVPS()->isSamplePredictionType( pcCU->getLayerIdx(), pcPic->getLayerIdx() ) )
3341          {
3342            continue;
3343          }
3344
3345          if(pcPic->isILR(pcCU->getLayerId()) && (ePartSize == SIZE_2Nx2N))
3346          {
3347            testRefIdx = false;  //the refined part is ILR, skip this reference pic           
3348          }
3349#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3350          if (pcPic->isILR(pcCU->getLayerId()) && m_disableILP)
3351          {
3352            testRefIdx = false;
3353          }
3354#endif
3355          if(testRefIdx)
3356          {
3357#endif
3358          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3359          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3360          {
3361            uiBitsTemp += iRefIdxTemp+1;
3362            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 )
3363            {
3364              uiBitsTemp--;
3365            }
3366          }
3367          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3368          // call ME
3369          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3370
3371          xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3372          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3373
3374          if ( uiCostTemp < uiCostBi )
3375          {
3376            bChanged = true;
3377
3378            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3379            iRefIdxBi[iRefList] = iRefIdxTemp;
3380
3381            uiCostBi            = uiCostTemp;
3382            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3383            uiBits[2]           = uiBitsTemp;
3384
3385            if(iNumIter!=1)
3386            {
3387              //  Set motion
3388              pcCU->getCUMvField( eRefPicList )->setAllMv( cMvBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3389              pcCU->getCUMvField( eRefPicList )->setAllRefIdx( iRefIdxBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3390
3391              TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3392              motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3393            }
3394          }
3395#if (ENCODER_FAST_MODE)
3396          }
3397#endif
3398        }
3399#if (ENCODER_FAST_MODE)
3400        } // for loop-iRefIdxTemp
3401#endif
3402       
3403        if ( !bChanged )
3404        {
3405          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] )
3406          {
3407            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3408            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3409            if(!pcCU->getSlice()->getMvdL1ZeroFlag())
3410            {
3411              xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3412              xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3413            }
3414          }
3415          break;
3416        }
3417      } // for loop-iter
3418    } // if (B_SLICE)
3419
3420#if AMP_MRG
3421    } //end if bTestNormalMC
3422#endif
3423    //  Clear Motion Field
3424    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3425    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3426    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3427    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3428
3429    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3430    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3431    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3432    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3433
3434    UInt uiMEBits = 0;
3435    // Set Motion Field_
3436    cMv[1] = mvValidList1;
3437    iRefIdx[1] = refIdxValidList1;
3438    uiBits[1] = bitsValidList1;
3439    uiCost[1] = costValidList1;
3440
3441#if AMP_MRG
3442    if (bTestNormalMC)
3443    {
3444#endif
3445    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3446    {
3447      uiLastMode = 2;
3448      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMvBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3449      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdxBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3450      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3451      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3452
3453      TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3454      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3455
3456      TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3457      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3458
3459      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3460
3461      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3462      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3463      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3464      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3465
3466      uiMEBits = uiBits[2];
3467    }
3468    else if ( uiCost[0] <= uiCost[1] )
3469    {
3470      uiLastMode = 0;
3471      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
3472      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
3473
3474      TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3475      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3476
3477      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3478
3479      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3480      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3481
3482      uiMEBits = uiBits[0];
3483    }
3484    else
3485    {
3486      uiLastMode = 1;
3487      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
3488      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
3489
3490      TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3491      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3492
3493      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3494
3495      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3496      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3497
3498      uiMEBits = uiBits[1];
3499    }
3500#if AMP_MRG
3501    } // end if bTestNormalMC
3502#endif
3503
3504    if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3505    {
3506      UInt uiMRGInterDir = 0;
3507      TComMvField cMRGMvField[2];
3508      UInt uiMRGIndex = 0;
3509
3510      UInt uiMEInterDir = 0;
3511      TComMvField cMEMvField[2];
3512
3513      m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
3514
3515#if AMP_MRG
3516      // calculate ME cost
3517      Distortion uiMEError = std::numeric_limits<Distortion>::max();
3518      Distortion uiMECost  = std::numeric_limits<Distortion>::max();
3519
3520      if (bTestNormalMC)
3521      {
3522        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3523        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3524      }
3525#else
3526      // calculate ME cost
3527      Distortion uiMEError = std::numeric_limits<Distortion>::max();
3528      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3529      Distortion uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3530#endif
3531      // save ME result.
3532      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3533      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3534      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3535
3536      // find Merge result
3537      Distortion uiMRGCost = std::numeric_limits<Distortion>::max();
3538
3539      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand);
3540
3541      if ( uiMRGCost < uiMECost )
3542      {
3543        // set Merge result
3544        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3545        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3546        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3547        pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3548        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3549
3550        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3551        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3552
3553        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3554        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3555        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3556        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3557      }
3558      else
3559      {
3560        // set ME result
3561        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3562        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3563        pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3564        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3565      }
3566    }
3567
3568    //  MC
3569    motionCompensation ( pcCU, pcPredYuv, REF_PIC_LIST_X, iPartIdx );
3570
3571  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3572
3573  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
3574
3575#if SVC_EXTENSION
3576  return true;
3577#else
3578  return;
3579#endif
3580}
3581
3582
3583// AMVP
3584Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, Distortion* puiDistBiP )
3585{
3586  AMVPInfo*  pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3587
3588  TComMv     cBestMv;
3589  Int        iBestIdx   = 0;
3590  TComMv     cZeroMv;
3591  TComMv     cMvPred;
3592  Distortion uiBestCost = std::numeric_limits<Distortion>::max();
3593  UInt       uiPartAddr = 0;
3594  Int        iRoiWidth, iRoiHeight;
3595  Int        i;
3596
3597  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3598  // Fill the MV Candidates
3599  if (!bFilled)
3600  {
3601    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
3602  }
3603
3604  // initialize Mvp index & Mvp
3605  iBestIdx = 0;
3606  cBestMv  = pcAMVPInfo->m_acMvCand[0];
3607  if (pcAMVPInfo->iN <= 1)
3608  {
3609    rcMvPred = cBestMv;
3610
3611    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3612    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3613
3614    if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefPicList==REF_PIC_LIST_1)
3615    {
3616      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3617    }
3618    return;
3619  }
3620
3621  if (bFilled)
3622  {
3623    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
3624    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
3625    return;
3626  }
3627
3628  m_cYuvPredTemp.clear();
3629  //-- Check Minimum Cost.
3630  for ( i = 0 ; i < pcAMVPInfo->iN; i++)
3631  {
3632    Distortion uiTmpCost;
3633    uiTmpCost = xGetTemplateCost( pcCU, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3634    if ( uiBestCost > uiTmpCost )
3635    {
3636      uiBestCost = uiTmpCost;
3637      cBestMv   = pcAMVPInfo->m_acMvCand[i];
3638      iBestIdx  = i;
3639      (*puiDistBiP) = uiTmpCost;
3640    }
3641  }
3642
3643  m_cYuvPredTemp.clear();
3644
3645  // Setting Best MVP
3646  rcMvPred = cBestMv;
3647  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3648  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3649  return;
3650}
3651
3652UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
3653{
3654  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
3655
3656  if (iNum == 1)
3657  {
3658    return 0;
3659  }
3660
3661  UInt uiLength = 1;
3662  Int iTemp = iIdx;
3663  if ( iTemp == 0 )
3664  {
3665    return uiLength;
3666  }
3667
3668  Bool bCodeLast = ( iNum-1 > iTemp );
3669
3670  uiLength += (iTemp-1);
3671
3672  if( bCodeLast )
3673  {
3674    uiLength++;
3675  }
3676
3677  return uiLength;
3678}
3679
3680Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
3681{
3682  if ( eCUMode == SIZE_2Nx2N )
3683  {
3684    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3685    uiBlkBit[1] = 3;
3686    uiBlkBit[2] = 5;
3687  }
3688  else if ( (eCUMode == SIZE_2NxN || eCUMode == SIZE_2NxnU) || eCUMode == SIZE_2NxnD )
3689  {
3690    UInt aauiMbBits[2][3][3] = { { {0,0,3}, {0,0,0}, {0,0,0} } , { {5,7,7}, {7,5,7}, {9-3,9-3,9-3} } };
3691    if ( bPSlice )
3692    {
3693      uiBlkBit[0] = 3;
3694      uiBlkBit[1] = 0;
3695      uiBlkBit[2] = 0;
3696    }
3697    else
3698    {
3699      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3700    }
3701  }
3702  else if ( (eCUMode == SIZE_Nx2N || eCUMode == SIZE_nLx2N) || eCUMode == SIZE_nRx2N )
3703  {
3704    UInt aauiMbBits[2][3][3] = { { {0,2,3}, {0,0,0}, {0,0,0} } , { {5,7,7}, {7-2,7-2,9-2}, {9-3,9-3,9-3} } };
3705    if ( bPSlice )
3706    {
3707      uiBlkBit[0] = 3;
3708      uiBlkBit[1] = 0;
3709      uiBlkBit[2] = 0;
3710    }
3711    else
3712    {
3713      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3714    }
3715  }
3716  else if ( eCUMode == SIZE_NxN )
3717  {
3718    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3719    uiBlkBit[1] = 3;
3720    uiBlkBit[2] = 5;
3721  }
3722  else
3723  {
3724    printf("Wrong!\n");
3725    assert( 0 );
3726  }
3727}
3728
3729Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
3730{
3731  pDst->iN = pSrc->iN;
3732  for (Int i = 0; i < pSrc->iN; i++)
3733  {
3734    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
3735  }
3736}
3737
3738Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, Distortion& ruiCost )
3739{
3740  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3741
3742  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
3743
3744  if (pcAMVPInfo->iN < 2)
3745  {
3746    return;
3747  }
3748
3749  m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(0) );
3750  m_pcRdCost->setCostScale ( 0    );
3751
3752  Int iBestMVPIdx = riMVPIdx;
3753
3754  m_pcRdCost->setPredictor( rcMvPred );
3755  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3756  iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
3757  Int iBestMvBits = iOrgMvBits;
3758
3759  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
3760  {
3761    if (iMVPIdx == riMVPIdx)
3762    {
3763      continue;
3764    }
3765
3766    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
3767
3768    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3769    iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
3770
3771    if (iMvBits < iBestMvBits)
3772    {
3773      iBestMvBits = iMvBits;
3774      iBestMVPIdx = iMVPIdx;
3775    }
3776  }
3777
3778  if (iBestMVPIdx != riMVPIdx)  //if changed
3779  {
3780    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
3781
3782    riMVPIdx = iBestMVPIdx;
3783    UInt uiOrgBits = ruiBits;
3784    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
3785    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
3786  }
3787}
3788
3789
3790Distortion TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
3791                                         UInt        uiPartAddr,
3792                                         TComYuv*    pcOrgYuv,
3793                                         TComYuv*    pcTemplateCand,
3794                                         TComMv      cMvCand,
3795                                         Int         iMVPIdx,
3796                                         Int         iMVPNum,
3797                                         RefPicList  eRefPicList,
3798                                         Int         iRefIdx,
3799                                         Int         iSizeX,
3800                                         Int         iSizeY
3801                                         )
3802{
3803  Distortion uiCost = std::numeric_limits<Distortion>::max();
3804
3805  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
3806
3807  pcCU->clipMv( cMvCand );
3808
3809  // prediction pattern
3810#if SVC_EXTENSION
3811  // Check WP for B-slices
3812  if( pcCU->getSlice()->testWeightPred() )
3813#else
3814  if ( pcCU->getSlice()->testWeightPred() && pcCU->getSlice()->getSliceType()==P_SLICE )
3815#endif
3816  {
3817#if SVC_EXTENSION
3818    xPredInterBlk( COMPONENT_Y, pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, true, pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA) );
3819#else
3820    xPredInterBlk( COMPONENT_Y, pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, true, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) );
3821#endif
3822  }
3823  else
3824  {
3825#if SVC_EXTENSION
3826    xPredInterBlk( COMPONENT_Y, pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false, pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA) );
3827#else
3828    xPredInterBlk( COMPONENT_Y, pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) );
3829#endif
3830  }
3831
3832#if SVC_EXTENSION
3833  // Check WP for B-slices
3834  if ( pcCU->getSlice()->testWeightPred() )
3835#else
3836  if ( pcCU->getSlice()->testWeightPred() && pcCU->getSlice()->getSliceType()==P_SLICE )
3837#endif
3838  {
3839    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, iRefIdx );
3840  }
3841
3842  // calc distortion
3843#if SVC_EXTENSION
3844  uiCost = m_pcRdCost->getDistPart( pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA), pcTemplateCand->getAddr(COMPONENT_Y, uiPartAddr), pcTemplateCand->getStride(COMPONENT_Y), pcOrgYuv->getAddr(COMPONENT_Y, uiPartAddr), pcOrgYuv->getStride(COMPONENT_Y), iSizeX, iSizeY, COMPONENT_Y, DF_SAD );
3845#else
3846  uiCost = m_pcRdCost->getDistPart( pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA), pcTemplateCand->getAddr(COMPONENT_Y, uiPartAddr), pcTemplateCand->getStride(COMPONENT_Y), pcOrgYuv->getAddr(COMPONENT_Y, uiPartAddr), pcOrgYuv->getStride(COMPONENT_Y), iSizeX, iSizeY, COMPONENT_Y, DF_SAD );
3847#endif
3848  uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
3849  return uiCost;
3850}
3851
3852
3853
3854
3855Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, Distortion& ruiCost, Bool bBi  )
3856{
3857  UInt          uiPartAddr;
3858  Int           iRoiWidth;
3859  Int           iRoiHeight;
3860
3861  TComMv        cMvHalf, cMvQter;
3862  TComMv        cMvSrchRngLT;
3863  TComMv        cMvSrchRngRB;
3864
3865  TComYuv*      pcYuv = pcYuvOrg;
3866
3867  assert(eRefPicList < MAX_NUM_REF_LIST_ADAPT_SR && iRefIdxPred<Int(MAX_IDX_ADAPT_SR));
3868  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
3869
3870  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
3871  TComPattern   tmpPattern;
3872  TComPattern*  pcPatternKey  = &tmpPattern;
3873
3874  Double        fWeight       = 1.0;
3875
3876  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3877
3878  if ( bBi )
3879  {
3880    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
3881    pcYuv                = &m_cYuvPredTemp;
3882
3883    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
3884
3885    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled() );
3886
3887    fWeight = 0.5;
3888  }
3889
3890  //  Search key pattern initialization
3891  pcPatternKey->initPattern( pcYuv->getAddr  ( COMPONENT_Y, uiPartAddr ),
3892                             iRoiWidth,
3893                             iRoiHeight,
3894                             pcYuv->getStride(COMPONENT_Y),
3895#if SVC_EXTENSION
3896                             pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA) );
3897#else
3898                             pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) );
3899#endif
3900
3901  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getAddr( COMPONENT_Y, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu() + uiPartAddr );
3902  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride(COMPONENT_Y);
3903
3904  TComMv      cMvPred = *pcMvPred;
3905
3906  if ( bBi )
3907  {
3908    xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3909  }
3910  else
3911  {
3912    xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3913  }
3914
3915  m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
3916
3917  m_pcRdCost->setPredictor  ( *pcMvPred );
3918  m_pcRdCost->setCostScale  ( 2 );
3919
3920  setWpScalingDistParam( pcCU, iRefIdxPred, eRefPicList );
3921  //  Do integer search
3922#if REF_IDX_ME_ZEROMV
3923  if( pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->isILR(pcCU->getLayerId()))  //ILR reference pic
3924  {
3925    rcMv.setZero();  //use Mv(0, 0) for integer ME
3926  }
3927  else  //non ILR reference pic
3928  {
3929#endif
3930   
3931  if ( !m_iFastSearch || bBi )
3932  {
3933    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
3934  }
3935  else
3936  {
3937    rcMv = *pcMvPred;
3938    const TComMv *pIntegerMv2Nx2NPred=0;
3939    if (pcCU->getPartitionSize(0) != SIZE_2Nx2N || pcCU->getDepth(0) != 0)
3940    {
3941      pIntegerMv2Nx2NPred = &(m_integerMv2Nx2N[eRefPicList][iRefIdxPred]);
3942    }
3943    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost, pIntegerMv2Nx2NPred );
3944    if (pcCU->getPartitionSize(0) == SIZE_2Nx2N)
3945    {
3946      m_integerMv2Nx2N[eRefPicList][iRefIdxPred] = rcMv;
3947    }
3948  }
3949#if REF_IDX_ME_ZEROMV
3950  }
3951#endif
3952 
3953  m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
3954  m_pcRdCost->setCostScale ( 1 );
3955
3956  const Bool bIsLosslessCoded = pcCU->getCUTransquantBypass(uiPartAddr) != 0;
3957
3958#if REF_IDX_ME_ZEROMV
3959  if( pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->isILR(pcCU->getLayerId()))  //ILR reference pic
3960  {
3961    xPatternSearchFracDIFMv0( pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
3962  }
3963  else    //non ILR reference pic
3964#endif
3965  xPatternSearchFracDIF( bIsLosslessCoded, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
3966
3967  m_pcRdCost->setCostScale( 0 );
3968  rcMv <<= 2;
3969  rcMv += (cMvHalf <<= 1);
3970  rcMv +=  cMvQter;
3971
3972  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
3973
3974  ruiBits      += uiMvBits;
3975  ruiCost       = (Distortion)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
3976}
3977
3978
3979
3980
3981Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
3982{
3983  Int  iMvShift = 2;
3984  TComMv cTmpMvPred = cMvPred;
3985  pcCU->clipMv( cTmpMvPred );
3986
3987  rcMvSrchRngLT.setHor( cTmpMvPred.getHor() - (iSrchRng << iMvShift) );
3988  rcMvSrchRngLT.setVer( cTmpMvPred.getVer() - (iSrchRng << iMvShift) );
3989
3990  rcMvSrchRngRB.setHor( cTmpMvPred.getHor() + (iSrchRng << iMvShift) );
3991  rcMvSrchRngRB.setVer( cTmpMvPred.getVer() + (iSrchRng << iMvShift) );
3992  pcCU->clipMv        ( rcMvSrchRngLT );
3993  pcCU->clipMv        ( rcMvSrchRngRB );
3994
3995  rcMvSrchRngLT >>= iMvShift;
3996  rcMvSrchRngRB >>= iMvShift;
3997}
3998
3999
4000
4001
4002Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, Distortion& ruiSAD )
4003{
4004  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4005  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4006  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4007  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4008
4009  Distortion  uiSad;
4010  Distortion  uiSadBest = std::numeric_limits<Distortion>::max();
4011  Int         iBestX = 0;
4012  Int         iBestY = 0;
4013
4014  Pel*  piRefSrch;
4015
4016  //-- jclee for using the SAD function pointer
4017  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
4018
4019  // fast encoder decision: use subsampled SAD for integer ME
4020  if ( m_pcEncCfg->getUseFastEnc() )
4021  {
4022    if ( m_cDistParam.iRows > 8 )
4023    {
4024      m_cDistParam.iSubShift = 1;
4025    }
4026  }
4027
4028  piRefY += (iSrchRngVerTop * iRefStride);
4029  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4030  {
4031    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4032    {
4033      //  find min. distortion position
4034      piRefSrch = piRefY + x;
4035      m_cDistParam.pCur = piRefSrch;
4036
4037      setDistParamComp(COMPONENT_Y);
4038
4039      m_cDistParam.bitDepth = pcPatternKey->getBitDepthY();
4040      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
4041
4042      // motion cost
4043      uiSad += m_pcRdCost->getCost( x, y );
4044
4045      if ( uiSad < uiSadBest )
4046      {
4047        uiSadBest = uiSad;
4048        iBestX    = x;
4049        iBestY    = y;
4050      }
4051    }
4052    piRefY += iRefStride;
4053  }
4054
4055  rcMv.set( iBestX, iBestY );
4056
4057  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4058  return;
4059}
4060
4061
4062
4063Void TEncSearch::xPatternSearchFast( TComDataCU*   pcCU,
4064                                     TComPattern*  pcPatternKey,
4065                                     Pel*          piRefY,
4066                                     Int           iRefStride,
4067                                     TComMv*       pcMvSrchRngLT,
4068                                     TComMv*       pcMvSrchRngRB,
4069                                     TComMv       &rcMv,
4070                                     Distortion   &ruiSAD,
4071                                     const TComMv* pIntegerMv2Nx2NPred )
4072{
4073  assert (MD_LEFT < NUM_MV_PREDICTORS);
4074  pcCU->getMvPredLeft       ( m_acMvPredictors[MD_LEFT] );
4075  assert (MD_ABOVE < NUM_MV_PREDICTORS);
4076  pcCU->getMvPredAbove      ( m_acMvPredictors[MD_ABOVE] );
4077  assert (MD_ABOVE_RIGHT < NUM_MV_PREDICTORS);
4078  pcCU->getMvPredAboveRight ( m_acMvPredictors[MD_ABOVE_RIGHT] );
4079
4080  switch ( m_iFastSearch )
4081  {
4082    case 1:
4083      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred );
4084      break;
4085
4086    case 2:
4087      xTZSearchSelective( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred );
4088      break;
4089    default:
4090      break;
4091  }
4092}
4093
4094
4095
4096
4097Void TEncSearch::xTZSearch( TComDataCU*  pcCU,
4098                            TComPattern* pcPatternKey,
4099                            Pel*         piRefY,
4100                            Int          iRefStride,
4101                            TComMv*      pcMvSrchRngLT,
4102                            TComMv*      pcMvSrchRngRB,
4103                            TComMv      &rcMv,
4104                            Distortion  &ruiSAD,
4105                            const TComMv* pIntegerMv2Nx2NPred )
4106{
4107  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4108  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4109  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4110  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4111
4112  TZ_SEARCH_CONFIGURATION
4113
4114  UInt uiSearchRange = m_iSearchRange;
4115  pcCU->clipMv( rcMv );
4116  rcMv >>= 2;
4117  // init TZSearchStruct
4118  IntTZSearchStruct cStruct;
4119  cStruct.iYStride    = iRefStride;
4120  cStruct.piRefY      = piRefY;
4121  cStruct.uiBestSad   = MAX_UINT;
4122
4123  // set rcMv (Median predictor) as start point and as best point
4124  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4125
4126  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4127  if ( bTestOtherPredictedMV )
4128  {
4129    for ( UInt index = 0; index < NUM_MV_PREDICTORS; index++ )
4130    {
4131      TComMv cMv = m_acMvPredictors[index];
4132      pcCU->clipMv( cMv );
4133      cMv >>= 2;
4134      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4135    }
4136  }
4137
4138  // test whether zero Mv is better start point than Median predictor
4139  if ( bTestZeroVector )
4140  {
4141    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4142  }
4143
4144  if (pIntegerMv2Nx2NPred != 0)
4145  {
4146    TComMv integerMv2Nx2NPred = *pIntegerMv2Nx2NPred;
4147    integerMv2Nx2NPred <<= 2;
4148    pcCU->clipMv( integerMv2Nx2NPred );
4149    integerMv2Nx2NPred >>= 2;
4150    xTZSearchHelp(pcPatternKey, cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
4151
4152    // reset search range
4153    TComMv cMvSrchRngLT;
4154    TComMv cMvSrchRngRB;
4155    Int iSrchRng = m_iSearchRange;
4156    TComMv currBestMv(cStruct.iBestX, cStruct.iBestY );
4157    currBestMv <<= 2;
4158    xSetSearchRange( pcCU, currBestMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4159    iSrchRngHorLeft   = cMvSrchRngLT.getHor();
4160    iSrchRngHorRight  = cMvSrchRngRB.getHor();
4161    iSrchRngVerTop    = cMvSrchRngLT.getVer();
4162    iSrchRngVerBottom = cMvSrchRngRB.getVer();
4163  }
4164
4165  // start search
4166  Int  iDist = 0;
4167  Int  iStartX = cStruct.iBestX;
4168  Int  iStartY = cStruct.iBestY;
4169
4170  // first search
4171  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4172  {
4173    if ( bFirstSearchDiamond == 1 )
4174    {
4175      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4176    }
4177    else
4178    {
4179      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4180    }
4181
4182    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4183    {
4184      break;
4185    }
4186  }
4187
4188  // test whether zero Mv is a better start point than Median predictor
4189  if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4190  {
4191    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4192    if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4193    {
4194      // test its neighborhood
4195      for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4196      {
4197        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
4198        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4199        {
4200          break;
4201        }
4202      }
4203    }
4204  }
4205
4206  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4207  if ( cStruct.uiBestDistance == 1 )
4208  {
4209    cStruct.uiBestDistance = 0;
4210    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4211  }
4212
4213  // raster search if distance is too big
4214  if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4215  {
4216    cStruct.uiBestDistance = iRaster;
4217    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4218    {
4219      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4220      {
4221        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4222      }
4223    }
4224  }
4225
4226  // raster refinement
4227  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4228  {
4229    while ( cStruct.uiBestDistance > 0 )
4230    {
4231      iStartX = cStruct.iBestX;
4232      iStartY = cStruct.iBestY;
4233      if ( cStruct.uiBestDistance > 1 )
4234      {
4235        iDist = cStruct.uiBestDistance >>= 1;
4236        if ( bRasterRefinementDiamond == 1 )
4237        {
4238          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4239        }
4240        else
4241        {
4242          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4243        }
4244      }
4245
4246      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4247      if ( cStruct.uiBestDistance == 1 )
4248      {
4249        cStruct.uiBestDistance = 0;
4250        if ( cStruct.ucPointNr != 0 )
4251        {
4252          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4253        }
4254      }
4255    }
4256  }
4257
4258  // start refinement
4259  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4260  {
4261    while ( cStruct.uiBestDistance > 0 )
4262    {
4263      iStartX = cStruct.iBestX;
4264      iStartY = cStruct.iBestY;
4265      cStruct.uiBestDistance = 0;
4266      cStruct.ucPointNr = 0;
4267      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4268      {
4269        if ( bStarRefinementDiamond == 1 )
4270        {
4271          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4272        }
4273        else
4274        {
4275          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4276        }
4277        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4278        {
4279          break;
4280        }
4281      }
4282
4283      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4284      if ( cStruct.uiBestDistance == 1 )
4285      {
4286        cStruct.uiBestDistance = 0;
4287        if ( cStruct.ucPointNr != 0 )
4288        {
4289          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4290        }
4291      }
4292    }
4293  }
4294
4295  // write out best match
4296  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4297  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4298}
4299
4300
4301Void TEncSearch::xTZSearchSelective( TComDataCU*   pcCU,
4302                                     TComPattern*  pcPatternKey,
4303                                     Pel*          piRefY,
4304                                     Int           iRefStride,
4305                                     TComMv*       pcMvSrchRngLT,
4306                                     TComMv*       pcMvSrchRngRB,
4307                                     TComMv       &rcMv,
4308                                     Distortion   &ruiSAD,
4309                                     const TComMv* pIntegerMv2Nx2NPred )
4310{
4311  SEL_SEARCH_CONFIGURATION
4312
4313  Int   iSrchRngHorLeft         = pcMvSrchRngLT->getHor();
4314  Int   iSrchRngHorRight        = pcMvSrchRngRB->getHor();
4315  Int   iSrchRngVerTop          = pcMvSrchRngLT->getVer();
4316  Int   iSrchRngVerBottom       = pcMvSrchRngRB->getVer();
4317  Int   iFirstSrchRngHorLeft    = 0;
4318  Int   iFirstSrchRngHorRight   = 0;
4319  Int   iFirstSrchRngVerTop     = 0;
4320  Int   iFirstSrchRngVerBottom  = 0;
4321  Int   iStartX                 = 0;
4322  Int   iStartY                 = 0;
4323  Int   iBestX                  = 0;
4324  Int   iBestY                  = 0;
4325  Int   iDist                   = 0;
4326
4327  pcCU->clipMv( rcMv );
4328  rcMv >>= 2;
4329  // init TZSearchStruct
4330  IntTZSearchStruct cStruct;
4331  cStruct.iYStride    = iRefStride;
4332  cStruct.piRefY      = piRefY;
4333  cStruct.uiBestSad   = MAX_UINT;
4334  cStruct.iBestX = 0;
4335  cStruct.iBestY = 0;
4336
4337
4338  // set rcMv (Median predictor) as start point and as best point
4339  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4340
4341  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4342  if ( bTestOtherPredictedMV )
4343  {
4344    for ( UInt index = 0; index < NUM_MV_PREDICTORS; index++ )
4345    {
4346      TComMv cMv = m_acMvPredictors[index];
4347      pcCU->clipMv( cMv );
4348      cMv >>= 2;
4349      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4350    }
4351  }
4352
4353  // test whether zero Mv is better start point than Median predictor
4354  if ( bTestZeroVector )
4355  {
4356    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4357  }
4358
4359  if ( pIntegerMv2Nx2NPred != 0 )
4360  {
4361    TComMv integerMv2Nx2NPred = *pIntegerMv2Nx2NPred;
4362    integerMv2Nx2NPred <<= 2;
4363    pcCU->clipMv( integerMv2Nx2NPred );
4364    integerMv2Nx2NPred >>= 2;
4365    xTZSearchHelp(pcPatternKey, cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
4366
4367    // reset search range
4368    TComMv cMvSrchRngLT;
4369    TComMv cMvSrchRngRB;
4370    Int iSrchRng = m_iSearchRange;
4371    TComMv currBestMv(cStruct.iBestX, cStruct.iBestY );
4372    currBestMv <<= 2;
4373    xSetSearchRange( pcCU, currBestMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4374    iSrchRngHorLeft   = cMvSrchRngLT.getHor();
4375    iSrchRngHorRight  = cMvSrchRngRB.getHor();
4376    iSrchRngVerTop    = cMvSrchRngLT.getVer();
4377    iSrchRngVerBottom = cMvSrchRngRB.getVer();
4378  }
4379
4380  // Initial search
4381  iBestX = cStruct.iBestX;
4382  iBestY = cStruct.iBestY; 
4383  iFirstSrchRngHorLeft    = ((iBestX - uiSearchRangeInitial) > iSrchRngHorLeft)   ? (iBestX - uiSearchRangeInitial) : iSrchRngHorLeft;
4384  iFirstSrchRngVerTop     = ((iBestY - uiSearchRangeInitial) > iSrchRngVerTop)    ? (iBestY - uiSearchRangeInitial) : iSrchRngVerTop;
4385  iFirstSrchRngHorRight   = ((iBestX + uiSearchRangeInitial) < iSrchRngHorRight)  ? (iBestX + uiSearchRangeInitial) : iSrchRngHorRight; 
4386  iFirstSrchRngVerBottom  = ((iBestY + uiSearchRangeInitial) < iSrchRngVerBottom) ? (iBestY + uiSearchRangeInitial) : iSrchRngVerBottom;   
4387
4388  for ( iStartY = iFirstSrchRngVerTop; iStartY <= iFirstSrchRngVerBottom; iStartY += uiSearchStep )
4389  {
4390    for ( iStartX = iFirstSrchRngHorLeft; iStartX <= iFirstSrchRngHorRight; iStartX += uiSearchStep )
4391    {
4392      xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, 0 );
4393      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 1 );
4394      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 2 );
4395    }
4396  }
4397
4398  Int iMaxMVDistToPred = (abs(cStruct.iBestX - iBestX) > iMVDistThresh || abs(cStruct.iBestY - iBestY) > iMVDistThresh);
4399
4400  //full search with early exit if MV is distant from predictors
4401  if ( bEnableRasterSearch && (iMaxMVDistToPred || bAlwaysRasterSearch) )
4402  {
4403    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += 1 )
4404    {
4405      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += 1 )
4406      {
4407        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, 1 );
4408      }
4409    }
4410  }
4411  //Smaller MV, refine around predictor
4412  else if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4413  {
4414    // start refinement
4415    while ( cStruct.uiBestDistance > 0 )
4416    {
4417      iStartX = cStruct.iBestX;
4418      iStartY = cStruct.iBestY;
4419      cStruct.uiBestDistance = 0;
4420      cStruct.ucPointNr = 0;
4421      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4422      {
4423        if ( bStarRefinementDiamond == 1 )
4424        {
4425          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4426        }
4427        else
4428        {
4429          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4430        }
4431        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4432        {
4433          break;
4434        }
4435      }
4436
4437      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4438      if ( cStruct.uiBestDistance == 1 )
4439      {
4440        cStruct.uiBestDistance = 0;
4441        if ( cStruct.ucPointNr != 0 )
4442        {
4443          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4444        }
4445      }
4446    }
4447  }
4448
4449  // write out best match
4450  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4451  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4452
4453}
4454
4455
4456Void TEncSearch::xPatternSearchFracDIF(
4457                                       Bool         bIsLosslessCoded,
4458                                       TComPattern* pcPatternKey,
4459                                       Pel*         piRefY,
4460                                       Int          iRefStride,
4461                                       TComMv*      pcMvInt,
4462                                       TComMv&      rcMvHalf,
4463                                       TComMv&      rcMvQter,
4464                                       Distortion&  ruiCost
4465                                      )
4466{
4467  //  Reference pattern initialization (integer scale)
4468  TComPattern cPatternRoi;
4469  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4470  cPatternRoi.initPattern(piRefY + iOffset,
4471                          pcPatternKey->getROIYWidth(),
4472                          pcPatternKey->getROIYHeight(),
4473                          iRefStride,
4474                          pcPatternKey->getBitDepthY());
4475
4476  //  Half-pel refinement
4477  xExtDIFUpSamplingH ( &cPatternRoi );
4478
4479  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4480  TComMv baseRefMv(0, 0);
4481  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 2, rcMvHalf, !bIsLosslessCoded );
4482
4483  m_pcRdCost->setCostScale( 0 );
4484
4485  xExtDIFUpSamplingQ ( &cPatternRoi, rcMvHalf );
4486  baseRefMv = rcMvHalf;
4487  baseRefMv <<= 1;
4488
4489  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4490  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4491  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 1, rcMvQter, !bIsLosslessCoded );
4492}
4493
4494
4495//! encode residual and calculate rate-distortion for a CU block
4496Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred,
4497                                            TComYuv* pcYuvResi, TComYuv* pcYuvResiBest, TComYuv* pcYuvRec,
4498                                            Bool bSkipResidual DEBUG_STRING_FN_DECLARE(sDebug) )
4499{
4500  assert ( !pcCU->isIntra(0) );
4501
4502  const UInt cuWidthPixels      = pcCU->getWidth ( 0 );
4503  const UInt cuHeightPixels     = pcCU->getHeight( 0 );
4504  const Int  numValidComponents = pcCU->getPic()->getNumberValidComponents();
4505#if !SVC_EXTENSION
4506  const TComSPS &sps=*(pcCU->getSlice()->getSPS());
4507#endif
4508
4509  // The pcCU is not marked as skip-mode at this point, and its m_pcTrCoeff, m_pcArlCoeff, m_puhCbf, m_puhTrIdx will all be 0.
4510  // due to prior calls to TComDataCU::initEstData(  );
4511
4512  if ( bSkipResidual ) //  No residual coding : SKIP mode
4513  {
4514    pcCU->setSkipFlagSubParts( true, 0, pcCU->getDepth(0) );
4515
4516    pcYuvResi->clear();
4517
4518    pcYuvPred->copyToPartYuv( pcYuvRec, 0 );
4519    Distortion distortion = 0;
4520
4521    for (Int comp=0; comp < numValidComponents; comp++)
4522    {
4523      const ComponentID compID=ComponentID(comp);
4524      const UInt csx=pcYuvOrg->getComponentScaleX(compID);
4525      const UInt csy=pcYuvOrg->getComponentScaleY(compID);
4526#if SVC_EXTENSION
4527      distortion += m_pcRdCost->getDistPart( pcCU->getSlice()->getBitDepth(toChannelType(compID)), pcYuvRec->getAddr(compID), pcYuvRec->getStride(compID), pcYuvOrg->getAddr(compID),
4528#else
4529      distortion += m_pcRdCost->getDistPart( sps.getBitDepth(toChannelType(compID)), pcYuvRec->getAddr(compID), pcYuvRec->getStride(compID), pcYuvOrg->getAddr(compID),
4530#endif
4531                                               pcYuvOrg->getStride(compID), cuWidthPixels >> csx, cuHeightPixels >> csy, compID);
4532    }
4533
4534    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4535    m_pcEntropyCoder->resetBits();
4536
4537    if (pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
4538    {
4539      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
4540    }
4541
4542    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4543    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, true );
4544
4545    UInt uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4546    pcCU->getTotalBits()       = uiBits;
4547    pcCU->getTotalDistortion() = distortion;
4548    pcCU->getTotalCost()       = m_pcRdCost->calcRdCost( uiBits, distortion );
4549
4550    m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4551
4552#if DEBUG_STRING
4553    pcYuvResiBest->clear(); // Clear the residual image, if we didn't code it.
4554    for(UInt i=0; i<MAX_NUM_COMPONENT+1; i++)
4555    {
4556      sDebug+=debug_reorder_data_inter_token[i];
4557    }
4558#endif
4559
4560    return;
4561  }
4562
4563  //  Residual coding.
4564
4565   pcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, cuWidthPixels );
4566
4567  TComTURecurse tuLevel0(pcCU, 0);
4568
4569  Double     nonZeroCost       = 0;
4570  UInt       nonZeroBits       = 0;
4571  Distortion nonZeroDistortion = 0;
4572  Distortion zeroDistortion    = 0;
4573
4574  m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4575
4576  xEstimateInterResidualQT( pcYuvResi,  nonZeroCost, nonZeroBits, nonZeroDistortion, &zeroDistortion, tuLevel0 DEBUG_STRING_PASS_INTO(sDebug) );
4577
4578  // -------------------------------------------------------
4579  // set the coefficients in the pcCU, and also calculates the residual data.
4580  // If a block full of 0's is efficient, then just use 0's.
4581  // The costs at this point do not include header bits.
4582
4583  m_pcEntropyCoder->resetBits();
4584  m_pcEntropyCoder->encodeQtRootCbfZero( );
4585  const UInt   zeroResiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4586  const Double zeroCost     = (pcCU->isLosslessCoded( 0 )) ? (nonZeroCost+1) : (m_pcRdCost->calcRdCost( zeroResiBits, zeroDistortion ));
4587
4588  if ( zeroCost < nonZeroCost || !pcCU->getQtRootCbf(0) )
4589  {
4590    const UInt uiQPartNum = tuLevel0.GetAbsPartIdxNumParts();
4591    ::memset( pcCU->getTransformIdx()     , 0, uiQPartNum * sizeof(UChar) );
4592    for (Int comp=0; comp < numValidComponents; comp++)
4593    {
4594      const ComponentID component = ComponentID(comp);
4595      ::memset( pcCU->getCbf( component ) , 0, uiQPartNum * sizeof(UChar) );
4596      ::memset( pcCU->getCrossComponentPredictionAlpha(component), 0, ( uiQPartNum * sizeof(Char) ) );
4597    }
4598    static const UInt useTS[MAX_NUM_COMPONENT]={0,0,0};
4599    pcCU->setTransformSkipSubParts ( useTS, 0, pcCU->getDepth(0) );
4600#if DEBUG_STRING
4601    sDebug.clear();
4602    for(UInt i=0; i<MAX_NUM_COMPONENT+1; i++)
4603    {
4604      sDebug+=debug_reorder_data_inter_token[i];
4605    }
4606#endif
4607  }
4608  else
4609  {
4610    xSetInterResidualQTData( NULL, false, tuLevel0); // Call first time to set coefficients.
4611  }
4612
4613  // all decisions now made. Fully encode the CU, including the headers:
4614  m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4615
4616  UInt finalBits = 0;
4617  xAddSymbolBitsInter( pcCU, finalBits );
4618  // we've now encoded the pcCU, and so have a valid bit cost
4619
4620  if ( !pcCU->getQtRootCbf( 0 ) )
4621  {
4622    pcYuvResiBest->clear(); // Clear the residual image, if we didn't code it.
4623  }
4624  else
4625  {
4626    xSetInterResidualQTData( pcYuvResiBest, true, tuLevel0 ); // else set the residual image data pcYUVResiBest from the various temp images.
4627  }
4628  m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4629
4630#if SVC_EXTENSION
4631  pcYuvRec->addClip ( pcYuvPred, pcYuvResiBest, 0, cuWidthPixels, pcCU->getSlice()->getBitDepths() );
4632#else
4633  pcYuvRec->addClip ( pcYuvPred, pcYuvResiBest, 0, cuWidthPixels, sps.getBitDepths() );
4634#endif
4635
4636  // update with clipped distortion and cost (previously unclipped reconstruction values were used)
4637
4638  Distortion finalDistortion = 0;
4639  for(Int comp=0; comp<numValidComponents; comp++)
4640  {
4641    const ComponentID compID=ComponentID(comp);
4642#if SVC_EXTENSION
4643    finalDistortion += m_pcRdCost->getDistPart( pcCU->getSlice()->getBitDepth(toChannelType(compID)), pcYuvRec->getAddr(compID ), pcYuvRec->getStride(compID ), pcYuvOrg->getAddr(compID ), pcYuvOrg->getStride(compID), cuWidthPixels >> pcYuvOrg->getComponentScaleX(compID), cuHeightPixels >> pcYuvOrg->getComponentScaleY(compID), compID);
4644#else
4645    finalDistortion += m_pcRdCost->getDistPart( sps.getBitDepth(toChannelType(compID)), pcYuvRec->getAddr(compID ), pcYuvRec->getStride(compID ), pcYuvOrg->getAddr(compID ), pcYuvOrg->getStride(compID), cuWidthPixels >> pcYuvOrg->getComponentScaleX(compID), cuHeightPixels >> pcYuvOrg->getComponentScaleY(compID), compID);
4646#endif
4647  }
4648
4649  pcCU->getTotalBits()       = finalBits;
4650  pcCU->getTotalDistortion() = finalDistortion;
4651  pcCU->getTotalCost()       = m_pcRdCost->calcRdCost( finalBits, finalDistortion );
4652}
4653
4654
4655
4656Void TEncSearch::xEstimateInterResidualQT( TComYuv    *pcResi,
4657                                           Double     &rdCost,
4658                                           UInt       &ruiBits,
4659                                           Distortion &ruiDist,
4660                                           Distortion *puiZeroDist,
4661                                           TComTU     &rTu
4662                                           DEBUG_STRING_FN_DECLARE(sDebug) )
4663{
4664  TComDataCU *pcCU        = rTu.getCU();
4665  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
4666  const UInt uiDepth      = rTu.GetTransformDepthTotal();
4667  const UInt uiTrMode     = rTu.GetTransformDepthRel();
4668  const UInt subTUDepth   = uiTrMode + 1;
4669  const UInt numValidComp = pcCU->getPic()->getNumberValidComponents();
4670  DEBUG_STRING_NEW(sSingleStringComp[MAX_NUM_COMPONENT])
4671
4672  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
4673  const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
4674
4675  UInt SplitFlag = ((pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && pcCU->isInter(uiAbsPartIdx) && ( pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N ));
4676#if DEBUG_STRING
4677  const Int debugPredModeMask = DebugStringGetPredModeMask(pcCU->getPredictionMode(uiAbsPartIdx));
4678#endif
4679
4680  Bool bCheckFull;
4681
4682  if ( SplitFlag && uiDepth == pcCU->getDepth(uiAbsPartIdx) && ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ) )
4683  {
4684    bCheckFull = false;
4685  }
4686  else
4687  {
4688    bCheckFull =  ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
4689  }
4690
4691  const Bool bCheckSplit  = ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
4692
4693  assert( bCheckFull || bCheckSplit );
4694
4695  // code full block
4696  Double     dSingleCost = MAX_DOUBLE;
4697  UInt       uiSingleBits                                                                                                        = 0;
4698  Distortion uiSingleDistComp            [MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{0,0},{0,0},{0,0}};
4699  Distortion uiSingleDist                                                                                                        = 0;
4700  TCoeff     uiAbsSum                    [MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{0,0},{0,0},{0,0}};
4701  UInt       uiBestTransformMode         [MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{0,0},{0,0},{0,0}};
4702  //  Stores the best explicit RDPCM mode for a TU encoded without split
4703  UInt       bestExplicitRdpcmModeUnSplit[MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{3,3}, {3,3}, {3,3}};
4704  Char       bestCrossCPredictionAlpha   [MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{0,0},{0,0},{0,0}};
4705
4706  m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4707
4708  if( bCheckFull )
4709  {
4710    Double minCost[MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/];
4711    Bool checkTransformSkip[MAX_NUM_COMPONENT];
4712    pcCU->setTrIdxSubParts( uiTrMode, uiAbsPartIdx, uiDepth );
4713
4714    m_pcEntropyCoder->resetBits();
4715
4716    memset( m_pTempPel, 0, sizeof( Pel ) * rTu.getRect(COMPONENT_Y).width * rTu.getRect(COMPONENT_Y).height ); // not necessary needed for inside of recursion (only at the beginning)
4717
4718    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
4719    TCoeff *pcCoeffCurr[MAX_NUM_COMPONENT];
4720#if ADAPTIVE_QP_SELECTION
4721    TCoeff *pcArlCoeffCurr[MAX_NUM_COMPONENT];
4722#endif
4723
4724    for(UInt i=0; i<numValidComp; i++)
4725    {
4726      minCost[i][0] = MAX_DOUBLE;
4727      minCost[i][1] = MAX_DOUBLE;
4728    }
4729
4730    Pel crossCPredictedResidualBuffer[ MAX_TU_SIZE * MAX_TU_SIZE ];
4731
4732    for(UInt i=0; i<numValidComp; i++)
4733    {
4734      checkTransformSkip[i]=false;
4735      const ComponentID compID=ComponentID(i);
4736#if SVC_EXTENSION
4737      const Int channelBitDepth=pcCU->getSlice()->getBitDepth(toChannelType(compID));
4738#else
4739      const Int channelBitDepth=pcCU->getSlice()->getSPS()->getBitDepth(toChannelType(compID));
4740#endif
4741      pcCoeffCurr[compID]    = m_ppcQTTempCoeff[compID][uiQTTempAccessLayer] + rTu.getCoefficientOffset(compID);
4742#if ADAPTIVE_QP_SELECTION
4743      pcArlCoeffCurr[compID] = m_ppcQTTempArlCoeff[compID ][uiQTTempAccessLayer] +  rTu.getCoefficientOffset(compID);
4744#endif
4745
4746      if(rTu.ProcessComponentSection(compID))
4747      {
4748        const QpParam cQP(*pcCU, compID);
4749
4750        checkTransformSkip[compID] = pcCU->getSlice()->getPPS()->getUseTransformSkip() &&
4751                                     TUCompRectHasAssociatedTransformSkipFlag(rTu.getRect(compID), pcCU->getSlice()->getPPS()->getPpsRangeExtension().getLog2MaxTransformSkipBlockSize()) &&
4752                                     (!pcCU->isLosslessCoded(0));
4753
4754        const Bool splitIntoSubTUs = rTu.getRect(compID).width != rTu.getRect(compID).height;
4755
4756        TComTURecurse TUIterator(rTu, false, (splitIntoSubTUs ? TComTU::VERTICAL_SPLIT : TComTU::DONT_SPLIT), true, compID);
4757
4758        const UInt partIdxesPerSubTU = TUIterator.GetAbsPartIdxNumParts(compID);
4759
4760        do
4761        {
4762          const UInt           subTUIndex             = TUIterator.GetSectionNumber();
4763          const UInt           subTUAbsPartIdx        = TUIterator.GetAbsPartIdxTU(compID);
4764          const TComRectangle &tuCompRect             = TUIterator.getRect(compID);
4765          const UInt           subTUBufferOffset      = tuCompRect.width * tuCompRect.height * subTUIndex;
4766
4767                TCoeff        *currentCoefficients    = pcCoeffCurr[compID] + subTUBufferOffset;
4768#if ADAPTIVE_QP_SELECTION
4769                TCoeff        *currentARLCoefficients = pcArlCoeffCurr[compID] + subTUBufferOffset;
4770#endif
4771          const Bool isCrossCPredictionAvailable      =    isChroma(compID)
4772                                                         && pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag()
4773                                                         && (pcCU->getCbf(subTUAbsPartIdx, COMPONENT_Y, uiTrMode) != 0);
4774
4775          Char preCalcAlpha = 0;
4776          const Pel *pLumaResi = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( COMPONENT_Y, rTu.getRect( COMPONENT_Y ).x0, rTu.getRect( COMPONENT_Y ).y0 );
4777
4778          if (isCrossCPredictionAvailable)
4779          {
4780            const Bool bUseReconstructedResidualForEstimate = m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate();
4781            const Pel  *const lumaResidualForEstimate       = bUseReconstructedResidualForEstimate ? pLumaResi                                                     : pcResi->getAddrPix(COMPONENT_Y, tuCompRect.x0, tuCompRect.y0);
4782            const UInt        lumaResidualStrideForEstimate = bUseReconstructedResidualForEstimate ? m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y) : pcResi->getStride(COMPONENT_Y);
4783
4784            preCalcAlpha = xCalcCrossComponentPredictionAlpha(TUIterator,
4785                                                              compID,
4786                                                              lumaResidualForEstimate,
4787                                                              pcResi->getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4788                                                              tuCompRect.width,
4789                                                              tuCompRect.height,
4790                                                              lumaResidualStrideForEstimate,
4791                                                              pcResi->getStride(compID));
4792          }
4793
4794          const Int transformSkipModesToTest    = checkTransformSkip[compID] ? 2 : 1;
4795          const Int crossCPredictionModesToTest = (preCalcAlpha != 0)        ? 2 : 1; // preCalcAlpha cannot be anything other than 0 if isCrossCPredictionAvailable is false
4796
4797          const Bool isOneMode                  = (crossCPredictionModesToTest == 1) && (transformSkipModesToTest == 1);
4798
4799          for (Int transformSkipModeId = 0; transformSkipModeId < transformSkipModesToTest; transformSkipModeId++)
4800          {
4801            pcCU->setTransformSkipPartRange(transformSkipModeId, compID, subTUAbsPartIdx, partIdxesPerSubTU);
4802
4803            for (Int crossCPredictionModeId = 0; crossCPredictionModeId < crossCPredictionModesToTest; crossCPredictionModeId++)
4804            {
4805              const Bool isFirstMode          = (transformSkipModeId == 0) && (crossCPredictionModeId == 0);
4806              const Bool bUseCrossCPrediction = crossCPredictionModeId != 0;
4807
4808              m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4809              m_pcEntropyCoder->resetBits();
4810
4811              pcCU->setTransformSkipPartRange(transformSkipModeId, compID, subTUAbsPartIdx, partIdxesPerSubTU);
4812              pcCU->setCrossComponentPredictionAlphaPartRange((bUseCrossCPrediction ? preCalcAlpha : 0), compID, subTUAbsPartIdx, partIdxesPerSubTU );
4813
4814              if ((compID != COMPONENT_Cr) && ((transformSkipModeId == 1) ? m_pcEncCfg->getUseRDOQTS() : m_pcEncCfg->getUseRDOQ()))
4815              {
4816                m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, tuCompRect.width, tuCompRect.height, toChannelType(compID));
4817              }
4818
4819#if RDOQ_CHROMA_LAMBDA
4820              m_pcTrQuant->selectLambda(compID);
4821#endif
4822
4823              Pel *pcResiCurrComp = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0);
4824              UInt resiStride     = m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID);
4825
4826              TCoeff bestCoeffComp   [MAX_TU_SIZE*MAX_TU_SIZE];
4827              Pel    bestResiComp    [MAX_TU_SIZE*MAX_TU_SIZE];
4828
4829#if ADAPTIVE_QP_SELECTION
4830              TCoeff bestArlCoeffComp[MAX_TU_SIZE*MAX_TU_SIZE];
4831#endif
4832              TCoeff     currAbsSum   = 0;
4833              UInt       currCompBits = 0;
4834              Distortion currCompDist = 0;
4835              Double     currCompCost = 0;
4836              UInt       nonCoeffBits = 0;
4837              Distortion nonCoeffDist = 0;
4838              Double     nonCoeffCost = 0;
4839
4840              if(!isOneMode && !isFirstMode)
4841              {
4842                memcpy(bestCoeffComp,    currentCoefficients,    (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
4843#if ADAPTIVE_QP_SELECTION
4844                memcpy(bestArlCoeffComp, currentARLCoefficients, (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
4845#endif
4846                for(Int y = 0; y < tuCompRect.height; y++)
4847                {
4848                  memcpy(&bestResiComp[y * tuCompRect.width], (pcResiCurrComp + (y * resiStride)), (sizeof(Pel) * tuCompRect.width));
4849                }
4850              }
4851
4852              if (bUseCrossCPrediction)
4853              {
4854                TComTrQuant::crossComponentPrediction(TUIterator,
4855                                                      compID,
4856                                                      pLumaResi,
4857                                                      pcResi->getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4858                                                      crossCPredictedResidualBuffer,
4859                                                      tuCompRect.width,
4860                                                      tuCompRect.height,
4861                                                      m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
4862                                                      pcResi->getStride(compID),
4863                                                      tuCompRect.width,
4864                                                      false);
4865
4866                m_pcTrQuant->transformNxN(TUIterator, compID, crossCPredictedResidualBuffer, tuCompRect.width, currentCoefficients,
4867#if ADAPTIVE_QP_SELECTION
4868                                          currentARLCoefficients,
4869#endif
4870                                          currAbsSum, cQP);
4871              }
4872              else
4873              {
4874                m_pcTrQuant->transformNxN(TUIterator, compID, pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ), pcResi->getStride(compID), currentCoefficients,
4875#if ADAPTIVE_QP_SELECTION
4876                                          currentARLCoefficients,
4877#endif
4878                                          currAbsSum, cQP);
4879              }
4880
4881              if(isFirstMode || (currAbsSum == 0))
4882              {
4883                if (bUseCrossCPrediction)
4884                {
4885                  TComTrQuant::crossComponentPrediction(TUIterator,
4886                                                        compID,
4887                                                        pLumaResi,
4888                                                        m_pTempPel,
4889                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4890                                                        tuCompRect.width,
4891                                                        tuCompRect.height,
4892                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
4893                                                        tuCompRect.width,
4894                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID),
4895                                                        true);
4896
4897                  nonCoeffDist = m_pcRdCost->getDistPart( channelBitDepth, m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4898                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride( compID ), pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4899                                                          pcResi->getStride(compID), tuCompRect.width, tuCompRect.height, compID); // initialized with zero residual destortion
4900                }
4901                else
4902                {
4903                  nonCoeffDist = m_pcRdCost->getDistPart( channelBitDepth, m_pTempPel, tuCompRect.width, pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4904                                                          pcResi->getStride(compID), tuCompRect.width, tuCompRect.height, compID); // initialized with zero residual destortion
4905                }
4906
4907                m_pcEntropyCoder->encodeQtCbfZero( TUIterator, toChannelType(compID) );
4908
4909                if ( isCrossCPredictionAvailable )
4910                {
4911                  m_pcEntropyCoder->encodeCrossComponentPrediction( TUIterator, compID );
4912                }
4913
4914                nonCoeffBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4915                nonCoeffCost = m_pcRdCost->calcRdCost( nonCoeffBits, nonCoeffDist );
4916              }
4917
4918              if((puiZeroDist != NULL) && isFirstMode)
4919              {
4920                *puiZeroDist += nonCoeffDist; // initialized with zero residual destortion
4921              }
4922
4923              DEBUG_STRING_NEW(sSingleStringTest)
4924
4925              if( currAbsSum > 0 ) //if non-zero coefficients are present, a residual needs to be derived for further prediction
4926              {
4927                if (isFirstMode)
4928                {
4929                  m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4930                  m_pcEntropyCoder->resetBits();
4931                }
4932
4933                m_pcEntropyCoder->encodeQtCbf( TUIterator, compID, true );
4934
4935                if (isCrossCPredictionAvailable)
4936                {
4937                  m_pcEntropyCoder->encodeCrossComponentPrediction( TUIterator, compID );
4938                }
4939
4940                m_pcEntropyCoder->encodeCoeffNxN( TUIterator, currentCoefficients, compID );
4941                currCompBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4942
4943                pcResiCurrComp = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 );
4944
4945                m_pcTrQuant->invTransformNxN( TUIterator, compID, pcResiCurrComp, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID), currentCoefficients, cQP DEBUG_STRING_PASS_INTO_OPTIONAL(&sSingleStringTest, (DebugOptionList::DebugString_InvTran.getInt()&debugPredModeMask)) );
4946
4947                if (bUseCrossCPrediction)
4948                {
4949                  TComTrQuant::crossComponentPrediction(TUIterator,
4950                                                        compID,
4951                                                        pLumaResi,
4952                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4953                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4954                                                        tuCompRect.width,
4955                                                        tuCompRect.height,
4956                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
4957                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID     ),
4958                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID     ),
4959                                                        true);
4960                }
4961
4962                currCompDist = m_pcRdCost->getDistPart( channelBitDepth, m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4963                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID),
4964                                                        pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4965                                                        pcResi->getStride(compID),
4966                                                        tuCompRect.width, tuCompRect.height, compID);
4967
4968                currCompCost = m_pcRdCost->calcRdCost(currCompBits, currCompDist);
4969                 
4970                if (pcCU->isLosslessCoded(0))
4971                {
4972                  nonCoeffCost = MAX_DOUBLE;
4973                }
4974              }
4975              else if ((transformSkipModeId == 1) && !bUseCrossCPrediction)
4976              {
4977                currCompCost = MAX_DOUBLE;
4978              }
4979              else
4980              {
4981                currCompBits = nonCoeffBits;
4982                currCompDist = nonCoeffDist;
4983                currCompCost = nonCoeffCost;
4984              }
4985
4986              // evaluate
4987              if ((currCompCost < minCost[compID][subTUIndex]) || ((transformSkipModeId == 1) && (currCompCost == minCost[compID][subTUIndex])))
4988              {
4989                bestExplicitRdpcmModeUnSplit[compID][subTUIndex] = pcCU->getExplicitRdpcmMode(compID, subTUAbsPartIdx);
4990
4991                if(isFirstMode) //check for forced null
4992                {
4993                  if((nonCoeffCost < currCompCost) || (currAbsSum == 0))
4994                  {
4995                    memset(currentCoefficients, 0, (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
4996
4997                    currAbsSum   = 0;
4998                    currCompBits = nonCoeffBits;
4999                    currCompDist = nonCoeffDist;
5000                    currCompCost = nonCoeffCost;
5001                  }
5002                }
5003
5004#if DEBUG_STRING
5005                if (currAbsSum > 0)
5006                {
5007                  DEBUG_STRING_SWAP(sSingleStringComp[compID], sSingleStringTest)
5008                }
5009                else
5010                {
5011                  sSingleStringComp[compID].clear();
5012                }
5013#endif
5014
5015                uiAbsSum                 [compID][subTUIndex] = currAbsSum;
5016                uiSingleDistComp         [compID][subTUIndex] = currCompDist;
5017                minCost                  [compID][subTUIndex] = currCompCost;
5018                uiBestTransformMode      [compID][subTUIndex] = transformSkipModeId;
5019                bestCrossCPredictionAlpha[compID][subTUIndex] = (crossCPredictionModeId == 1) ? pcCU->getCrossComponentPredictionAlpha(subTUAbsPartIdx, compID) : 0;
5020
5021                if (uiAbsSum[compID][subTUIndex] == 0)
5022                {
5023                  if (bUseCrossCPrediction)
5024                  {
5025                    TComTrQuant::crossComponentPrediction(TUIterator,
5026                                                          compID,
5027                                                          pLumaResi,
5028                                                          m_pTempPel,
5029                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
5030                                                          tuCompRect.width,
5031                                                          tuCompRect.height,
5032                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
5033                                                          tuCompRect.width,
5034                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID),
5035                                                          true);
5036                  }
5037                  else
5038                  {
5039                    pcResiCurrComp = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0);
5040                    const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID);
5041                    for(UInt uiY = 0; uiY < tuCompRect.height; uiY++)
5042                    {
5043                      memset(pcResiCurrComp, 0, (sizeof(Pel) * tuCompRect.width));
5044                      pcResiCurrComp += uiStride;
5045                    }
5046                  }
5047                }
5048              }
5049              else
5050              {
5051                // reset
5052                memcpy(currentCoefficients,    bestCoeffComp,    (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
5053#if ADAPTIVE_QP_SELECTION
5054                memcpy(currentARLCoefficients, bestArlCoeffComp, (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
5055#endif
5056                for (Int y = 0; y < tuCompRect.height; y++)
5057                {
5058                  memcpy((pcResiCurrComp + (y * resiStride)), &bestResiComp[y * tuCompRect.width], (sizeof(Pel) * tuCompRect.width));
5059                }
5060              }
5061            }
5062          }
5063
5064          pcCU->setExplicitRdpcmModePartRange            (   bestExplicitRdpcmModeUnSplit[compID][subTUIndex],                            compID, subTUAbsPartIdx, partIdxesPerSubTU);
5065          pcCU->setTransformSkipPartRange                (   uiBestTransformMode         [compID][subTUIndex],                            compID, subTUAbsPartIdx, partIdxesPerSubTU );
5066          pcCU->setCbfPartRange                          ((((uiAbsSum                    [compID][subTUIndex] > 0) ? 1 : 0) << uiTrMode), compID, subTUAbsPartIdx, partIdxesPerSubTU );
5067          pcCU->setCrossComponentPredictionAlphaPartRange(   bestCrossCPredictionAlpha   [compID][subTUIndex],                            compID, subTUAbsPartIdx, partIdxesPerSubTU );
5068        } while (TUIterator.nextSection(rTu)); //end of sub-TU loop
5069      } // processing section
5070    } // component loop
5071
5072    for(UInt ch = 0; ch < numValidComp; ch++)
5073    {
5074      const ComponentID compID = ComponentID(ch);
5075      if (rTu.ProcessComponentSection(compID) && (rTu.getRect(compID).width != rTu.getRect(compID).height))
5076      {
5077        offsetSubTUCBFs(rTu, compID); //the CBFs up to now have been defined for two sub-TUs - shift them down a level and replace with the parent level CBF
5078      }
5079    }
5080
5081    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5082    m_pcEntropyCoder->resetBits();
5083
5084    if( uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5085    {
5086      m_pcEntropyCoder->encodeTransformSubdivFlag( 0, 5 - uiLog2TrSize );
5087    }
5088
5089    for(UInt ch = 0; ch < numValidComp; ch++)
5090    {
5091      const UInt chOrderChange = ((ch + 1) == numValidComp) ? 0 : (ch + 1);
5092      const ComponentID compID=ComponentID(chOrderChange);
5093      if( rTu.ProcessComponentSection(compID) )
5094      {
5095        m_pcEntropyCoder->encodeQtCbf( rTu, compID, true );
5096      }
5097    }
5098
5099    for(UInt ch = 0; ch < numValidComp; ch++)
5100    {
5101      const ComponentID compID=ComponentID(ch);
5102      if (rTu.ProcessComponentSection(compID))
5103      {
5104        if(isChroma(compID) && (uiAbsSum[COMPONENT_Y][0] != 0))
5105        {
5106          m_pcEntropyCoder->encodeCrossComponentPrediction( rTu, compID );
5107        }
5108
5109        m_pcEntropyCoder->encodeCoeffNxN( rTu, pcCoeffCurr[compID], compID );
5110        for (UInt subTUIndex = 0; subTUIndex < 2; subTUIndex++)
5111        {
5112          uiSingleDist += uiSingleDistComp[compID][subTUIndex];
5113        }
5114      }
5115    }
5116
5117    uiSingleBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5118
5119    dSingleCost = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDist );
5120  } // check full
5121
5122  // code sub-blocks
5123  if( bCheckSplit )
5124  {
5125    if( bCheckFull )
5126    {
5127      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5128      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5129    }
5130    Distortion uiSubdivDist = 0;
5131    UInt       uiSubdivBits = 0;
5132    Double     dSubdivCost = 0.0;
5133
5134    //save the non-split CBFs in case we need to restore them later
5135
5136    UInt bestCBF     [MAX_NUM_COMPONENT];
5137    UInt bestsubTUCBF[MAX_NUM_COMPONENT][2];
5138    for(UInt ch = 0; ch < numValidComp; ch++)
5139    {
5140      const ComponentID compID=ComponentID(ch);
5141
5142      if (rTu.ProcessComponentSection(compID))
5143      {
5144        bestCBF[compID] = pcCU->getCbf(uiAbsPartIdx, compID, uiTrMode);
5145
5146        const TComRectangle &tuCompRect = rTu.getRect(compID);
5147        if (tuCompRect.width != tuCompRect.height)
5148        {
5149          const UInt partIdxesPerSubTU = rTu.GetAbsPartIdxNumParts(compID) >> 1;
5150
5151          for (UInt subTU = 0; subTU < 2; subTU++)
5152          {
5153            bestsubTUCBF[compID][subTU] = pcCU->getCbf ((uiAbsPartIdx + (subTU * partIdxesPerSubTU)), compID, subTUDepth);
5154          }
5155        }
5156      }
5157    }
5158
5159
5160    TComTURecurse tuRecurseChild(rTu, false);
5161    const UInt uiQPartNumSubdiv = tuRecurseChild.GetAbsPartIdxNumParts();
5162
5163    DEBUG_STRING_NEW(sSplitString[MAX_NUM_COMPONENT])
5164
5165    do
5166    {
5167      DEBUG_STRING_NEW(childString)
5168      xEstimateInterResidualQT( pcResi, dSubdivCost, uiSubdivBits, uiSubdivDist, bCheckFull ? NULL : puiZeroDist,  tuRecurseChild DEBUG_STRING_PASS_INTO(childString));
5169#if DEBUG_STRING
5170      // split the string by component and append to the relevant output (because decoder decodes in channel order, whereas this search searches by TU-order)
5171      std::size_t lastPos=0;
5172      const std::size_t endStrng=childString.find(debug_reorder_data_inter_token[MAX_NUM_COMPONENT], lastPos);
5173      for(UInt ch = 0; ch < numValidComp; ch++)
5174      {
5175        if (lastPos!=std::string::npos && childString.find(debug_reorder_data_inter_token[ch], lastPos)==lastPos)
5176        {
5177          lastPos+=strlen(debug_reorder_data_inter_token[ch]); // skip leading string
5178        }
5179        std::size_t pos=childString.find(debug_reorder_data_inter_token[ch+1], lastPos);
5180        if (pos!=std::string::npos && pos>endStrng)
5181        {
5182          lastPos=endStrng;
5183        }
5184        sSplitString[ch]+=childString.substr(lastPos, (pos==std::string::npos)? std::string::npos : (pos-lastPos) );
5185        lastPos=pos;
5186      }
5187#endif
5188    } while ( tuRecurseChild.nextSection(rTu) ) ;
5189
5190    UInt uiCbfAny=0;
5191    for(UInt ch = 0; ch < numValidComp; ch++)
5192    {
5193      UInt uiYUVCbf = 0;
5194      for( UInt ui = 0; ui < 4; ++ui )
5195      {
5196        uiYUVCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, ComponentID(ch),  uiTrMode + 1 );
5197      }
5198      UChar *pBase=pcCU->getCbf( ComponentID(ch) );
5199      const UInt flags=uiYUVCbf << uiTrMode;
5200      for( UInt ui = 0; ui < 4 * uiQPartNumSubdiv; ++ui )
5201      {
5202        pBase[uiAbsPartIdx + ui] |= flags;
5203      }
5204      uiCbfAny|=uiYUVCbf;
5205    }
5206
5207    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5208    m_pcEntropyCoder->resetBits();
5209
5210    // when compID isn't a channel, code Cbfs:
5211    xEncodeInterResidualQT( MAX_NUM_COMPONENT, rTu );
5212    for(UInt ch = 0; ch < numValidComp; ch++)
5213    {
5214      xEncodeInterResidualQT( ComponentID(ch), rTu );
5215    }
5216
5217    uiSubdivBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5218    dSubdivCost  = m_pcRdCost->calcRdCost( uiSubdivBits, uiSubdivDist );
5219
5220    if (!bCheckFull || (uiCbfAny && (dSubdivCost < dSingleCost)))
5221    {
5222      rdCost += dSubdivCost;
5223      ruiBits += uiSubdivBits;
5224      ruiDist += uiSubdivDist;
5225#if DEBUG_STRING
5226      for(UInt ch = 0; ch < numValidComp; ch++)
5227      {
5228        DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[ch])
5229        DEBUG_STRING_APPEND(sDebug, sSplitString[ch])
5230      }
5231#endif
5232    }
5233    else
5234    {
5235      rdCost  += dSingleCost;
5236      ruiBits += uiSingleBits;
5237      ruiDist += uiSingleDist;
5238
5239      //restore state to unsplit
5240
5241      pcCU->setTrIdxSubParts( uiTrMode, uiAbsPartIdx, uiDepth );
5242
5243      for(UInt ch = 0; ch < numValidComp; ch++)
5244      {
5245        const ComponentID compID=ComponentID(ch);
5246
5247        DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[ch])
5248        if (rTu.ProcessComponentSection(compID))
5249        {
5250          DEBUG_STRING_APPEND(sDebug, sSingleStringComp[compID])
5251
5252          const Bool splitIntoSubTUs   = rTu.getRect(compID).width != rTu.getRect(compID).height;
5253          const UInt numberOfSections  = splitIntoSubTUs ? 2 : 1;
5254          const UInt partIdxesPerSubTU = rTu.GetAbsPartIdxNumParts(compID) >> (splitIntoSubTUs ? 1 : 0);
5255
5256          for (UInt subTUIndex = 0; subTUIndex < numberOfSections; subTUIndex++)
5257          {
5258            const UInt  uisubTUPartIdx = uiAbsPartIdx + (subTUIndex * partIdxesPerSubTU);
5259
5260            if (splitIntoSubTUs)
5261            {
5262              const UChar combinedCBF = (bestsubTUCBF[compID][subTUIndex] << subTUDepth) | (bestCBF[compID] << uiTrMode);
5263              pcCU->setCbfPartRange(combinedCBF, compID, uisubTUPartIdx, partIdxesPerSubTU);
5264            }
5265            else
5266            {
5267              pcCU->setCbfPartRange((bestCBF[compID] << uiTrMode), compID, uisubTUPartIdx, partIdxesPerSubTU);
5268            }
5269
5270            pcCU->setCrossComponentPredictionAlphaPartRange(bestCrossCPredictionAlpha[compID][subTUIndex], compID, uisubTUPartIdx, partIdxesPerSubTU);
5271            pcCU->setTransformSkipPartRange(uiBestTransformMode[compID][subTUIndex], compID, uisubTUPartIdx, partIdxesPerSubTU);
5272            pcCU->setExplicitRdpcmModePartRange(bestExplicitRdpcmModeUnSplit[compID][subTUIndex], compID, uisubTUPartIdx, partIdxesPerSubTU);
5273          }
5274        }
5275      }
5276
5277      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5278    }
5279  }
5280  else
5281  {
5282    rdCost  += dSingleCost;
5283    ruiBits += uiSingleBits;
5284    ruiDist += uiSingleDist;
5285#if DEBUG_STRING
5286    for(UInt ch = 0; ch < numValidComp; ch++)
5287    {
5288      const ComponentID compID=ComponentID(ch);
5289      DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[compID])
5290
5291      if (rTu.ProcessComponentSection(compID))
5292      {
5293        DEBUG_STRING_APPEND(sDebug, sSingleStringComp[compID])
5294      }
5295    }
5296#endif
5297  }
5298  DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[MAX_NUM_COMPONENT])
5299}
5300
5301
5302
5303Void TEncSearch::xEncodeInterResidualQT( const ComponentID compID, TComTU &rTu )
5304{
5305  TComDataCU* pcCU=rTu.getCU();
5306  const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU();
5307  const UInt uiCurrTrMode = rTu.GetTransformDepthRel();
5308  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5309  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5310
5311  const Bool bSubdiv = uiCurrTrMode != uiTrMode;
5312
5313  const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
5314
5315  if (compID==MAX_NUM_COMPONENT)  // we are not processing a channel, instead we always recurse and code the CBFs
5316  {
5317    if( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() && uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5318    {
5319      if((pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N))
5320      {
5321        assert(bSubdiv); // Inferred splitting rule - see derivation and use of interSplitFlag in the specification.
5322      }
5323      else
5324      {
5325        m_pcEntropyCoder->encodeTransformSubdivFlag( bSubdiv, 5 - uiLog2TrSize );
5326      }
5327    }
5328
5329    assert( !pcCU->isIntra(uiAbsPartIdx) );
5330
5331    const Bool bFirstCbfOfCU = uiCurrTrMode == 0;
5332
5333    for (UInt ch=COMPONENT_Cb; ch<pcCU->getPic()->getNumberValidComponents(); ch++)
5334    {
5335      const ComponentID compIdInner=ComponentID(ch);
5336      if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compIdInner) )
5337      {
5338        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compIdInner, uiCurrTrMode - 1 ) )
5339        {
5340          m_pcEntropyCoder->encodeQtCbf( rTu, compIdInner, !bSubdiv );
5341        }
5342      }
5343      else
5344      {
5345        assert( pcCU->getCbf( uiAbsPartIdx, compIdInner, uiCurrTrMode ) == pcCU->getCbf( uiAbsPartIdx, compIdInner, uiCurrTrMode - 1 ) );
5346      }
5347    }
5348
5349    if (!bSubdiv)
5350    {
5351      m_pcEntropyCoder->encodeQtCbf( rTu, COMPONENT_Y, true );
5352    }
5353  }
5354
5355  if( !bSubdiv )
5356  {
5357    if (compID != MAX_NUM_COMPONENT) // we have already coded the CBFs, so now we code coefficients
5358    {
5359      if (rTu.ProcessComponentSection(compID))
5360      {
5361        if (isChroma(compID) && (pcCU->getCbf(uiAbsPartIdx, COMPONENT_Y, uiTrMode) != 0))
5362        {
5363          m_pcEntropyCoder->encodeCrossComponentPrediction(rTu, compID);
5364        }
5365
5366        if (pcCU->getCbf(uiAbsPartIdx, compID, uiTrMode) != 0)
5367        {
5368          const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5369          TCoeff *pcCoeffCurr = m_ppcQTTempCoeff[compID][uiQTTempAccessLayer] + rTu.getCoefficientOffset(compID);
5370          m_pcEntropyCoder->encodeCoeffNxN( rTu, pcCoeffCurr, compID );
5371        }
5372      }
5373    }
5374  }
5375  else
5376  {
5377    if( compID==MAX_NUM_COMPONENT || pcCU->getCbf( uiAbsPartIdx, compID, uiCurrTrMode ) )
5378    {
5379      TComTURecurse tuRecurseChild(rTu, false);
5380      do
5381      {
5382        xEncodeInterResidualQT( compID, tuRecurseChild );
5383      } while (tuRecurseChild.nextSection(rTu));
5384    }
5385  }
5386}
5387
5388
5389
5390
5391Void TEncSearch::xSetInterResidualQTData( TComYuv* pcResi, Bool bSpatial, TComTU &rTu ) // TODO: turn this into two functions for bSpatial=true and false.
5392{
5393  TComDataCU* pcCU=rTu.getCU();
5394  const UInt uiCurrTrMode=rTu.GetTransformDepthRel();
5395  const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU();
5396  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5397  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5398  const TComSPS *sps=pcCU->getSlice()->getSPS();
5399
5400  if( uiCurrTrMode == uiTrMode )
5401  {
5402    const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
5403    const UInt uiQTTempAccessLayer = sps->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5404
5405    if( bSpatial )
5406    {
5407      // Data to be copied is in the spatial domain, i.e., inverse-transformed.
5408
5409      for(UInt i=0; i<pcResi->getNumberValidComponents(); i++)
5410      {
5411        const ComponentID compID=ComponentID(i);
5412        if (rTu.ProcessComponentSection(compID))
5413        {
5414          const TComRectangle &rectCompTU(rTu.getRect(compID));
5415          m_pcQTTempTComYuv[uiQTTempAccessLayer].copyPartToPartComponentMxN    ( compID, pcResi, rectCompTU );
5416        }
5417      }
5418    }
5419    else
5420    {
5421      for (UInt ch=0; ch < getNumberValidComponents(sps->getChromaFormatIdc()); ch++)
5422      {
5423        const ComponentID compID   = ComponentID(ch);
5424        if (rTu.ProcessComponentSection(compID))
5425        {
5426          const TComRectangle &rectCompTU(rTu.getRect(compID));
5427          const UInt numCoeffInBlock    = rectCompTU.width * rectCompTU.height;
5428          const UInt offset             = rTu.getCoefficientOffset(compID);
5429          TCoeff* dest                  = pcCU->getCoeff(compID)                        + offset;
5430          const TCoeff* src             = m_ppcQTTempCoeff[compID][uiQTTempAccessLayer] + offset;
5431          ::memcpy( dest, src, sizeof(TCoeff)*numCoeffInBlock );
5432
5433#if ADAPTIVE_QP_SELECTION
5434          TCoeff* pcArlCoeffSrc            = m_ppcQTTempArlCoeff[compID][uiQTTempAccessLayer] + offset;
5435          TCoeff* pcArlCoeffDst            = pcCU->getArlCoeff(compID)                        + offset;
5436          ::memcpy( pcArlCoeffDst, pcArlCoeffSrc, sizeof( TCoeff ) * numCoeffInBlock );
5437#endif
5438        }
5439      }
5440    }
5441  }
5442  else
5443  {
5444
5445    TComTURecurse tuRecurseChild(rTu, false);
5446    do
5447    {
5448      xSetInterResidualQTData( pcResi, bSpatial, tuRecurseChild );
5449    } while (tuRecurseChild.nextSection(rTu));
5450  }
5451}
5452
5453
5454
5455
5456UInt TEncSearch::xModeBitsIntra( TComDataCU* pcCU, UInt uiMode, UInt uiPartOffset, UInt uiDepth, const ChannelType chType )
5457{
5458  // Reload only contexts required for coding intra mode information
5459  m_pcRDGoOnSbacCoder->loadIntraDirMode( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST], chType );
5460
5461  // Temporarily set the intra dir being tested, and only
5462  // for absPartIdx, since encodeIntraDirModeLuma/Chroma only use
5463  // the entry at absPartIdx.
5464
5465  UChar &rIntraDirVal=pcCU->getIntraDir( chType )[uiPartOffset];
5466  UChar origVal=rIntraDirVal;
5467  rIntraDirVal = uiMode;
5468  //pcCU->setIntraDirSubParts ( chType, uiMode, uiPartOffset, uiDepth + uiInitTrDepth );
5469
5470  m_pcEntropyCoder->resetBits();
5471  if (isLuma(chType))
5472  {
5473    m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPartOffset);
5474  }
5475  else
5476  {
5477    m_pcEntropyCoder->encodeIntraDirModeChroma ( pcCU, uiPartOffset);
5478  }
5479
5480  rIntraDirVal = origVal; // restore
5481
5482  return m_pcEntropyCoder->getNumberOfWrittenBits();
5483}
5484
5485
5486
5487
5488UInt TEncSearch::xUpdateCandList( UInt uiMode, Double uiCost, UInt uiFastCandNum, UInt * CandModeList, Double * CandCostList )
5489{
5490  UInt i;
5491  UInt shift=0;
5492
5493  while ( shift<uiFastCandNum && uiCost<CandCostList[ uiFastCandNum-1-shift ] )
5494  {
5495    shift++;
5496  }
5497
5498  if( shift!=0 )
5499  {
5500    for(i=1; i<shift; i++)
5501    {
5502      CandModeList[ uiFastCandNum-i ] = CandModeList[ uiFastCandNum-1-i ];
5503      CandCostList[ uiFastCandNum-i ] = CandCostList[ uiFastCandNum-1-i ];
5504    }
5505    CandModeList[ uiFastCandNum-shift ] = uiMode;
5506    CandCostList[ uiFastCandNum-shift ] = uiCost;
5507    return 1;
5508  }
5509
5510  return 0;
5511}
5512
5513
5514
5515
5516
5517/** add inter-prediction syntax elements for a CU block
5518 * \param pcCU
5519 * \param uiQp
5520 * \param uiTrMode
5521 * \param ruiBits
5522 * \returns Void
5523 */
5524Void  TEncSearch::xAddSymbolBitsInter( TComDataCU* pcCU, UInt& ruiBits )
5525{
5526  if(pcCU->getMergeFlag( 0 ) && pcCU->getPartitionSize( 0 ) == SIZE_2Nx2N && !pcCU->getQtRootCbf( 0 ))
5527  {
5528    pcCU->setSkipFlagSubParts( true, 0, pcCU->getDepth(0) );
5529
5530    m_pcEntropyCoder->resetBits();
5531    if(pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
5532    {
5533      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
5534    }
5535    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
5536    m_pcEntropyCoder->encodeMergeIndex(pcCU, 0, true);
5537
5538    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5539  }
5540  else
5541  {
5542    m_pcEntropyCoder->resetBits();
5543
5544    if(pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
5545    {
5546      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
5547    }
5548
5549    m_pcEntropyCoder->encodeSkipFlag ( pcCU, 0, true );
5550    m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
5551    m_pcEntropyCoder->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
5552    m_pcEntropyCoder->encodePredInfo( pcCU, 0 );
5553
5554    Bool codeDeltaQp = false;
5555    Bool codeChromaQpAdj = false;
5556    m_pcEntropyCoder->encodeCoeff   ( pcCU, 0, pcCU->getDepth(0), codeDeltaQp, codeChromaQpAdj );
5557
5558    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5559  }
5560}
5561
5562
5563
5564
5565
5566/**
5567 * \brief Generate half-sample interpolated block
5568 *
5569 * \param pattern Reference picture ROI
5570 * \param biPred    Flag indicating whether block is for biprediction
5571 */
5572Void TEncSearch::xExtDIFUpSamplingH( TComPattern* pattern )
5573{
5574  Int width      = pattern->getROIYWidth();
5575  Int height     = pattern->getROIYHeight();
5576  Int srcStride  = pattern->getPatternLStride();
5577
5578  Int intStride = m_filteredBlockTmp[0].getStride(COMPONENT_Y);
5579  Int dstStride = m_filteredBlock[0][0].getStride(COMPONENT_Y);
5580  Pel *intPtr;
5581  Pel *dstPtr;
5582  Int filterSize = NTAPS_LUMA;
5583  Int halfFilterSize = (filterSize>>1);
5584  Pel *srcPtr = pattern->getROIY() - halfFilterSize*srcStride - 1;
5585
5586  const ChromaFormat chFmt = m_filteredBlock[0][0].getChromaFormat();
5587
5588  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[0].getAddr(COMPONENT_Y), intStride, width+1, height+filterSize, 0, false, chFmt, pattern->getBitDepthY());
5589  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[2].getAddr(COMPONENT_Y), intStride, width+1, height+filterSize, 2, false, chFmt, pattern->getBitDepthY());
5590
5591  intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + halfFilterSize * intStride + 1;
5592  dstPtr = m_filteredBlock[0][0].getAddr(COMPONENT_Y);
5593  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+0, height+0, 0, false, true, chFmt, pattern->getBitDepthY());
5594
5595  intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride + 1;
5596  dstPtr = m_filteredBlock[2][0].getAddr(COMPONENT_Y);
5597  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+0, height+1, 2, false, true, chFmt, pattern->getBitDepthY());
5598
5599  intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + halfFilterSize * intStride;
5600  dstPtr = m_filteredBlock[0][2].getAddr(COMPONENT_Y);
5601  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+1, height+0, 0, false, true, chFmt, pattern->getBitDepthY());
5602
5603  intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5604  dstPtr = m_filteredBlock[2][2].getAddr(COMPONENT_Y);
5605  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+1, height+1, 2, false, true, chFmt, pattern->getBitDepthY());
5606}
5607
5608
5609
5610
5611
5612/**
5613 * \brief Generate quarter-sample interpolated blocks
5614 *
5615 * \param pattern    Reference picture ROI
5616 * \param halfPelRef Half-pel mv
5617 * \param biPred     Flag indicating whether block is for biprediction
5618 */
5619Void TEncSearch::xExtDIFUpSamplingQ( TComPattern* pattern, TComMv halfPelRef )
5620{
5621  Int width      = pattern->getROIYWidth();
5622  Int height     = pattern->getROIYHeight();
5623  Int srcStride  = pattern->getPatternLStride();
5624
5625  Pel *srcPtr;
5626  Int intStride = m_filteredBlockTmp[0].getStride(COMPONENT_Y);
5627  Int dstStride = m_filteredBlock[0][0].getStride(COMPONENT_Y);
5628  Pel *intPtr;
5629  Pel *dstPtr;
5630  Int filterSize = NTAPS_LUMA;
5631
5632  Int halfFilterSize = (filterSize>>1);
5633
5634  Int extHeight = (halfPelRef.getVer() == 0) ? height + filterSize : height + filterSize-1;
5635
5636  const ChromaFormat chFmt = m_filteredBlock[0][0].getChromaFormat();
5637
5638  // Horizontal filter 1/4
5639  srcPtr = pattern->getROIY() - halfFilterSize * srcStride - 1;
5640  intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y);
5641  if (halfPelRef.getVer() > 0)
5642  {
5643    srcPtr += srcStride;
5644  }
5645  if (halfPelRef.getHor() >= 0)
5646  {
5647    srcPtr += 1;
5648  }
5649  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 1, false, chFmt, pattern->getBitDepthY());
5650
5651  // Horizontal filter 3/4
5652  srcPtr = pattern->getROIY() - halfFilterSize*srcStride - 1;
5653  intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y);
5654  if (halfPelRef.getVer() > 0)
5655  {
5656    srcPtr += srcStride;
5657  }
5658  if (halfPelRef.getHor() > 0)
5659  {
5660    srcPtr += 1;
5661  }
5662  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 3, false, chFmt, pattern->getBitDepthY());
5663
5664  // Generate @ 1,1
5665  intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5666  dstPtr = m_filteredBlock[1][1].getAddr(COMPONENT_Y);
5667  if (halfPelRef.getVer() == 0)
5668  {
5669    intPtr += intStride;
5670  }
5671  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, pattern->getBitDepthY());
5672
5673  // Generate @ 3,1
5674  intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5675  dstPtr = m_filteredBlock[3][1].getAddr(COMPONENT_Y);
5676  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5677
5678  if (halfPelRef.getVer() != 0)
5679  {
5680    // Generate @ 2,1
5681    intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5682    dstPtr = m_filteredBlock[2][1].getAddr(COMPONENT_Y);
5683    if (halfPelRef.getVer() == 0)
5684    {
5685      intPtr += intStride;
5686    }
5687    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true, chFmt, pattern->getBitDepthY());
5688
5689    // Generate @ 2,3
5690    intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5691    dstPtr = m_filteredBlock[2][3].getAddr(COMPONENT_Y);
5692    if (halfPelRef.getVer() == 0)
5693    {
5694      intPtr += intStride;
5695    }
5696    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true, chFmt, pattern->getBitDepthY());
5697  }
5698  else
5699  {
5700    // Generate @ 0,1
5701    intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + halfFilterSize * intStride;
5702    dstPtr = m_filteredBlock[0][1].getAddr(COMPONENT_Y);
5703    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true, chFmt, pattern->getBitDepthY());
5704
5705    // Generate @ 0,3
5706    intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + halfFilterSize * intStride;
5707    dstPtr = m_filteredBlock[0][3].getAddr(COMPONENT_Y);
5708    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true, chFmt, pattern->getBitDepthY());
5709  }
5710
5711  if (halfPelRef.getHor() != 0)
5712  {
5713    // Generate @ 1,2
5714    intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5715    dstPtr = m_filteredBlock[1][2].getAddr(COMPONENT_Y);
5716    if (halfPelRef.getHor() > 0)
5717    {
5718      intPtr += 1;
5719    }
5720    if (halfPelRef.getVer() >= 0)
5721    {
5722      intPtr += intStride;
5723    }
5724    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, pattern->getBitDepthY());
5725
5726    // Generate @ 3,2
5727    intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5728    dstPtr = m_filteredBlock[3][2].getAddr(COMPONENT_Y);
5729    if (halfPelRef.getHor() > 0)
5730    {
5731      intPtr += 1;
5732    }
5733    if (halfPelRef.getVer() > 0)
5734    {
5735      intPtr += intStride;
5736    }
5737    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5738  }
5739  else
5740  {
5741    // Generate @ 1,0
5742    intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride + 1;
5743    dstPtr = m_filteredBlock[1][0].getAddr(COMPONENT_Y);
5744    if (halfPelRef.getVer() >= 0)
5745    {
5746      intPtr += intStride;
5747    }
5748    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, pattern->getBitDepthY());
5749
5750    // Generate @ 3,0
5751    intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride + 1;
5752    dstPtr = m_filteredBlock[3][0].getAddr(COMPONENT_Y);
5753    if (halfPelRef.getVer() > 0)
5754    {
5755      intPtr += intStride;
5756    }
5757    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5758  }
5759
5760  // Generate @ 1,3
5761  intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5762  dstPtr = m_filteredBlock[1][3].getAddr(COMPONENT_Y);
5763  if (halfPelRef.getVer() == 0)
5764  {
5765    intPtr += intStride;
5766  }
5767  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, pattern->getBitDepthY());
5768
5769  // Generate @ 3,3
5770  intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5771  dstPtr = m_filteredBlock[3][3].getAddr(COMPONENT_Y);
5772  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5773}
5774
5775
5776
5777
5778
5779//! set wp tables
5780Void  TEncSearch::setWpScalingDistParam( TComDataCU* pcCU, Int iRefIdx, RefPicList eRefPicListCur )
5781{
5782  if ( iRefIdx<0 )
5783  {
5784    m_cDistParam.bApplyWeight = false;
5785    return;
5786  }
5787
5788  TComSlice       *pcSlice  = pcCU->getSlice();
5789  WPScalingParam  *wp0 , *wp1;
5790
5791  m_cDistParam.bApplyWeight = ( pcSlice->getSliceType()==P_SLICE && pcSlice->testWeightPred() ) || ( pcSlice->getSliceType()==B_SLICE && pcSlice->testWeightBiPred() ) ;
5792
5793  if ( !m_cDistParam.bApplyWeight )
5794  {
5795    return;
5796  }
5797
5798  Int iRefIdx0 = ( eRefPicListCur == REF_PIC_LIST_0 ) ? iRefIdx : (-1);
5799  Int iRefIdx1 = ( eRefPicListCur == REF_PIC_LIST_1 ) ? iRefIdx : (-1);
5800
5801  getWpScaling( pcCU, iRefIdx0, iRefIdx1, wp0 , wp1 );
5802
5803  if ( iRefIdx0 < 0 )
5804  {
5805    wp0 = NULL;
5806  }
5807  if ( iRefIdx1 < 0 )
5808  {
5809    wp1 = NULL;
5810  }
5811
5812  m_cDistParam.wpCur  = NULL;
5813
5814  if ( eRefPicListCur == REF_PIC_LIST_0 )
5815  {
5816    m_cDistParam.wpCur = wp0;
5817  }
5818  else
5819  {
5820    m_cDistParam.wpCur = wp1;
5821  }
5822}
5823
5824#if SVC_EXTENSION
5825#if REF_IDX_ME_ZEROMV
5826Void TEncSearch::xPatternSearchFracDIFMv0( TComPattern* pcPatternKey,
5827                                           Pel* piRefY,
5828                                           Int iRefStride,
5829                                           TComMv* pcMvInt,
5830                                           TComMv& rcMvHalf,
5831                                           TComMv& rcMvQter,
5832                                           UInt& ruiCost     )                                           
5833{
5834  assert(pcMvInt->getHor() == 0 && pcMvInt->getVer() == 0);
5835  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
5836  m_pcRdCost->setDistParam( pcPatternKey, piRefY + iOffset, iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME() );
5837  m_pcRdCost->setCostScale ( 2 );
5838  setDistParamComp(COMPONENT_Y);
5839  ruiCost = m_cDistParam.DistFunc( &m_cDistParam );  //SATD
5840  ruiCost += m_pcRdCost->getCost( pcMvInt->getHor(), pcMvInt->getVer() );  //SATD rdCost
5841  rcMvHalf.setZero();
5842  rcMvQter.setZero();
5843}
5844#endif
5845
5846#if ENCODER_FAST_MODE
5847Bool TEncSearch::predInterSearchILRUni( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, UInt refLayerId )
5848{
5849  rpcPredYuv->clear();
5850  rpcRecoYuv->clear();
5851
5852  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
5853
5854  TComMv        cMv[2];
5855  TComMv        cMvPred[2][33];
5856  TComMv        cMvTemp[2][33];
5857  TComMv        TempMv;
5858
5859  Int           iRefIdx[2]={0,0};
5860
5861  Int           aaiMvpIdx[2][33];
5862  Int           aaiMvpNum[2][33];
5863
5864  UInt          uiMbBits[3] = {1, 1, 0};
5865  UInt          uiLastMode = 0;
5866
5867  UInt          uiCost[2]   = { MAX_UINT, MAX_UINT };     //uni, rdCost
5868  UInt          uiCostTemp;
5869  UInt          biPDistTemp = MAX_INT;
5870  UInt          uiBitsTemp;
5871
5872  PartSize      ePartSize = pcCU->getPartitionSize( 0 );  //2Nx2N
5873  Int           iPartIdx  = 0;                            //one PU in CU
5874  UInt          uiPartAddr;
5875  Int           iRoiWidth, iRoiHeight;
5876  Bool          bILRSearched = false;
5877
5878  xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
5879  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
5880
5881  for( Int iRefList = 0; iRefList < iNumPredDir; iRefList++)  //list
5882  {
5883    if(bILRSearched)
5884    {
5885      continue;
5886    }
5887
5888    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
5889
5890    Int  iRefIdxTemp = -1;
5891    Bool foundILR    = false;
5892
5893    for( Int refIdx = 0; refIdx < pcCU->getSlice()->getNumRefIdx(eRefPicList); refIdx++ )
5894    {
5895      TComPic* refPic = pcCU->getSlice()->getRefPic(eRefPicList, refIdx);
5896
5897      // ILRP has to be for the sample prediction type
5898      if( refPic->isILR(pcCU->getLayerId()) && refPic->getLayerId() == refLayerId && pcCU->getSlice()->getVPS()->isSamplePredictionType( pcCU->getLayerIdx(), pcCU->getSlice()->getVPS()->getLayerIdxInVps(refLayerId) ) )
5899      {
5900        iRefIdxTemp = refIdx;
5901        foundILR    = true;
5902        bILRSearched = true;
5903        break;
5904      }
5905    }
5906
5907    if(!foundILR)  //no ILR in eRefPiclist
5908    {
5909      continue; 
5910    }   
5911
5912    uiBitsTemp = uiMbBits[iRefList];
5913    if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 ) 
5914    { 
5915      uiBitsTemp += iRefIdxTemp+1; 
5916      if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--; 
5917    }
5918
5919    xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
5920    aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
5921    aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
5922
5923    uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
5924
5925    xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
5926    xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
5927
5928    if( uiCostTemp < uiCost[iRefList] )
5929    {
5930      uiCost[iRefList] = uiCostTemp;
5931
5932      cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
5933      iRefIdx[iRefList] = iRefIdxTemp;
5934
5935      pcCU->getCUMvField(eRefPicList)->setAllMv( cMv[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
5936      pcCU->getCUMvField(eRefPicList)->setAllRefIdx( iRefIdx[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
5937    }
5938  }
5939
5940  if( uiCost[0] == MAX_UINT && uiCost[1] == MAX_UINT )  //no ILR in both list0 and list1
5941  {
5942    return false;
5943  }
5944
5945  //  Clear Motion Field
5946  pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
5947  pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
5948  pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx ); 
5949  pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx );
5950
5951  pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
5952  pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
5953  pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
5954  pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
5955
5956  if( uiCost[0] <= uiCost[1] )  //list0 ILR
5957  {
5958    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv    ( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
5959    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
5960
5961    TempMv = cMv[0] - cMvPred[0][iRefIdx[0]]; 
5962    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
5963
5964    pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
5965
5966    pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
5967    pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
5968  }
5969  else if( uiCost[1] < uiCost[0] )  //list1 ILR
5970  {
5971    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv    ( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
5972    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
5973
5974    TempMv = cMv[1] - cMvPred[1][iRefIdx[1]]; 
5975    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
5976
5977    pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
5978
5979    pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
5980    pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
5981  }
5982  else
5983  {
5984    assert(0);
5985  }
5986
5987  pcCU->setMergeFlagSubParts( false, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
5988
5989  motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
5990  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
5991
5992  return true;
5993}
5994#endif
5995#endif //SVC_EXTENSION
5996
5997//! \}
Note: See TracBrowser for help on using the repository browser.