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

Last change on this file since 1314 was 1313, checked in by seregin, 11 years ago

port rev 4387

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