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

Last change on this file since 1110 was 1057, checked in by seregin, 10 years ago

revert back using layerIdx for m_ppcTEncTop, fix RefLayerId settings and related

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