source: 3DVCSoftware/branches/0.2-poznan-univ/source/Lib/TLibEncoder/TEncSearch.cpp @ 12

Last change on this file since 12 was 12, checked in by poznan-univ, 12 years ago

Poznan Tools

  • Depth base motion vector prediction
  • Property svn:eol-style set to native
File size: 222.3 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-2011, 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 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
35/** \file     TEncSearch.cpp
36 \brief    encoder search class
37 */
38
39#include "../TLibCommon/TypeDef.h"
40#include "../TLibCommon/TComMotionInfo.h"
41#include "TEncSearch.h"
42
43static TComMv s_acMvRefineH[9] =
44{
45  TComMv(  0,  0 ), // 0
46  TComMv(  0, -1 ), // 1
47  TComMv(  0,  1 ), // 2
48  TComMv( -1,  0 ), // 3
49  TComMv(  1,  0 ), // 4
50  TComMv( -1, -1 ), // 5
51  TComMv(  1, -1 ), // 6
52  TComMv( -1,  1 ), // 7
53  TComMv(  1,  1 )  // 8
54};
55
56static TComMv s_acMvRefineQ[9] =
57{
58  TComMv(  0,  0 ), // 0
59  TComMv(  0, -1 ), // 1
60  TComMv(  0,  1 ), // 2
61  TComMv( -1, -1 ), // 5
62  TComMv(  1, -1 ), // 6
63  TComMv( -1,  0 ), // 3
64  TComMv(  1,  0 ), // 4
65  TComMv( -1,  1 ), // 7
66  TComMv(  1,  1 )  // 8
67};
68
69static UInt s_auiDFilter[9] =
70{
71  0, 1, 0,
72  2, 3, 2,
73  0, 1, 0
74};
75
76TEncSearch::TEncSearch()
77{
78  m_ppcQTTempCoeffY  = NULL;
79  m_ppcQTTempCoeffCb = NULL;
80  m_ppcQTTempCoeffCr = NULL;
81  m_pcQTTempCoeffY   = NULL;
82  m_pcQTTempCoeffCb  = NULL;
83  m_pcQTTempCoeffCr  = NULL;
84  m_puhQTTempTrIdx   = NULL;
85  m_puhQTTempCbf[0] = m_puhQTTempCbf[1] = m_puhQTTempCbf[2] = NULL;
86  m_pcQTTempTComYuv  = NULL;
87  m_pcEncCfg = NULL;
88  m_pcEntropyCoder = NULL;
89  m_pTempPel = NULL;
90#ifdef WEIGHT_PRED
91  setWpScalingDistParam( NULL, -1, -1, REF_PIC_LIST_X );
92#endif
93}
94
95TEncSearch::~TEncSearch()
96{
97  if ( m_pTempPel )
98  {
99    delete [] m_pTempPel;
100    m_pTempPel = NULL;
101  }
102
103  if ( m_pcEncCfg )
104  {
105    const UInt uiNumLayersAllocated = m_pcEncCfg->getQuadtreeTULog2MaxSize()-m_pcEncCfg->getQuadtreeTULog2MinSize()+1;
106    for( UInt ui = 0; ui < uiNumLayersAllocated; ++ui )
107    {
108      delete[] m_ppcQTTempCoeffY[ui];
109      delete[] m_ppcQTTempCoeffCb[ui];
110      delete[] m_ppcQTTempCoeffCr[ui];
111      m_pcQTTempTComYuv[ui].destroy();
112    }
113  }
114  delete[] m_ppcQTTempCoeffY;
115  delete[] m_ppcQTTempCoeffCb;
116  delete[] m_ppcQTTempCoeffCr;
117  delete[] m_pcQTTempCoeffY;
118  delete[] m_pcQTTempCoeffCb;
119  delete[] m_pcQTTempCoeffCr;
120  delete[] m_puhQTTempTrIdx;
121  delete[] m_puhQTTempCbf[0];
122  delete[] m_puhQTTempCbf[1];
123  delete[] m_puhQTTempCbf[2];
124  delete[] m_pcQTTempTComYuv;
125}
126
127void TEncSearch::init(TEncCfg*      pcEncCfg,
128                      TComTrQuant*  pcTrQuant,
129                      Int           iSearchRange,
130                      Int           bipredSearchRange,
131                      Int           iFastSearch,
132                      Int           iMaxDeltaQP,
133                      TEncEntropy*  pcEntropyCoder,
134                      TComRdCost*   pcRdCost,
135                      TEncSbac*** pppcRDSbacCoder,
136                      TEncSbac*   pcRDGoOnSbacCoder
137                      )
138{
139  m_pcEncCfg             = pcEncCfg;
140  m_pcTrQuant            = pcTrQuant;
141  m_iSearchRange         = iSearchRange;
142  m_bipredSearchRange    = bipredSearchRange;
143  m_iFastSearch          = iFastSearch;
144  m_iMaxDeltaQP          = iMaxDeltaQP;
145  m_pcEntropyCoder       = pcEntropyCoder;
146  m_pcRdCost             = pcRdCost;
147
148  m_pppcRDSbacCoder     = pppcRDSbacCoder;
149  m_pcRDGoOnSbacCoder   = pcRDGoOnSbacCoder;
150
151  m_bUseSBACRD          = pppcRDSbacCoder ? true : false;
152
153  for (Int iDir = 0; iDir < 2; iDir++)
154  {
155    for (Int iRefIdx = 0; iRefIdx < 33; iRefIdx++)
156    {
157      m_aaiAdaptSR[iDir][iRefIdx] = iSearchRange;
158    }
159  }
160
161  m_puiDFilter = s_auiDFilter + 4;
162
163  // initialize motion cost
164  m_pcRdCost->initRateDistortionModel( m_iSearchRange << 2 );
165
166  for( Int iNum = 0; iNum < AMVP_MAX_NUM_CANDS+1; iNum++)
167  {
168    for( Int iIdx = 0; iIdx < AMVP_MAX_NUM_CANDS; iIdx++)
169    {
170      if (iIdx < iNum)
171        m_auiMVPIdxCost[iIdx][iNum] = xGetMvpIdxBits(iIdx, iNum);
172      else
173        m_auiMVPIdxCost[iIdx][iNum] = MAX_INT;
174    }
175  }
176
177  initTempBuff();
178
179  m_pTempPel = new Pel[g_uiMaxCUWidth*g_uiMaxCUHeight];
180
181  const UInt uiNumLayersToAllocate = pcEncCfg->getQuadtreeTULog2MaxSize()-pcEncCfg->getQuadtreeTULog2MinSize()+1;
182  m_ppcQTTempCoeffY  = new TCoeff*[uiNumLayersToAllocate];
183  m_ppcQTTempCoeffCb = new TCoeff*[uiNumLayersToAllocate];
184  m_ppcQTTempCoeffCr = new TCoeff*[uiNumLayersToAllocate];
185  m_pcQTTempCoeffY   = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight   ];
186  m_pcQTTempCoeffCb  = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
187  m_pcQTTempCoeffCr  = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
188
189  const UInt uiNumPartitions = 1<<(g_uiMaxCUDepth<<1);
190  m_puhQTTempTrIdx   = new UChar  [uiNumPartitions];
191  m_puhQTTempCbf[0]  = new UChar  [uiNumPartitions];
192  m_puhQTTempCbf[1]  = new UChar  [uiNumPartitions];
193  m_puhQTTempCbf[2]  = new UChar  [uiNumPartitions];
194  m_pcQTTempTComYuv  = new TComYuv[uiNumLayersToAllocate];
195  for( UInt ui = 0; ui < uiNumLayersToAllocate; ++ui )
196  {
197    m_ppcQTTempCoeffY[ui]  = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight   ];
198    m_ppcQTTempCoeffCb[ui] = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
199    m_ppcQTTempCoeffCr[ui] = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
200    m_pcQTTempTComYuv[ui].create( g_uiMaxCUWidth, g_uiMaxCUHeight );
201  }
202}
203
204#if FASTME_SMOOTHER_MV
205#define FIRSTSEARCHSTOP     1
206#else
207#define FIRSTSEARCHSTOP     0
208#endif
209
210#define TZ_SEARCH_CONFIGURATION                                                                                 \
211const Int  iRaster                  = 5;  /* TZ soll von aussen ?ergeben werden */                            \
212const Bool bTestOtherPredictedMV    = 0;                                                                      \
213const Bool bTestZeroVector          = 1;                                                                      \
214const Bool bTestZeroVectorStart     = 0;                                                                      \
215const Bool bTestZeroVectorStop      = 0;                                                                      \
216const Bool bFirstSearchDiamond      = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
217const Bool bFirstSearchStop         = FIRSTSEARCHSTOP;                                                        \
218const UInt uiFirstSearchRounds      = 3;  /* first search stop X rounds after best match (must be >=1) */     \
219const Bool bEnableRasterSearch      = 1;                                                                      \
220const Bool bAlwaysRasterSearch      = 0;  /* ===== 1: BETTER but factor 2 slower ===== */                     \
221const Bool bRasterRefinementEnable  = 0;  /* enable either raster refinement or star refinement */            \
222const Bool bRasterRefinementDiamond = 0;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
223const Bool bStarRefinementEnable    = 1;  /* enable either star refinement or raster refinement */            \
224const Bool bStarRefinementDiamond   = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
225const Bool bStarRefinementStop      = 0;                                                                      \
226const UInt uiStarRefinementRounds   = 2;  /* star refinement stop X rounds after best match (must be >=1) */  \
227
228
229__inline Void TEncSearch::xTZSearchHelp( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance )
230{
231  UInt  uiSad;
232
233  Pel*  piRefSrch;
234
235  piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;
236
237  //-- jclee for using the SAD function pointer
238  m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );
239
240  // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
241  if ( m_pcEncCfg->getUseFastEnc() )
242  {
243    if ( m_cDistParam.iRows > 8 )
244    {
245      m_cDistParam.iSubShift = 1;
246    }
247  }
248#ifdef WEIGHT_PRED
249  setDistParamComp(0);  // Y component
250#endif
251
252  // distortion
253  uiSad = m_cDistParam.DistFunc( &m_cDistParam );
254
255  // motion cost
256  uiSad += m_pcRdCost->getCost( iSearchX, iSearchY );
257
258  // regularization cost
259  if( m_pcRdCost->useMultiviewReg() )
260  {
261    uiSad += m_pcRdCost->getMultiviewRegCost( iSearchX, iSearchY );
262  }
263
264  if( uiSad < rcStruct.uiBestSad )
265  {
266    rcStruct.uiBestSad      = uiSad;
267    rcStruct.iBestX         = iSearchX;
268    rcStruct.iBestY         = iSearchY;
269    rcStruct.uiBestDistance = uiDistance;
270    rcStruct.uiBestRound    = 0;
271    rcStruct.ucPointNr      = ucPointNr;
272  }
273}
274
275__inline Void TEncSearch::xTZ2PointSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB )
276{
277  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
278  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
279  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
280  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
281
282  // 2 point search,                   //   1 2 3
283  // check only the 2 untested points  //   4 0 5
284  // around the start point            //   6 7 8
285  Int iStartX = rcStruct.iBestX;
286  Int iStartY = rcStruct.iBestY;
287  switch( rcStruct.ucPointNr )
288  {
289    case 1:
290    {
291      if ( (iStartX - 1) >= iSrchRngHorLeft )
292      {
293        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY, 0, 2 );
294      }
295      if ( (iStartY - 1) >= iSrchRngVerTop )
296      {
297        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
298      }
299    }
300      break;
301    case 2:
302    {
303      if ( (iStartY - 1) >= iSrchRngVerTop )
304      {
305        if ( (iStartX - 1) >= iSrchRngHorLeft )
306        {
307          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
308        }
309        if ( (iStartX + 1) <= iSrchRngHorRight )
310        {
311          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
312        }
313      }
314    }
315      break;
316    case 3:
317    {
318      if ( (iStartY - 1) >= iSrchRngVerTop )
319      {
320        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
321      }
322      if ( (iStartX + 1) <= iSrchRngHorRight )
323      {
324        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
325      }
326    }
327      break;
328    case 4:
329    {
330      if ( (iStartX - 1) >= iSrchRngHorLeft )
331      {
332        if ( (iStartY + 1) <= iSrchRngVerBottom )
333        {
334          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
335        }
336        if ( (iStartY - 1) >= iSrchRngVerTop )
337        {
338          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
339        }
340      }
341    }
342      break;
343    case 5:
344    {
345      if ( (iStartX + 1) <= iSrchRngHorRight )
346      {
347        if ( (iStartY - 1) >= iSrchRngVerTop )
348        {
349          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
350        }
351        if ( (iStartY + 1) <= iSrchRngVerBottom )
352        {
353          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
354        }
355      }
356    }
357      break;
358    case 6:
359    {
360      if ( (iStartX - 1) >= iSrchRngHorLeft )
361      {
362        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY , 0, 2 );
363      }
364      if ( (iStartY + 1) <= iSrchRngVerBottom )
365      {
366        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
367      }
368    }
369      break;
370    case 7:
371    {
372      if ( (iStartY + 1) <= iSrchRngVerBottom )
373      {
374        if ( (iStartX - 1) >= iSrchRngHorLeft )
375        {
376          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
377        }
378        if ( (iStartX + 1) <= iSrchRngHorRight )
379        {
380          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
381        }
382      }
383    }
384      break;
385    case 8:
386    {
387      if ( (iStartX + 1) <= iSrchRngHorRight )
388      {
389        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
390      }
391      if ( (iStartY + 1) <= iSrchRngVerBottom )
392      {
393        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
394      }
395    }
396      break;
397    default:
398    {
399      assert( false );
400    }
401      break;
402  } // switch( rcStruct.ucPointNr )
403}
404
405__inline Void TEncSearch::xTZ8PointSquareSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
406{
407  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
408  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
409  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
410  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
411
412  // 8 point search,                   //   1 2 3
413  // search around the start point     //   4 0 5
414  // with the required  distance       //   6 7 8
415  assert( iDist != 0 );
416  const Int iTop        = iStartY - iDist;
417  const Int iBottom     = iStartY + iDist;
418  const Int iLeft       = iStartX - iDist;
419  const Int iRight      = iStartX + iDist;
420  rcStruct.uiBestRound += 1;
421
422  if ( iTop >= iSrchRngVerTop ) // check top
423  {
424    if ( iLeft >= iSrchRngHorLeft ) // check top left
425    {
426      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iTop, 1, iDist );
427    }
428    // top middle
429    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
430
431    if ( iRight <= iSrchRngHorRight ) // check top right
432    {
433      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iTop, 3, iDist );
434    }
435  } // check top
436  if ( iLeft >= iSrchRngHorLeft ) // check middle left
437  {
438    xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
439  }
440  if ( iRight <= iSrchRngHorRight ) // check middle right
441  {
442    xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
443  }
444  if ( iBottom <= iSrchRngVerBottom ) // check bottom
445  {
446    if ( iLeft >= iSrchRngHorLeft ) // check bottom left
447    {
448      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iBottom, 6, iDist );
449    }
450    // check bottom middle
451    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
452
453    if ( iRight <= iSrchRngHorRight ) // check bottom right
454    {
455      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iBottom, 8, iDist );
456    }
457  } // check bottom
458}
459
460__inline Void TEncSearch::xTZ8PointDiamondSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
461{
462  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
463  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
464  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
465  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
466
467  // 8 point search,                   //   1 2 3
468  // search around the start point     //   4 0 5
469  // with the required  distance       //   6 7 8
470  assert ( iDist != 0 );
471  const Int iTop        = iStartY - iDist;
472  const Int iBottom     = iStartY + iDist;
473  const Int iLeft       = iStartX - iDist;
474  const Int iRight      = iStartX + iDist;
475  rcStruct.uiBestRound += 1;
476
477  if ( iDist == 1 ) // iDist == 1
478  {
479    if ( iTop >= iSrchRngVerTop ) // check top
480    {
481      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
482    }
483    if ( iLeft >= iSrchRngHorLeft ) // check middle left
484    {
485      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
486    }
487    if ( iRight <= iSrchRngHorRight ) // check middle right
488    {
489      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
490    }
491    if ( iBottom <= iSrchRngVerBottom ) // check bottom
492    {
493      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
494    }
495  }
496  else // if (iDist != 1)
497  {
498    if ( iDist <= 8 )
499    {
500      const Int iTop_2      = iStartY - (iDist>>1);
501      const Int iBottom_2   = iStartY + (iDist>>1);
502      const Int iLeft_2     = iStartX - (iDist>>1);
503      const Int iRight_2    = iStartX + (iDist>>1);
504
505      if (  iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
506          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
507      {
508        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iTop,      2, iDist    );
509        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iTop_2,    1, iDist>>1 );
510        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2,    3, iDist>>1 );
511        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,    iStartY,   4, iDist    );
512        xTZSearchHelp( pcPatternKey, rcStruct, iRight,   iStartY,   5, iDist    );
513        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iBottom_2, 6, iDist>>1 );
514        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, iDist>>1 );
515        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iBottom,   7, iDist    );
516      }
517      else // check border
518      {
519        if ( iTop >= iSrchRngVerTop ) // check top
520        {
521          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
522        }
523        if ( iTop_2 >= iSrchRngVerTop ) // check half top
524        {
525          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
526          {
527            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iTop_2, 1, (iDist>>1) );
528          }
529          if ( iRight_2 <= iSrchRngHorRight ) // check half right
530          {
531            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2, 3, (iDist>>1) );
532          }
533        } // check half top
534        if ( iLeft >= iSrchRngHorLeft ) // check left
535        {
536          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
537        }
538        if ( iRight <= iSrchRngHorRight ) // check right
539        {
540          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
541        }
542        if ( iBottom_2 <= iSrchRngVerBottom ) // check half bottom
543        {
544          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
545          {
546            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iBottom_2, 6, (iDist>>1) );
547          }
548          if ( iRight_2 <= iSrchRngHorRight ) // check half right
549          {
550            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, (iDist>>1) );
551          }
552        } // check half bottom
553        if ( iBottom <= iSrchRngVerBottom ) // check bottom
554        {
555          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
556        }
557      } // check border
558    }
559    else // iDist > 8
560    {
561      if ( iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
562          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
563      {
564        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop,    0, iDist );
565        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,   iStartY, 0, iDist );
566        xTZSearchHelp( pcPatternKey, rcStruct, iRight,  iStartY, 0, iDist );
567        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
568        for ( Int index = 1; index < 4; index++ )
569        {
570          Int iPosYT = iTop    + ((iDist>>2) * index);
571          Int iPosYB = iBottom - ((iDist>>2) * index);
572          Int iPosXL = iStartX - ((iDist>>2) * index);
573          Int iPosXR = iStartX + ((iDist>>2) * index);
574          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
575          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
576          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
577          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
578        }
579      }
580      else // check border
581      {
582        if ( iTop >= iSrchRngVerTop ) // check top
583        {
584          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 0, iDist );
585        }
586        if ( iLeft >= iSrchRngHorLeft ) // check left
587        {
588          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 0, iDist );
589        }
590        if ( iRight <= iSrchRngHorRight ) // check right
591        {
592          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 0, iDist );
593        }
594        if ( iBottom <= iSrchRngVerBottom ) // check bottom
595        {
596          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
597        }
598        for ( Int index = 1; index < 4; index++ )
599        {
600          Int iPosYT = iTop    + ((iDist>>2) * index);
601          Int iPosYB = iBottom - ((iDist>>2) * index);
602          Int iPosXL = iStartX - ((iDist>>2) * index);
603          Int iPosXR = iStartX + ((iDist>>2) * index);
604
605          if ( iPosYT >= iSrchRngVerTop ) // check top
606          {
607            if ( iPosXL >= iSrchRngHorLeft ) // check left
608            {
609              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
610            }
611            if ( iPosXR <= iSrchRngHorRight ) // check right
612            {
613              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
614            }
615          } // check top
616          if ( iPosYB <= iSrchRngVerBottom ) // check bottom
617          {
618            if ( iPosXL >= iSrchRngHorLeft ) // check left
619            {
620              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
621            }
622            if ( iPosXR <= iSrchRngHorRight ) // check right
623            {
624              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
625            }
626          } // check bottom
627        } // for ...
628      } // check border
629    } // iDist <= 8
630  } // iDist == 1
631}
632
633#ifdef ROUNDING_CONTROL_BIPRED
634UInt TEncSearch::xPatternRefinement_Bi    ( TComPattern* pcPatternKey, Pel* piRef, Int iRefStride, Int iIntStep, Int iFrac, TComMv& rcMvFrac, Pel* pcRef2, Bool bRound, Bool bInterview )
635{
636  UInt  uiDist;
637  UInt  uiDistBest  = MAX_UINT;
638  UInt  uiDirecBest = 0;
639
640  Pel*  piRefPos;
641
642  m_pcRdCost->setDistParam_Bi( pcPatternKey, piRef, iRefStride, iIntStep, m_cDistParam, m_pcEncCfg->getUseHADME() );
643
644  TComMv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
645
646  for (UInt i = 0; i < 9; i++)
647  {
648    TComMv cMvTest = pcMvRefine[i];
649    cMvTest += rcMvFrac;
650    piRefPos = piRef + (pcMvRefine[i].getHor() + iRefStride * pcMvRefine[i].getVer()) * iFrac;
651    m_cDistParam.pCur = piRefPos;
652    uiDist = m_cDistParam.DistFuncRnd( &m_cDistParam, pcRef2, bRound );
653    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
654
655    if ( uiDist < uiDistBest )
656    {
657      uiDistBest  = uiDist;
658      uiDirecBest = i;
659    }
660  }
661
662  rcMvFrac = pcMvRefine[uiDirecBest];
663
664  return uiDistBest;
665}
666#endif
667
668//<--
669
670UInt TEncSearch::xPatternRefinement( TComPattern* pcPatternKey, Pel* piRef, Int iRefStride, Int iIntStep, Int iFrac, TComMv& rcMvFrac )
671{
672  UInt  uiDist;
673  UInt  uiDistBest  = MAX_UINT;
674  UInt  uiDirecBest = 0;
675
676  Pel*  piRefPos;
677  m_pcRdCost->setDistParam( pcPatternKey, piRef, iRefStride, iIntStep, m_cDistParam, m_pcEncCfg->getUseHADME() );
678
679  TComMv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
680
681  for (UInt i = 0; i < 9; i++)
682  {
683    TComMv cMvTest = pcMvRefine[i];
684    cMvTest += rcMvFrac;
685    piRefPos = piRef + (pcMvRefine[i].getHor() + iRefStride * pcMvRefine[i].getVer()) * iFrac;
686    m_cDistParam.pCur = piRefPos;
687#ifdef WEIGHT_PRED
688    setDistParamComp(0);  // Y component
689#endif
690    uiDist = m_cDistParam.DistFunc( &m_cDistParam );
691    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
692
693    if ( uiDist < uiDistBest )
694    {
695      uiDistBest  = uiDist;
696      uiDirecBest = i;
697    }
698  }
699
700  rcMvFrac = pcMvRefine[uiDirecBest];
701
702  return uiDistBest;
703}
704
705Void
706TEncSearch::xEncSubdivCbfQT( TComDataCU*  pcCU,
707                            UInt         uiTrDepth,
708                            UInt         uiAbsPartIdx,
709                            Bool         bLuma,
710                            Bool         bChroma )
711{
712  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
713  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
714  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
715  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
716
717#if CAVLC_RQT_CBP
718  if(pcCU->getSlice()->getSymbolMode() == 0)
719  {
720    if(bLuma && bChroma)
721    {
722      m_pcEntropyCoder->m_pcEntropyCoderIf->codeCbfTrdiv( pcCU, uiAbsPartIdx, uiFullDepth);
723    }
724    else
725    {
726      UInt uiFlagPattern = m_pcEntropyCoder->m_pcEntropyCoderIf->xGetFlagPattern(pcCU, uiAbsPartIdx, uiFullDepth);
727      if(bLuma)
728      {
729        if(uiTrDepth==0 || pcCU->getCbf(uiAbsPartIdx, TEXT_LUMA, uiTrDepth-1))
730          m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, uiTrDepth);
731        if(uiFlagPattern & 0x01)
732          m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, uiFullDepth );
733      }
734      else if(bChroma)
735      {
736        if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
737        {
738          if(uiTrDepth==0 || pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth-1))
739            m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth);
740          if(uiTrDepth==0 || pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth-1))
741            m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth);
742        }
743        if(uiFlagPattern & 0x01)
744          m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, uiFullDepth );
745      }
746    }
747  }
748#endif
749
750#if CAVLC_RQT_CBP
751  if(pcCU->getSlice()->getSymbolMode())
752  {
753#endif
754  if( pcCU->getPredictionMode(0) == MODE_INTRA && pcCU->getPartitionSize(0) == SIZE_NxN && uiTrDepth == 0 )
755  {
756    assert( uiSubdiv );
757  }
758  else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
759  {
760    assert( uiSubdiv );
761  }
762  else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
763  {
764    assert( !uiSubdiv );
765  }
766  else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
767  {
768    assert( !uiSubdiv );
769  }
770  else
771  {
772    assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
773    if( bLuma )
774    {
775      m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, uiFullDepth );
776    }
777  }
778#if CAVLC_RQT_CBP
779  }
780#endif
781
782  if( uiSubdiv )
783  {
784    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
785    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
786    {
787      xEncSubdivCbfQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, bLuma, bChroma );
788    }
789    return;
790  }
791
792  if(pcCU->getSlice()->getSymbolMode())
793  {
794    //===== Cbfs =====
795    if( bLuma )
796    {
797      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
798    }
799    if( bChroma )
800    {
801      Bool bCodeChroma = true;
802      if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
803      {
804        assert( uiTrDepth > 0 );
805        UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
806        bCodeChroma  = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
807      }
808      if( bCodeChroma )
809      {
810        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
811        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
812      }
813    }
814  }
815}
816
817
818Void
819TEncSearch::xEncCoeffQT( TComDataCU*  pcCU,
820                        UInt         uiTrDepth,
821                        UInt         uiAbsPartIdx,
822                        TextType     eTextType,
823                        Bool         bRealCoeff )
824{
825  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
826  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
827  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
828  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
829  UInt  uiChroma        = ( eTextType != TEXT_LUMA ? 1 : 0 );
830
831  if( uiSubdiv )
832  {
833    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
834#if !CAVLC_RQT_CBP
835    if ( pcCU->getSlice()->getSymbolMode() || pcCU->getCbf( uiAbsPartIdx, eTextType, uiTrDepth ))
836    {
837      if(pcCU->getSlice()->getSymbolMode() == 0)
838      {
839        if( eTextType == TEXT_LUMA || uiLog2TrafoSize-1 > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
840          m_pcEntropyCoder->m_pcEntropyCoderIf->codeBlockCbf(pcCU, uiAbsPartIdx, eTextType, uiTrDepth + 1, uiQPartNum, true);
841      }
842#endif
843      for( UInt uiPart = 0; uiPart < 4; uiPart++ )
844      {
845        xEncCoeffQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, eTextType, bRealCoeff );
846      }
847#if !CAVLC_RQT_CBP
848    }
849#endif
850    return;
851  }
852
853  if( eTextType != TEXT_LUMA && uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
854  {
855    assert( uiTrDepth > 0 );
856    uiTrDepth--;
857    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
858    Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
859    if( !bFirstQ )
860    {
861      return;
862    }
863  }
864
865  //===== coefficients =====
866  UInt    uiWidth         = pcCU->getWidth  ( 0 ) >> ( uiTrDepth + uiChroma );
867  UInt    uiHeight        = pcCU->getHeight ( 0 ) >> ( uiTrDepth + uiChroma );
868  UInt    uiCoeffOffset   = ( pcCU->getPic()->getMinCUWidth() * pcCU->getPic()->getMinCUHeight() * uiAbsPartIdx ) >> ( uiChroma << 1 );
869  UInt    uiQTLayer       = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrafoSize;
870  TCoeff* pcCoeff         = 0;
871  switch( eTextType )
872  {
873    case TEXT_LUMA:     pcCoeff = ( bRealCoeff ? pcCU->getCoeffY () : m_ppcQTTempCoeffY [uiQTLayer] );  break;
874    case TEXT_CHROMA_U: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCb() : m_ppcQTTempCoeffCb[uiQTLayer] );  break;
875    case TEXT_CHROMA_V: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCr() : m_ppcQTTempCoeffCr[uiQTLayer] );  break;
876    default:            assert(0);
877  }
878  pcCoeff += uiCoeffOffset;
879
880  m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiWidth, uiHeight, uiFullDepth, eTextType, false );
881}
882
883
884Void
885TEncSearch::xEncIntraHeader( TComDataCU*  pcCU,
886                            UInt         uiTrDepth,
887                            UInt         uiAbsPartIdx,
888                            Bool         bLuma,
889                            Bool         bChroma )
890{
891  if( bLuma )
892  {
893    // CU header
894    if( uiAbsPartIdx == 0 )
895    {
896      if( !pcCU->getSlice()->isIntra() )
897      {
898        m_pcEntropyCoder->encodeSkipFlag( pcCU, 0, true );
899        m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
900      }
901
902      m_pcEntropyCoder  ->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
903    }
904    // luma prediction mode
905    if( pcCU->getPartitionSize(0) == SIZE_2Nx2N )
906    {
907      if( uiAbsPartIdx == 0 )
908      {
909        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, 0 );
910      }
911    }
912    else
913    {
914      UInt uiQNumParts = pcCU->getTotalNumPart() >> 2;
915      if( uiTrDepth == 0 )
916      {
917        assert( uiAbsPartIdx == 0 );
918        for( UInt uiPart = 0; uiPart < 4; uiPart++ )
919        {
920          m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPart * uiQNumParts );
921        }
922      }
923      else if( ( uiAbsPartIdx % uiQNumParts ) == 0 )
924      {
925        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiAbsPartIdx );
926      }
927    }
928  }
929  if( bChroma )
930  {
931    // chroma prediction mode
932    if( uiAbsPartIdx == 0 )
933    {
934      m_pcEntropyCoder->encodeIntraDirModeChroma( pcCU, 0, true );
935    }
936  }
937}
938
939
940UInt
941TEncSearch::xGetIntraBitsQT( TComDataCU*  pcCU,
942                            UInt         uiTrDepth,
943                            UInt         uiAbsPartIdx,
944                            Bool         bLuma,
945                            Bool         bChroma,
946                            Bool         bRealCoeff /* just for test */
947                            )
948{
949  m_pcEntropyCoder->resetBits();
950  xEncIntraHeader ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
951  xEncSubdivCbfQT ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
952 
953  if( bLuma )
954  {
955    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_LUMA,      bRealCoeff );
956  }
957  if( bChroma )
958  {
959    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_U,  bRealCoeff );
960    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_V,  bRealCoeff );
961  }
962  UInt   uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
963  return uiBits;
964}
965
966
967
968Void
969TEncSearch::xIntraCodingLumaBlk( TComDataCU* pcCU,
970                                UInt        uiTrDepth,
971                                UInt        uiAbsPartIdx,
972                                TComYuv*    pcOrgYuv,
973                                TComYuv*    pcPredYuv,
974                                TComYuv*    pcResiYuv,
975                                Dist&       ruiDist
976                                )
977{
978  UInt    uiLumaPredMode    = pcCU     ->getLumaIntraDir     ( uiAbsPartIdx );
979  UInt    uiFullDepth       = pcCU     ->getDepth   ( 0 )  + uiTrDepth;
980  UInt    uiWidth           = pcCU     ->getWidth   ( 0 ) >> uiTrDepth;
981  UInt    uiHeight          = pcCU     ->getHeight  ( 0 ) >> uiTrDepth;
982  UInt    uiStride          = pcOrgYuv ->getStride  ();
983  Pel*    piOrg             = pcOrgYuv ->getLumaAddr( uiAbsPartIdx );
984  Pel*    piPred            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
985  Pel*    piResi            = pcResiYuv->getLumaAddr( uiAbsPartIdx );
986  Pel*    piReco            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
987
988  UInt    uiLog2TrSize      = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
989  UInt    uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
990  UInt    uiNumCoeffPerInc  = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
991  TCoeff* pcCoeff           = m_ppcQTTempCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;
992  Pel*    piRecQt           = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
993  UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
994
995  UInt    uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
996  Pel*    piRecIPred        = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
997  UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getStride  ();
998
999  //===== init availability pattern =====
1000  Bool  bAboveAvail = false;
1001  Bool  bLeftAvail  = false;
1002  pcCU->getPattern()->initPattern   ( pcCU, uiTrDepth, uiAbsPartIdx );
1003  pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1004
1005#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1006  if( uiLumaPredMode > MAX_MODE_ID_INTRA_DIR )
1007  {
1008    predIntraLumaDMM( pcCU, uiAbsPartIdx, uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail, true );
1009  }
1010  else
1011#endif
1012  {
1013    //===== get prediction signal =====
1014    predIntraLumaAng( pcCU->getPattern(), uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1015  }
1016
1017  //===== get residual signal =====
1018  {
1019    // get residual
1020    Pel*  pOrg    = piOrg;
1021    Pel*  pPred   = piPred;
1022    Pel*  pResi   = piResi;
1023    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1024    {
1025      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1026      {
1027        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1028      }
1029      pOrg  += uiStride;
1030      pResi += uiStride;
1031      pPred += uiStride;
1032    }
1033  }
1034
1035  //===== transform and quantization =====
1036  //--- init rate estimation arrays for RDOQ ---
1037  if( m_pcEncCfg->getUseRDOQ() )
1038  {
1039    m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, TEXT_LUMA );
1040  }
1041  //--- transform and quantization ---
1042  UInt uiAbsSum = 0;
1043  pcCU       ->setTrIdxSubParts ( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1044#if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
1045  m_pcTrQuant->setQPforQuant    ( pcCU->getQP( 0 ) + pcCU->getQpOffsetForTextCU(uiAbsPartIdx, true), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_LUMA );
1046#else
1047  m_pcTrQuant->setQPforQuant    ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_LUMA );
1048#endif
1049  m_pcTrQuant->transformNxN     ( pcCU, piResi, uiStride, pcCoeff, uiWidth, uiHeight, uiAbsSum, TEXT_LUMA, uiAbsPartIdx );
1050
1051  //--- set coded block flag ---
1052  pcCU->setCbfSubParts          ( ( uiAbsSum ? 1 : 0 ) << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );
1053  //--- inverse transform ---
1054  if( uiAbsSum )
1055  {
1056#if INTRA_DST_TYPE_7
1057    m_pcTrQuant->invtransformNxN( TEXT_LUMA,pcCU->getLumaIntraDir( uiAbsPartIdx ), piResi, uiStride, pcCoeff, uiWidth, uiHeight );
1058#else
1059    m_pcTrQuant->invtransformNxN( piResi, uiStride, pcCoeff, uiWidth, uiHeight );
1060#endif
1061  }
1062  else
1063  {
1064    Pel* pResi = piResi;
1065    memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );
1066    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1067    {
1068      memset( pResi, 0, sizeof( Pel ) * uiWidth );
1069      pResi += uiStride;
1070    }
1071  }
1072
1073  //===== reconstruction =====
1074  {
1075    Pel* pPred      = piPred;
1076    Pel* pResi      = piResi;
1077    Pel* pReco      = piReco;
1078    Pel* pRecQt     = piRecQt;
1079    Pel* pRecIPred  = piRecIPred;
1080    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1081    {
1082      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1083      {
1084        pReco    [ uiX ] = Clip( pPred[ uiX ] + pResi[ uiX ] );
1085        pRecQt   [ uiX ] = pReco[ uiX ];
1086        pRecIPred[ uiX ] = pReco[ uiX ];
1087      }
1088      pPred     += uiStride;
1089      pResi     += uiStride;
1090      pReco     += uiStride;
1091      pRecQt    += uiRecQtStride;
1092      pRecIPred += uiRecIPredStride;
1093    }
1094  }
1095
1096  //===== update distortion =====
1097#if HHI_VSO
1098  if ( m_pcRdCost->getUseVSO() )
1099  {
1100    ruiDist += m_pcRdCost->getDistVS  ( pcCU, uiAbsPartIdx, piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight, false, 0 );
1101  }
1102  else
1103#endif
1104  {
1105    ruiDist += m_pcRdCost->getDistPart( piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight );
1106  }
1107}
1108
1109Void
1110TEncSearch::xIntraCodingChromaBlk( TComDataCU* pcCU,
1111                                  UInt        uiTrDepth,
1112                                  UInt        uiAbsPartIdx,
1113                                  TComYuv*    pcOrgYuv,
1114                                  TComYuv*    pcPredYuv,
1115                                  TComYuv*    pcResiYuv,
1116                                  Dist&       ruiDist,
1117                                  UInt        uiChromaId )
1118{
1119  UInt uiOrgTrDepth = uiTrDepth;
1120  UInt uiFullDepth  = pcCU->getDepth( 0 ) + uiTrDepth;
1121  UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1122  if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
1123  {
1124    assert( uiTrDepth > 0 );
1125    uiTrDepth--;
1126    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
1127    Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
1128    if( !bFirstQ )
1129    {
1130      return;
1131    }
1132  }
1133
1134  TextType  eText             = ( uiChromaId > 0 ? TEXT_CHROMA_V : TEXT_CHROMA_U );
1135  UInt      uiChromaPredMode  = pcCU     ->getChromaIntraDir( uiAbsPartIdx );
1136  UInt      uiWidth           = pcCU     ->getWidth   ( 0 ) >> ( uiTrDepth + 1 );
1137  UInt      uiHeight          = pcCU     ->getHeight  ( 0 ) >> ( uiTrDepth + 1 );
1138  UInt      uiStride          = pcOrgYuv ->getCStride ();
1139  Pel*      piOrg             = ( uiChromaId > 0 ? pcOrgYuv ->getCrAddr( uiAbsPartIdx ) : pcOrgYuv ->getCbAddr( uiAbsPartIdx ) );
1140  Pel*      piPred            = ( uiChromaId > 0 ? pcPredYuv->getCrAddr( uiAbsPartIdx ) : pcPredYuv->getCbAddr( uiAbsPartIdx ) );
1141  Pel*      piResi            = ( uiChromaId > 0 ? pcResiYuv->getCrAddr( uiAbsPartIdx ) : pcResiYuv->getCbAddr( uiAbsPartIdx ) );
1142  Pel*      piReco            = ( uiChromaId > 0 ? pcPredYuv->getCrAddr( uiAbsPartIdx ) : pcPredYuv->getCbAddr( uiAbsPartIdx ) );
1143
1144  UInt      uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1145  UInt      uiNumCoeffPerInc  = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) ) >> 2;
1146  TCoeff*   pcCoeff           = ( uiChromaId > 0 ? m_ppcQTTempCoeffCr[ uiQTLayer ] : m_ppcQTTempCoeffCb[ uiQTLayer ] ) + uiNumCoeffPerInc * uiAbsPartIdx;
1147  Pel*      piRecQt           = ( uiChromaId > 0 ? m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr( uiAbsPartIdx ) : m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr( uiAbsPartIdx ) );
1148  UInt      uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getCStride();
1149
1150  UInt      uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1151  Pel*      piRecIPred        = ( uiChromaId > 0 ? pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder ) : pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder ) );
1152  UInt      uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getCStride();
1153
1154  //===== update chroma mode =====
1155#if !LM_CHROMA
1156  if( uiChromaPredMode == 4 )
1157  {
1158    uiChromaPredMode          = pcCU->getLumaIntraDir( 0 );
1159  }
1160#endif
1161
1162  //===== init availability pattern =====
1163  Bool  bAboveAvail = false;
1164  Bool  bLeftAvail  = false;
1165  pcCU->getPattern()->initPattern         ( pcCU, uiTrDepth, uiAbsPartIdx );
1166  pcCU->getPattern()->initAdiPatternChroma( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1167  Int*  pPatChroma  = ( uiChromaId > 0 ? pcCU->getPattern()->getAdiCrBuf( uiWidth, uiHeight, m_piYuvExt ) : pcCU->getPattern()->getAdiCbBuf( uiWidth, uiHeight, m_piYuvExt ) );
1168
1169  //===== get prediction signal =====
1170#if LM_CHROMA
1171  if(pcCU->getSlice()->getSPS()->getUseLMChroma() && uiChromaPredMode == 3)
1172  {
1173    predLMIntraChroma( pcCU->getPattern(), pPatChroma, piPred, uiStride, uiWidth, uiHeight, uiChromaId );
1174  }
1175  else
1176  {
1177    if( uiChromaPredMode == 4 )
1178    {
1179      uiChromaPredMode          = pcCU->getLumaIntraDir( 0 );
1180    }
1181  predIntraChromaAng( pcCU->getPattern(), pPatChroma, uiChromaPredMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1182  }
1183#else // LM_CHROMA
1184  predIntraChromaAng( pcCU->getPattern(), pPatChroma, uiChromaPredMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1185#endif
1186
1187  //===== get residual signal =====
1188  {
1189    // get residual
1190    Pel*  pOrg    = piOrg;
1191    Pel*  pPred   = piPred;
1192    Pel*  pResi   = piResi;
1193    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1194    {
1195      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1196      {
1197        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1198      }
1199      pOrg  += uiStride;
1200      pResi += uiStride;
1201      pPred += uiStride;
1202    }
1203  }
1204
1205  //===== transform and quantization =====
1206  {
1207    //--- init rate estimation arrays for RDOQ ---
1208    if( m_pcEncCfg->getUseRDOQ() )
1209    {
1210      m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, eText );
1211    }
1212    //--- transform and quantization ---
1213    UInt uiAbsSum = 0;
1214#if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
1215  m_pcTrQuant->setQPforQuant       ( pcCU->getQP( 0 ) + pcCU->getQpOffsetForTextCU(uiAbsPartIdx, true), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
1216#else
1217    m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
1218#endif
1219    m_pcTrQuant->transformNxN      ( pcCU, piResi, uiStride, pcCoeff, uiWidth, uiHeight, uiAbsSum, eText, uiAbsPartIdx );
1220    //--- set coded block flag ---
1221    pcCU->setCbfSubParts           ( ( uiAbsSum ? 1 : 0 ) << uiOrgTrDepth, eText, uiAbsPartIdx, pcCU->getDepth(0) + uiTrDepth );
1222    //--- inverse transform ---
1223    if( uiAbsSum )
1224    {
1225#if INTRA_DST_TYPE_7
1226    m_pcTrQuant->invtransformNxN( TEXT_CHROMA, REG_DCT, piResi, uiStride, pcCoeff, uiWidth, uiHeight );
1227#else
1228    m_pcTrQuant->invtransformNxN( piResi, uiStride, pcCoeff, uiWidth, uiHeight );
1229#endif
1230    }
1231    else
1232    {
1233      Pel* pResi = piResi;
1234      memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );
1235      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1236      {
1237        memset( pResi, 0, sizeof( Pel ) * uiWidth );
1238        pResi += uiStride;
1239      }
1240    }
1241  }
1242
1243  //===== reconstruction =====
1244  {
1245    Pel* pPred      = piPred;
1246    Pel* pResi      = piResi;
1247    Pel* pReco      = piReco;
1248    Pel* pRecQt     = piRecQt;
1249    Pel* pRecIPred  = piRecIPred;
1250    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1251    {
1252      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1253      {
1254        pReco    [ uiX ] = Clip( pPred[ uiX ] + pResi[ uiX ] );
1255        pRecQt   [ uiX ] = pReco[ uiX ];
1256        pRecIPred[ uiX ] = pReco[ uiX ];
1257      }
1258      pPred     += uiStride;
1259      pResi     += uiStride;
1260      pReco     += uiStride;
1261      pRecQt    += uiRecQtStride;
1262      pRecIPred += uiRecIPredStride;
1263    }
1264  }
1265
1266  //===== update distortion =====
1267  ruiDist += m_pcRdCost->getDistPart( piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight );
1268}
1269
1270
1271
1272Void
1273TEncSearch::xRecurIntraCodingQT( TComDataCU*  pcCU,
1274                                UInt         uiTrDepth,
1275                                UInt         uiAbsPartIdx,
1276                                Bool         bLumaOnly,
1277                                TComYuv*     pcOrgYuv,
1278                                TComYuv*     pcPredYuv,
1279                                TComYuv*     pcResiYuv,
1280                                Dist&        ruiDistY,
1281                                Dist&        ruiDistC,
1282#if HHI_RQT_INTRA_SPEEDUP
1283                                Bool         bCheckFirst,
1284#endif
1285                                Double&      dRDCost )
1286{
1287  UInt    uiFullDepth   = pcCU->getDepth( 0 ) +  uiTrDepth;
1288  UInt    uiLog2TrSize  = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1289  Bool    bCheckFull    = ( uiLog2TrSize  <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
1290  Bool    bCheckSplit   = ( uiLog2TrSize  >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
1291
1292#if HHI_RQT_INTRA_SPEEDUP
1293  if( bCheckFirst && bCheckFull )
1294  {
1295    bCheckSplit = false;
1296  }
1297#endif
1298#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1299  if( pcCU->getLumaIntraDir( uiAbsPartIdx ) > MAX_MODE_ID_INTRA_DIR )
1300  {
1301    bCheckSplit = false;
1302  }
1303#endif
1304  Double  dSingleCost   = MAX_DOUBLE;
1305  Dist    uiSingleDistY = 0;
1306  Dist    uiSingleDistC = 0;
1307  UInt    uiSingleCbfY  = 0;
1308  UInt    uiSingleCbfU  = 0;
1309  UInt    uiSingleCbfV  = 0;
1310
1311  if( bCheckFull )
1312  {
1313    //----- store original entropy coding status -----
1314    if( m_bUseSBACRD && bCheckSplit )
1315    {
1316      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1317    }
1318
1319    //----- code luma block with given intra prediction mode and store Cbf-----
1320    dSingleCost   = 0.0;
1321    xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistY );
1322    if( bCheckSplit )
1323    {
1324      uiSingleCbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrDepth );
1325    }
1326    //----- code chroma blocks with given intra prediction mode and store Cbf-----
1327    if( !bLumaOnly )
1328    {
1329      xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 0 );
1330      xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 1 );
1331      if( bCheckSplit )
1332      {
1333        uiSingleCbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
1334        uiSingleCbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
1335      }
1336    }
1337    //----- determine rate and r-d cost -----
1338    UInt uiSingleBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );
1339
1340#if HHI_VSO
1341    if ( m_pcRdCost->getUseLambdaScaleVSO())
1342    {
1343      dSingleCost = m_pcRdCost->calcRdCostVSO( uiSingleBits, uiSingleDistY + uiSingleDistC );
1344    }
1345    else
1346    {
1347      dSingleCost = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDistY + uiSingleDistC );
1348    }
1349#else
1350    dSingleCost = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDistY + uiSingleDistC );
1351#endif
1352  }
1353
1354  if( bCheckSplit )
1355  {
1356    //----- store full entropy coding status, load original entropy coding status -----
1357    if( m_bUseSBACRD )
1358    {
1359      if( bCheckFull )
1360      {
1361        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1362        m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1363      }
1364      else
1365      {
1366        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1367      }
1368    }
1369    //----- code splitted block -----
1370    Double  dSplitCost      = 0.0;
1371    Dist    uiSplitDistY    = 0;
1372    Dist    uiSplitDistC    = 0;
1373    UInt    uiQPartsDiv     = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1374    UInt    uiAbsPartIdxSub = uiAbsPartIdx;
1375
1376    UInt    uiSplitCbfY = 0;
1377    UInt    uiSplitCbfU = 0;
1378    UInt    uiSplitCbfV = 0;
1379
1380    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiAbsPartIdxSub += uiQPartsDiv )
1381    {
1382#if HHI_RQT_INTRA_SPEEDUP
1383      xRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, bCheckFirst, dSplitCost );
1384#else
1385      xRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, dSplitCost );
1386#endif
1387
1388      uiSplitCbfY |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_LUMA, uiTrDepth + 1 );
1389      if(!bLumaOnly)
1390      {
1391        uiSplitCbfU |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_U, uiTrDepth + 1 );
1392        uiSplitCbfV |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_V, uiTrDepth + 1 );
1393      }
1394    }
1395
1396    for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1397    {
1398      pcCU->getCbf( TEXT_LUMA )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfY << uiTrDepth );
1399    }
1400    if( !bLumaOnly )
1401    {
1402      for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1403      {
1404        pcCU->getCbf( TEXT_CHROMA_U )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfU << uiTrDepth );
1405        pcCU->getCbf( TEXT_CHROMA_V )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfV << uiTrDepth );
1406      }
1407    }
1408    //----- restore context states -----
1409    if( m_bUseSBACRD )
1410    {
1411      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1412    }
1413    //----- determine rate and r-d cost -----
1414    UInt uiSplitBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );
1415#if HHI_VSO
1416    if( m_pcRdCost->getUseLambdaScaleVSO() )
1417    {
1418      dSplitCost = m_pcRdCost->calcRdCostVSO( uiSplitBits, uiSplitDistY + uiSplitDistC );
1419    }
1420    else
1421    {
1422      dSplitCost       = m_pcRdCost->calcRdCost( uiSplitBits, uiSplitDistY + uiSplitDistC );
1423    }
1424#else
1425    dSplitCost       = m_pcRdCost->calcRdCost( uiSplitBits, uiSplitDistY + uiSplitDistC );
1426#endif
1427
1428    //===== compare and set best =====
1429    if( dSplitCost < dSingleCost )
1430    {
1431      //--- update cost ---
1432      ruiDistY += uiSplitDistY;
1433      ruiDistC += uiSplitDistC;
1434      dRDCost  += dSplitCost;
1435      return;
1436    }
1437    //----- set entropy coding status -----
1438    if( m_bUseSBACRD )
1439    {
1440      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1441    }
1442  }
1443
1444  if( bCheckSplit )
1445  {
1446    //--- set transform index and Cbf values ---
1447    pcCU->setTrIdxSubParts( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1448    pcCU->setCbfSubParts  ( uiSingleCbfY << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );
1449    if( !bLumaOnly )
1450    {
1451      pcCU->setCbfSubParts( uiSingleCbfU << uiTrDepth, TEXT_CHROMA_U, uiAbsPartIdx, uiFullDepth );
1452      pcCU->setCbfSubParts( uiSingleCbfV << uiTrDepth, TEXT_CHROMA_V, uiAbsPartIdx, uiFullDepth );
1453    }
1454
1455    //--- set reconstruction for next intra prediction blocks ---
1456    UInt  uiWidth     = pcCU->getWidth ( 0 ) >> uiTrDepth;
1457    UInt  uiHeight    = pcCU->getHeight( 0 ) >> uiTrDepth;
1458    UInt  uiQTLayer   = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1459    UInt  uiZOrder    = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1460    Pel*  piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
1461    UInt  uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
1462    Pel*  piDes       = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
1463    UInt  uiDesStride = pcCU->getPic()->getPicYuvRec()->getStride  ();
1464    for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1465    {
1466      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1467      {
1468        piDes[ uiX ] = piSrc[ uiX ];
1469      }
1470    }
1471    if( !bLumaOnly )
1472    {
1473      uiWidth   >>= 1;
1474      uiHeight  >>= 1;
1475      piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr  ( uiAbsPartIdx );
1476      uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getCStride ();
1477      piDes       = pcCU->getPic()->getPicYuvRec()->getCbAddr ( pcCU->getAddr(), uiZOrder );
1478      uiDesStride = pcCU->getPic()->getPicYuvRec()->getCStride();
1479      for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1480      {
1481        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1482        {
1483          piDes[ uiX ] = piSrc[ uiX ];
1484        }
1485      }
1486      piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr  ( uiAbsPartIdx );
1487      piDes       = pcCU->getPic()->getPicYuvRec()->getCrAddr ( pcCU->getAddr(), uiZOrder );
1488      for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1489      {
1490        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1491        {
1492          piDes[ uiX ] = piSrc[ uiX ];
1493        }
1494      }
1495    }
1496  }
1497
1498#if HHI_VSO
1499  if ( m_pcRdCost->getUseRenModel() && bCheckFull )
1500  {
1501    UInt  uiWidth     = pcCU->getWidth ( 0 ) >> uiTrDepth;
1502    UInt  uiHeight    = pcCU->getHeight( 0 ) >> uiTrDepth;
1503    UInt  uiQTLayer   = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1504    Pel*  piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
1505    UInt  uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
1506
1507    m_pcRdCost->setRenModelData( pcCU, uiAbsPartIdx, piSrc, (Int) uiSrcStride, (Int) uiWidth, (Int) uiHeight );
1508  }
1509#endif
1510
1511  ruiDistY += uiSingleDistY;
1512  ruiDistC += uiSingleDistC;
1513  dRDCost  += dSingleCost;
1514}
1515
1516
1517Void
1518TEncSearch::xSetIntraResultQT( TComDataCU* pcCU,
1519                              UInt        uiTrDepth,
1520                              UInt        uiAbsPartIdx,
1521                              Bool        bLumaOnly,
1522                              TComYuv*    pcRecoYuv )
1523{
1524  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
1525  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1526  if(  uiTrMode == uiTrDepth )
1527  {
1528    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1529    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1530
1531    Bool bSkipChroma  = false;
1532    Bool bChromaSame  = false;
1533    if( !bLumaOnly && uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
1534    {
1535      assert( uiTrDepth > 0 );
1536      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
1537      bSkipChroma  = ( ( uiAbsPartIdx % uiQPDiv ) != 0 );
1538      bChromaSame  = true;
1539    }
1540
1541    //===== copy transform coefficients =====
1542    UInt uiNumCoeffY    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
1543    UInt uiNumCoeffIncY = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
1544    TCoeff* pcCoeffSrcY = m_ppcQTTempCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1545    TCoeff* pcCoeffDstY = pcCU->getCoeffY ()              + ( uiNumCoeffIncY * uiAbsPartIdx );
1546    ::memcpy( pcCoeffDstY, pcCoeffSrcY, sizeof( TCoeff ) * uiNumCoeffY );
1547    if( !bLumaOnly && !bSkipChroma )
1548    {
1549      UInt uiNumCoeffC    = ( bChromaSame ? uiNumCoeffY    : uiNumCoeffY    >> 2 );
1550      UInt uiNumCoeffIncC = uiNumCoeffIncY >> 2;
1551      TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1552      TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1553      TCoeff* pcCoeffDstU = pcCU->getCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1554      TCoeff* pcCoeffDstV = pcCU->getCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1555      ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
1556      ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
1557    }
1558
1559    //===== copy reconstruction =====
1560    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartLuma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSize, 1 << uiLog2TrSize );
1561    if( !bLumaOnly && !bSkipChroma )
1562    {
1563      UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
1564      m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
1565    }
1566  }
1567  else
1568  {
1569    UInt uiNumQPart  = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1570    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
1571    {
1572      xSetIntraResultQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiNumQPart, bLumaOnly, pcRecoYuv );
1573    }
1574  }
1575}
1576
1577
1578
1579Void
1580TEncSearch::xRecurIntraChromaCodingQT( TComDataCU*  pcCU,
1581                                      UInt         uiTrDepth,
1582                                      UInt         uiAbsPartIdx,
1583                                      TComYuv*     pcOrgYuv,
1584                                      TComYuv*     pcPredYuv,
1585                                      TComYuv*     pcResiYuv,
1586                                      Dist&        ruiDist )
1587{
1588  UInt uiFullDepth = pcCU->getDepth( 0 ) +  uiTrDepth;
1589  UInt uiTrMode    = pcCU->getTransformIdx( uiAbsPartIdx );
1590  if(  uiTrMode == uiTrDepth )
1591  {
1592    xIntraCodingChromaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist, 0 );
1593    xIntraCodingChromaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist, 1 );
1594  }
1595  else
1596  {
1597    UInt uiSplitCbfU     = 0;
1598    UInt uiSplitCbfV     = 0;
1599    UInt uiQPartsDiv     = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1600    UInt uiAbsPartIdxSub = uiAbsPartIdx;
1601    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiAbsPartIdxSub += uiQPartsDiv )
1602    {
1603      xRecurIntraChromaCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist );
1604      uiSplitCbfU |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_U, uiTrDepth + 1 );
1605      uiSplitCbfV |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_V, uiTrDepth + 1 );
1606    }
1607    for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1608    {
1609      pcCU->getCbf( TEXT_CHROMA_U )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfU << uiTrDepth );
1610      pcCU->getCbf( TEXT_CHROMA_V )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfV << uiTrDepth );
1611    }
1612  }
1613}
1614
1615Void
1616TEncSearch::xSetIntraResultChromaQT( TComDataCU* pcCU,
1617                                    UInt        uiTrDepth,
1618                                    UInt        uiAbsPartIdx,
1619                                    TComYuv*    pcRecoYuv )
1620{
1621  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
1622  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1623  if(  uiTrMode == uiTrDepth )
1624  {
1625    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1626    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1627
1628    Bool bChromaSame  = false;
1629    if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
1630    {
1631      assert( uiTrDepth > 0 );
1632      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
1633      if( ( uiAbsPartIdx % uiQPDiv ) != 0 )
1634      {
1635        return;
1636      }
1637      bChromaSame     = true;
1638    }
1639
1640    //===== copy transform coefficients =====
1641    UInt uiNumCoeffC    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
1642    if( !bChromaSame )
1643    {
1644      uiNumCoeffC     >>= 2;
1645    }
1646    UInt uiNumCoeffIncC = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) + 2 );
1647    TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1648    TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1649    TCoeff* pcCoeffDstU = pcCU->getCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1650    TCoeff* pcCoeffDstV = pcCU->getCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1651    ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
1652    ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
1653
1654    //===== copy reconstruction =====
1655    UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
1656    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
1657  }
1658  else
1659  {
1660    UInt uiNumQPart  = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1661    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
1662    {
1663      xSetIntraResultChromaQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiNumQPart, pcRecoYuv );
1664    }
1665  }
1666}
1667
1668
1669Void
1670TEncSearch::preestChromaPredMode( TComDataCU* pcCU,
1671                                 TComYuv*    pcOrgYuv,
1672                                 TComYuv*    pcPredYuv )
1673{
1674  UInt  uiWidth     = pcCU->getWidth ( 0 ) >> 1;
1675  UInt  uiHeight    = pcCU->getHeight( 0 ) >> 1;
1676  UInt  uiStride    = pcOrgYuv ->getCStride();
1677  Pel*  piOrgU      = pcOrgYuv ->getCbAddr ( 0 );
1678  Pel*  piOrgV      = pcOrgYuv ->getCrAddr ( 0 );
1679  Pel*  piPredU     = pcPredYuv->getCbAddr ( 0 );
1680  Pel*  piPredV     = pcPredYuv->getCrAddr ( 0 );
1681
1682  //===== init pattern =====
1683  Bool  bAboveAvail = false;
1684  Bool  bLeftAvail  = false;
1685  pcCU->getPattern()->initPattern         ( pcCU, 0, 0 );
1686  pcCU->getPattern()->initAdiPatternChroma( pcCU, 0, 0, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1687  Int*  pPatChromaU = pcCU->getPattern()->getAdiCbBuf( uiWidth, uiHeight, m_piYuvExt );
1688  Int*  pPatChromaV = pcCU->getPattern()->getAdiCrBuf( uiWidth, uiHeight, m_piYuvExt );
1689
1690  //===== get best prediction modes (using SAD) =====
1691  UInt  uiMinMode   = 0;
1692  UInt  uiMaxMode   = 4;
1693  UInt  uiBestMode  = MAX_UINT;
1694  UInt  uiMinSAD    = MAX_UINT;
1695  for( UInt uiMode  = uiMinMode; uiMode < uiMaxMode; uiMode++ )
1696  {
1697    //--- get prediction ---
1698    predIntraChromaAng( pcCU->getPattern(), pPatChromaU, uiMode, piPredU, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1699    predIntraChromaAng( pcCU->getPattern(), pPatChromaV, uiMode, piPredV, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1700
1701    //--- get SAD ---
1702    UInt  uiSAD  = m_pcRdCost->calcHAD( piOrgU, uiStride, piPredU, uiStride, uiWidth, uiHeight );  //GT: change metric here?
1703    uiSAD       += m_pcRdCost->calcHAD( piOrgV, uiStride, piPredV, uiStride, uiWidth, uiHeight );  //GT: change metric here?
1704    //--- check ---
1705    if( uiSAD < uiMinSAD )
1706    {
1707      uiMinSAD   = uiSAD;
1708      uiBestMode = uiMode;
1709    }
1710  }
1711
1712  //===== set chroma pred mode =====
1713  pcCU->setChromIntraDirSubParts( uiBestMode, 0, pcCU->getDepth( 0 ) );
1714}
1715
1716Void
1717TEncSearch::estIntraPredQT( TComDataCU* pcCU,
1718                            TComYuv*    pcOrgYuv,
1719                            TComYuv*    pcPredYuv,
1720                            TComYuv*    pcResiYuv,
1721                            TComYuv*    pcRecoYuv,
1722                            Dist&       ruiDistC,
1723                            Bool        bLumaOnly )
1724{
1725  UInt    uiDepth        = pcCU->getDepth(0);
1726  UInt    uiNumPU        = pcCU->getNumPartInter();
1727  UInt    uiInitTrDepth  = pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1;
1728  UInt    uiWidth        = pcCU->getWidth (0) >> uiInitTrDepth;
1729  UInt    uiHeight       = pcCU->getHeight(0) >> uiInitTrDepth;
1730  UInt    uiQNumParts    = pcCU->getTotalNumPart() >> 2;
1731  UInt    uiWidthBit     = pcCU->getIntraSizeIdx(0);
1732  Dist    uiOverallDistY = 0;
1733  Dist    uiOverallDistC = 0;
1734  UInt    CandNum;
1735  UInt    CandModeList[ FAST_UDI_MAX_RDMODE_NUM ];
1736  Double  CandCostList[ FAST_UDI_MAX_RDMODE_NUM ];
1737  UInt    uiFastCandNum=g_aucIntraModeNumFast[ uiWidthBit ];
1738
1739  //===== set QP and clear Cbf =====
1740  pcCU->setQPSubParts( pcCU->getSlice()->getSliceQp(), 0, uiDepth );
1741
1742  //===== loop over partitions =====
1743  UInt uiPartOffset = 0;
1744  for( UInt uiPU = 0; uiPU < uiNumPU; uiPU++, uiPartOffset += uiQNumParts )
1745  {
1746    //===== init pattern for luma prediction =====
1747    Bool bAboveAvail = false;
1748    Bool bLeftAvail  = false;
1749    pcCU->getPattern()->initPattern   ( pcCU, uiInitTrDepth, uiPartOffset );
1750    pcCU->getPattern()->initAdiPattern( pcCU, uiPartOffset, uiInitTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1751
1752    //===== determine set of modes to be tested (using prediction signal only) =====
1753    UInt uiMaxMode     = g_aucIntraModeNumAng[uiWidthBit];
1754#if ADD_PLANAR_MODE
1755    uiMaxMode += 1;
1756#endif
1757#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1758    Bool bTestDmm = false;
1759    if ( m_pcEncCfg->isDepthCoder() && m_pcEncCfg->getUseDMM() )
1760      bTestDmm = true;
1761#endif
1762    UInt uiMaxModeFast = g_aucIntraModeNumFast[ uiWidthBit ];
1763    Pel* piOrg         = pcOrgYuv ->getLumaAddr( uiPU, uiWidth );
1764    Pel* piPred        = pcPredYuv->getLumaAddr( uiPU, uiWidth );
1765    UInt uiStride      = pcPredYuv->getStride();
1766
1767    if ( uiFastCandNum != uiMaxMode ) uiMaxModeFast = 0;
1768    for( Int i=0; i < uiFastCandNum; i++ )
1769    {
1770      CandCostList[ i ] = MAX_DOUBLE;
1771    }
1772    CandNum = 0;
1773
1774#if ADD_PLANAR_MODE
1775    UInt uiHdModeList[NUM_INTRA_MODE];
1776    uiHdModeList[0] = PLANAR_IDX;
1777    for( Int i=1; i < uiMaxMode; i++) uiHdModeList[i] = i-1;
1778
1779    for( Int iMode = Int(uiMaxModeFast); iMode < Int(uiMaxMode); iMode++ )
1780    {
1781      UInt uiMode = uiHdModeList[iMode];
1782#if (!REFERENCE_SAMPLE_PADDING)
1783      if ( !predIntraLumaDirAvailable( uiMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
1784        continue;
1785#endif
1786      predIntraLumaAng( pcCU->getPattern(), uiMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1787#else
1788    for( UInt uiMode = uiMaxModeFast; uiMode < uiMaxMode; uiMode++ )
1789    {
1790#if (!REFERENCE_SAMPLE_PADDING)
1791      if ( !predIntraLumaDirAvailable( uiMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
1792        continue;
1793#endif
1794
1795      predIntraLumaAng( pcCU->getPattern(), uiMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1796#endif
1797      // use hadamard transform here
1798      Dist uiSad;
1799#if HHI_VSO
1800      if ( m_pcRdCost->getUseVSO() )
1801      {
1802        Bool bSad = !m_pcRdCost->getUseRenModel();
1803        uiSad = m_pcRdCost->getDistVS(pcCU, uiPartOffset, piPred, uiStride, piOrg, uiStride, uiWidth, uiHeight, bSad, 0 );
1804      }
1805      else
1806      {
1807        uiSad = (Dist) m_pcRdCost->calcHAD( piOrg, uiStride, piPred, uiStride, uiWidth, uiHeight );
1808      }
1809#else
1810        uiSad = (Dist) m_pcRdCost->calcHAD( piOrg, uiStride, piPred, uiStride, uiWidth, uiHeight );
1811#endif
1812
1813      UInt   iModeBits = xModeBitsIntra( pcCU, uiMode, uiPU, uiPartOffset, uiDepth, uiInitTrDepth );
1814
1815      Double dLambda;
1816#if HHI_VSO
1817      if ( m_pcRdCost->getUseLambdaScaleVSO() )
1818      {
1819        dLambda = m_pcRdCost->getUseRenModel() ? m_pcRdCost->getLambdaVSO() : m_pcRdCost->getSqrtLambdaVSO();
1820        //GT: Sad is SSE for VSO4
1821      }
1822      else
1823      {
1824        dLambda = m_pcRdCost->getSqrtLambda();
1825      }
1826#else
1827      dLambda = m_pcRdCost->getSqrtLambda();
1828#endif
1829
1830      Double cost = (Double)uiSad + (Double)iModeBits *  dLambda;
1831
1832      CandNum += xUpdateCandList( uiMode, cost, uiFastCandNum, CandModeList, CandCostList );
1833#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1834      if ( bTestDmm ) bTestDmm = uiSad ? true : false;
1835#endif
1836    }
1837    UInt uiRdModeList[FAST_UDI_MAX_RDMODE_NUM];
1838    UInt uiNewMaxMode;
1839    UInt uiMinMode = 0;
1840
1841    if(uiFastCandNum!=uiMaxMode)
1842    {
1843      uiNewMaxMode = Min( uiFastCandNum, CandNum );
1844      for( Int i = 0; i < uiNewMaxMode; i++)
1845      {
1846        uiRdModeList[i] = CandModeList[i];
1847      }
1848#if FAST_UDI_USE_MPM
1849#if MTK_DCM_MPM
1850      Int uiPreds[2] = {-1, -1};
1851      Int numCand = pcCU->getIntraDirLumaPredictor(uiPartOffset, uiPreds);
1852
1853      for( Int j=0; j < numCand; j++)
1854      {
1855        Bool mostProbableModeIncluded = false;
1856        Int mostProbableMode = uiPreds[j];
1857#if ADD_PLANAR_MODE
1858      if (mostProbableMode == 2)
1859      {
1860        mostProbableMode = PLANAR_IDX;
1861      }
1862#endif
1863        for( Int i=0; i < uiNewMaxMode; i++)
1864        {
1865          mostProbableModeIncluded |= (mostProbableMode == uiRdModeList[i]);
1866        }
1867        if (!mostProbableModeIncluded)
1868        {
1869          uiRdModeList[uiNewMaxMode++] = mostProbableMode;
1870        }
1871      }
1872#else
1873      Int mostProbableMode = pcCU->getMostProbableIntraDirLuma( uiPartOffset );
1874#if ADD_PLANAR_MODE
1875      if (mostProbableMode == 2)
1876      {
1877        mostProbableMode = PLANAR_IDX;
1878      }
1879#endif
1880      Bool mostProbableModeIncluded = false;
1881      for( Int i=0; i < uiNewMaxMode; i++)
1882      {
1883        mostProbableModeIncluded |= (mostProbableMode == uiRdModeList[i]);
1884      }
1885      if (!mostProbableModeIncluded)
1886      {
1887        uiRdModeList[uiNewMaxMode++] = mostProbableMode;
1888      }
1889#endif
1890#endif
1891    }
1892    else
1893    {
1894      uiNewMaxMode = uiMaxMode;
1895#if ADD_PLANAR_MODE
1896      uiRdModeList[0] = PLANAR_IDX;
1897      for( Int i=1; i < uiNewMaxMode; i++) uiRdModeList[i] = i-1;
1898#else
1899      for( Int i=0; i < uiNewMaxMode; i++) uiRdModeList[i] = i;
1900#endif
1901    }
1902
1903#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1904    if( m_pcEncCfg->isDepthCoder() && uiWidth >= 4 && uiWidth < 64 && m_pcEncCfg->getUseDMM() && bTestDmm && uiWidth == uiHeight )
1905    {
1906#if HHI_DMM_WEDGE_INTRA
1907      UInt uiTabIdx  = 0;
1908      Int  iDeltaDC1 = 0;
1909      Int  iDeltaDC2 = 0;
1910      findWedgeFullMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTabIdx, iDeltaDC1, iDeltaDC2, bAboveAvail, bLeftAvail, WedgeDist_SAD );
1911      pcCU->setWedgeFullTabIdxSubParts  ( uiTabIdx,  uiPartOffset, uiDepth + uiInitTrDepth );
1912      pcCU->setWedgeFullDeltaDC1SubParts( iDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1913      pcCU->setWedgeFullDeltaDC2SubParts( iDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1914
1915      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_FULL_IDX;
1916      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_FULL_D_IDX;
1917
1918      if ( uiWidth > 4 )
1919      {
1920        Int  iWedgeDeltaEnd = 0;
1921
1922        iDeltaDC1 = 0;
1923        iDeltaDC2 = 0;
1924
1925        findWedgePredDirMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTabIdx, iWedgeDeltaEnd, iDeltaDC1, iDeltaDC2, bAboveAvail, bLeftAvail, WedgeDist_SAD );
1926        pcCU->setWedgePredDirTabIdxSubParts  ( uiTabIdx,       uiPartOffset, uiDepth + uiInitTrDepth );
1927        pcCU->setWedgePredDirDeltaEndSubParts( iWedgeDeltaEnd, uiPartOffset, uiDepth + uiInitTrDepth );
1928        pcCU->setWedgePredDirDeltaDC1SubParts( iDeltaDC1,      uiPartOffset, uiDepth + uiInitTrDepth );
1929        pcCU->setWedgePredDirDeltaDC2SubParts( iDeltaDC2,      uiPartOffset, uiDepth + uiInitTrDepth );
1930
1931        uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDDIR_IDX;
1932        uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDDIR_D_IDX;
1933      }
1934#endif
1935#if HHI_DMM_PRED_TEX
1936      TComYuv cTempYuv; cTempYuv.create( uiWidth, uiHeight ); cTempYuv.clear();
1937      Pel* piTempY      = cTempYuv.getLumaAddr();
1938
1939      fillTexturePicTempBlock( pcCU, uiPartOffset, piTempY, uiWidth, uiHeight );
1940
1941      piTempY = cTempYuv.getLumaAddr();
1942
1943      UInt uiTexTabIdx  = 0;
1944      Int  iTexDeltaDC1 = 0;
1945      Int  iTexDeltaDC2 = 0;
1946      findWedgeTexMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTexTabIdx, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail, WedgeDist_SAD, piTempY ); 
1947      pcCU->setWedgePredTexTabIdxSubParts  ( uiTexTabIdx,  uiPartOffset, uiDepth + uiInitTrDepth );
1948      pcCU->setWedgePredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1949      pcCU->setWedgePredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1950
1951      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDTEX_IDX;
1952      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDTEX_D_IDX;
1953
1954      if ( uiWidth > 4 )
1955      {
1956        piTempY = cTempYuv.getLumaAddr();
1957
1958        iTexDeltaDC1 = 0;
1959        iTexDeltaDC2 = 0;
1960
1961        findContourPredTex( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail, piTempY );
1962        pcCU->setContourPredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1963        pcCU->setContourPredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1964
1965        uiRdModeList[ uiNewMaxMode++ ] = DMM_CONTOUR_PREDTEX_IDX;
1966        uiRdModeList[ uiNewMaxMode++ ] = DMM_CONTOUR_PREDTEX_D_IDX;
1967      }
1968
1969      cTempYuv.destroy();
1970#endif
1971    }
1972#endif
1973    //===== check modes (using r-d costs) =====
1974#if HHI_RQT_INTRA_SPEEDUP_MOD
1975    UInt   uiSecondBestMode  = MAX_UINT;
1976    Double dSecondBestPUCost = MAX_DOUBLE;
1977#endif
1978
1979    UInt    uiBestPUMode  = 0;
1980    Dist    uiBestPUDistY = 0;
1981    Dist    uiBestPUDistC = 0;
1982    Double  dBestPUCost   = MAX_DOUBLE;
1983    for( UInt uiMode = uiMinMode; uiMode < uiNewMaxMode; uiMode++ )
1984    {
1985      // set luma prediction mode
1986      UInt uiOrgMode = uiRdModeList[uiMode];
1987
1988#if (!REFERENCE_SAMPLE_PADDING)
1989#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1990      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail, uiWidth, uiHeight, pcCU, uiPartOffset ) )
1991        continue;
1992#else
1993      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
1994        continue;
1995#endif
1996#else
1997#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1998      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
1999        continue;
2000#endif
2001#endif
2002
2003      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2004
2005      // set context models
2006      if( m_bUseSBACRD )
2007      {
2008        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2009      }
2010
2011      // determine residual for partition
2012      Dist   uiPUDistY = 0;
2013      Dist   uiPUDistC = 0;
2014      Double dPUCost   = 0.0;
2015
2016
2017      // reset Model
2018#if HHI_VSO
2019      if( m_pcRdCost->getUseRenModel() )
2020      {
2021        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2022      }
2023#endif
2024
2025#if HHI_RQT_INTRA_SPEEDUP
2026      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );
2027#else
2028      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
2029#endif
2030
2031      // check r-d cost
2032      if( dPUCost < dBestPUCost )
2033      {
2034#if HHI_RQT_INTRA_SPEEDUP_MOD
2035        uiSecondBestMode  = uiBestPUMode;
2036        dSecondBestPUCost = dBestPUCost;
2037#endif
2038        uiBestPUMode  = uiOrgMode;
2039        uiBestPUDistY = uiPUDistY;
2040        uiBestPUDistC = uiPUDistC;
2041        dBestPUCost   = dPUCost;
2042
2043        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2044
2045        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2046        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2047        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2048        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2049        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2050
2051      }
2052#if HHI_RQT_INTRA_SPEEDUP_MOD
2053      else if( dPUCost < dSecondBestPUCost )
2054      {
2055        uiSecondBestMode  = uiOrgMode;
2056        dSecondBestPUCost = dPUCost;
2057      }
2058#endif
2059    } // Mode loop
2060
2061#if HHI_RQT_INTRA_SPEEDUP
2062#if HHI_RQT_INTRA_SPEEDUP_MOD
2063    for( UInt ui =0; ui < 2; ++ui )
2064#endif
2065    {
2066#if HHI_RQT_INTRA_SPEEDUP_MOD
2067      UInt uiOrgMode   = ui ? uiSecondBestMode  : uiBestPUMode;
2068      if( uiOrgMode == MAX_UINT )
2069      {
2070        break;
2071      }
2072#else
2073      UInt uiOrgMode = uiBestPUMode;
2074#endif
2075
2076#if (!REFERENCE_SAMPLE_PADDING)
2077#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2078      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail, uiWidth, uiHeight, pcCU, uiPartOffset ) )
2079        continue;
2080#else
2081      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
2082        continue;
2083#endif
2084#else
2085#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2086      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
2087        continue;
2088#endif
2089#endif
2090
2091      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2092
2093      // set context models
2094      if( m_bUseSBACRD )
2095      {
2096        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2097      }
2098
2099      // determine residual for partition
2100      Dist   uiPUDistY = 0;
2101      Dist   uiPUDistC = 0;
2102      Double dPUCost   = 0.0;
2103
2104#if HHI_VSO
2105      // reset Model
2106      if( m_pcRdCost->getUseRenModel() )
2107      {
2108        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2109      }
2110#endif
2111
2112      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, false, dPUCost );
2113
2114      // check r-d cost
2115      if( dPUCost < dBestPUCost )
2116      {
2117        uiBestPUMode  = uiOrgMode;
2118        uiBestPUDistY = uiPUDistY;
2119        uiBestPUDistC = uiPUDistC;
2120        dBestPUCost   = dPUCost;
2121
2122        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2123
2124        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2125        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2126        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2127        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2128        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2129
2130      }
2131    } // Mode loop
2132#endif
2133
2134    //--- update overall distortion ---
2135    uiOverallDistY += uiBestPUDistY;
2136    uiOverallDistC += uiBestPUDistC;
2137
2138    //--- update transform index and cbf ---
2139    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2140    ::memcpy( pcCU->getTransformIdx()       + uiPartOffset, m_puhQTTempTrIdx,  uiQPartNum * sizeof( UChar ) );
2141    ::memcpy( pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, m_puhQTTempCbf[0], uiQPartNum * sizeof( UChar ) );
2142    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, m_puhQTTempCbf[1], uiQPartNum * sizeof( UChar ) );
2143    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, m_puhQTTempCbf[2], uiQPartNum * sizeof( UChar ) );
2144
2145    //--- set reconstruction for next intra prediction blocks ---
2146    if( uiPU != uiNumPU - 1 )
2147    {
2148      Bool bSkipChroma  = false;
2149      Bool bChromaSame  = false;
2150      UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> ( pcCU->getDepth(0) + uiInitTrDepth ) ] + 2;
2151      if( !bLumaOnly && uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
2152      {
2153        assert( uiInitTrDepth  > 0 );
2154        bSkipChroma  = ( uiPU != 0 );
2155        bChromaSame  = true;
2156      }
2157
2158      UInt    uiCompWidth   = pcCU->getWidth ( 0 ) >> uiInitTrDepth;
2159      UInt    uiCompHeight  = pcCU->getHeight( 0 ) >> uiInitTrDepth;
2160      UInt    uiZOrder      = pcCU->getZorderIdxInCU() + uiPartOffset;
2161      Pel*    piDes         = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
2162      UInt    uiDesStride   = pcCU->getPic()->getPicYuvRec()->getStride();
2163      Pel*    piSrc         = pcRecoYuv->getLumaAddr( uiPartOffset );
2164      UInt    uiSrcStride   = pcRecoYuv->getStride();
2165      for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2166      {
2167        for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2168        {
2169          piDes[ uiX ] = piSrc[ uiX ];
2170        }
2171      }
2172
2173#if HHI_VSO
2174      // set model
2175      if( m_pcRdCost->getUseRenModel() )
2176      {
2177        piSrc = pcRecoYuv->getLumaAddr( uiPartOffset );
2178        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piSrc, uiSrcStride, uiCompWidth, uiCompHeight);
2179      }
2180#endif
2181
2182      if( !bLumaOnly && !bSkipChroma )
2183      {
2184        if( !bChromaSame )
2185        {
2186          uiCompWidth   >>= 1;
2187          uiCompHeight  >>= 1;
2188        }
2189        piDes         = pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder );
2190        uiDesStride   = pcCU->getPic()->getPicYuvRec()->getCStride();
2191        piSrc         = pcRecoYuv->getCbAddr( uiPartOffset );
2192        uiSrcStride   = pcRecoYuv->getCStride();
2193        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2194        {
2195          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2196          {
2197            piDes[ uiX ] = piSrc[ uiX ];
2198          }
2199        }
2200        piDes         = pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder );
2201        piSrc         = pcRecoYuv->getCrAddr( uiPartOffset );
2202        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2203        {
2204          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2205          {
2206            piDes[ uiX ] = piSrc[ uiX ];
2207          }
2208        }
2209      }
2210    }
2211
2212    //=== update PU data ====
2213    pcCU->setLumaIntraDirSubParts     ( uiBestPUMode, uiPartOffset, uiDepth + uiInitTrDepth );
2214    pcCU->copyToPic                   ( uiDepth, uiPU, uiInitTrDepth );
2215  } // PU loop
2216
2217
2218  if( uiNumPU > 1 )
2219  { // set Cbf for all blocks
2220    UInt uiCombCbfY = 0;
2221    UInt uiCombCbfU = 0;
2222    UInt uiCombCbfV = 0;
2223    UInt uiPartIdx  = 0;
2224    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += uiQNumParts )
2225    {
2226      uiCombCbfY |= pcCU->getCbf( uiPartIdx, TEXT_LUMA,     1 );
2227      uiCombCbfU |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_U, 1 );
2228      uiCombCbfV |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_V, 1 );
2229    }
2230    for( UInt uiOffs = 0; uiOffs < 4 * uiQNumParts; uiOffs++ )
2231    {
2232      pcCU->getCbf( TEXT_LUMA     )[ uiOffs ] |= uiCombCbfY;
2233      pcCU->getCbf( TEXT_CHROMA_U )[ uiOffs ] |= uiCombCbfU;
2234      pcCU->getCbf( TEXT_CHROMA_V )[ uiOffs ] |= uiCombCbfV;
2235    }
2236  }
2237
2238  //===== reset context models =====
2239  if(m_bUseSBACRD)
2240  {
2241    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2242  }
2243
2244  //===== set distortion (rate and r-d costs are determined later) =====
2245  ruiDistC                   = uiOverallDistC;
2246  pcCU->getTotalDistortion() = uiOverallDistY + uiOverallDistC;
2247}
2248
2249
2250
2251Void
2252TEncSearch::estIntraPredChromaQT( TComDataCU* pcCU,
2253                                 TComYuv*    pcOrgYuv,
2254                                 TComYuv*    pcPredYuv,
2255                                 TComYuv*    pcResiYuv,
2256                                 TComYuv*    pcRecoYuv,
2257                                 Dist        uiPreCalcDistC )
2258{
2259  UInt    uiDepth     = pcCU->getDepth(0);
2260  UInt    uiBestMode  = 0;
2261  Dist    uiBestDist  = 0;
2262  Double  dBestCost   = MAX_DOUBLE;
2263
2264  //----- init mode list -----
2265#if ADD_PLANAR_MODE
2266  UInt  uiModeList[6];
2267  uiModeList[0] = PLANAR_IDX;
2268  for( Int i = 0; i < 5; i++ )
2269  {
2270    uiModeList[i+1] = i;
2271  }
2272  UInt uiLumaMode = pcCU->getLumaIntraDir(0);
2273#else
2274  UInt  uiModeList[5];
2275  for( Int i = 0; i < 4; i++ )
2276  {
2277    uiModeList[i] = i;
2278  }
2279
2280  uiModeList[4]   = pcCU->getLumaIntraDir(0);
2281#endif
2282
2283  UInt  uiMinMode = 0;
2284#if CHROMA_CODEWORD
2285#if ADD_PLANAR_MODE
2286  UInt  uiMaxMode = 6;
2287
2288#if LM_CHROMA
2289  UInt  uiIgnore;
2290  if(pcCU->getSlice()->getSPS()->getUseLMChroma())
2291  {
2292    uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 3) ) ? uiMaxMode : uiLumaMode );
2293  }
2294  else
2295  {
2296    uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? uiMaxMode : uiLumaMode );
2297  }
2298#else
2299  UInt  uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? uiMaxMode : uiLumaMode );
2300#endif
2301
2302#else
2303  UInt  uiMaxMode = 5;
2304
2305#if LM_CHROMA
2306  UInt  uiIgnore;
2307  if(pcCU->getSlice()->getSPS()->getUseLMChroma())
2308  {
2309    uiIgnore = (uiModeList[4] >= 0 && uiModeList[4] < 3) ? uiModeList[4] : 6;
2310  }
2311  else
2312  {
2313    uiIgnore = (uiModeList[4] >= 0 && uiModeList[4] < 4) ? uiModeList[4] : 6;
2314  }
2315#else
2316  UInt  uiIgnore = (uiModeList[4] < 4) ? uiModeList[4] : 6;
2317#endif
2318
2319#endif
2320#else
2321#if ADD_PLANAR_MODE
2322  UInt  uiMaxMode = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? 6 : 5 );
2323#else
2324  UInt  uiMaxMode = ( uiModeList[4] >= 4 ? 5 : 4 );
2325#endif
2326#endif
2327
2328  //----- check chroma modes -----
2329  for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )
2330  {
2331#if CHROMA_CODEWORD
2332#if ADD_PLANAR_MODE
2333    if ( uiModeList[uiMode] == uiIgnore )
2334#else
2335    if (uiMode == uiIgnore)
2336#endif
2337    {
2338      continue;
2339    }
2340#endif
2341#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2342#if ADD_PLANAR_MODE
2343    if ( uiModeList[uiMode] == 4 && pcCU->getLumaIntraDir(0) > MAX_MODE_ID_INTRA_DIR )
2344    {
2345      continue;
2346    }
2347#else
2348    if ( uiMode == 4 && pcCU->getLumaIntraDir(0) > MAX_MODE_ID_INTRA_DIR )
2349    {
2350      continue;
2351    }
2352#endif
2353#endif
2354    //----- restore context models -----
2355    if( m_bUseSBACRD )
2356    {
2357      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2358    }
2359
2360    //----- chroma coding -----
2361    Dist    uiDist = 0;
2362#if ADD_PLANAR_MODE
2363    pcCU->setChromIntraDirSubParts  ( uiModeList[uiMode], 0, uiDepth );
2364#else
2365    pcCU->setChromIntraDirSubParts  ( uiMode, 0, uiDepth );
2366#endif
2367    xRecurIntraChromaCodingQT       ( pcCU,   0, 0, pcOrgYuv, pcPredYuv, pcResiYuv, uiDist );
2368    UInt    uiBits = xGetIntraBitsQT( pcCU,   0, 0, false, true, false );
2369    Double  dCost  = m_pcRdCost->calcRdCost( uiBits, uiDist );
2370
2371    //----- compare -----
2372    if( dCost < dBestCost )
2373    {
2374      dBestCost   = dCost;
2375      uiBestDist  = uiDist;
2376#if ADD_PLANAR_MODE
2377      uiBestMode  = uiModeList[uiMode];
2378#else
2379      uiBestMode  = uiMode;
2380#endif
2381      UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2382      xSetIntraResultChromaQT( pcCU, 0, 0, pcRecoYuv );
2383      ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
2384      ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
2385    }
2386  }
2387
2388  //----- set data -----
2389  UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2390  ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPN * sizeof( UChar ) );
2391  ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPN * sizeof( UChar ) );
2392  pcCU->setChromIntraDirSubParts( uiBestMode, 0, uiDepth );
2393  pcCU->getTotalDistortion      () += uiBestDist - uiPreCalcDistC;
2394
2395  //----- restore context models -----
2396  if( m_bUseSBACRD )
2397  {
2398    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2399  }
2400}
2401
2402#if (!REFERENCE_SAMPLE_PADDING)
2403#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2404Bool TEncSearch::predIntraLumaDirAvailable( UInt uiMode, UInt uiWidthBit, Bool bAboveAvail, Bool bLeftAvail, UInt uiWidth, UInt uiHeight, TComDataCU* pcCU, UInt uiAbsPartIdx   )
2405#else
2406Bool TEncSearch::predIntraLumaDirAvailable( UInt uiMode, UInt uiWidthBit, Bool bAboveAvail, Bool bLeftAvail )
2407#endif
2408{
2409  Bool bDirAvailable;
2410#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2411  if( uiMode > MAX_MODE_ID_INTRA_DIR )
2412  {
2413    return predIntraLumaDMMAvailable( uiMode, bAboveAvail, bLeftAvail, uiWidth, uiHeight );
2414  }
2415  else
2416#endif
2417  {
2418    bDirAvailable = true;
2419    UInt uiNewMode = g_aucAngIntraModeOrder[uiMode];
2420    if ( uiNewMode > 0 && ( ( (!bAboveAvail) && uiNewMode < 18 ) || ( (!bLeftAvail) && uiNewMode > 17 ) ) )
2421    {
2422      bDirAvailable = false;
2423    }
2424  }
2425
2426  return bDirAvailable;
2427}
2428#endif
2429
2430#if HHI_DMM_WEDGE_INTRA
2431Void TEncSearch::findWedgeFullMinDist( TComDataCU*  pcCU,
2432                                      UInt         uiAbsPtIdx,
2433                                      Pel*         piOrig,
2434                                      Pel*         piPredic,
2435                                      UInt         uiStride,
2436                                      UInt         uiWidth,
2437                                      UInt         uiHeight,
2438                                      UInt&        ruiTabIdx,
2439                                      Int&         riDeltaDC1,
2440                                      Int&         riDeltaDC2,
2441                                      Bool         bAbove,
2442                                      Bool         bLeft,
2443                                      WedgeDist    eWedgeDist
2444                                      )
2445{
2446  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2447
2448  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2449  xSearchWedgeFullMinDist( pcCU, uiAbsPtIdx, pacWedgeList, piOrig, uiStride, uiWidth, uiHeight, ruiTabIdx );
2450
2451  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2452  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2453}
2454
2455Void TEncSearch::xSearchWedgeFullMinDist( TComDataCU* pcCU, UInt uiAbsPtIdx, WedgeList* pacWedgeList, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx )
2456{
2457  ruiTabIdx = 0;
2458
2459  // local pred buffer
2460  TComYuv cPredYuv;
2461  cPredYuv.create( uiWidth, uiHeight );
2462  cPredYuv.clear();
2463
2464  UInt uiPredStride = cPredYuv.getStride();
2465  Pel* piPred       = cPredYuv.getLumaAddr();
2466
2467  Int  iDC1 = 0;
2468  Int  iDC2 = 0;
2469  // regular wedge search
2470  Dist uiBestDist   = RDO_DIST_MAX;
2471  UInt uiBestTabIdx = 0;
2472
2473  for( UInt uiIdx = 0; uiIdx < pacWedgeList->size(); uiIdx++ )
2474  {
2475    calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piRef,  uiRefStride,  iDC1, iDC2 );
2476    assignWedgeDCs2Pred( &(pacWedgeList->at(uiIdx)), piPred, uiPredStride, iDC1, iDC2 );
2477
2478    Dist uiActDist = RDO_DIST_MAX;
2479#if HHI_VSO
2480    if( m_pcRdCost->getUseVSO() )
2481    {
2482      uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false, 0 );
2483    }
2484    else
2485    {
2486      uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2487    }
2488#else
2489    uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2490#endif
2491
2492    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2493    {
2494      uiBestDist   = uiActDist;
2495      uiBestTabIdx = uiIdx;
2496    }
2497  }
2498  ruiTabIdx = uiBestTabIdx;
2499
2500  cPredYuv.destroy();
2501  return;
2502}
2503
2504Void TEncSearch::findWedgePredDirMinDist( TComDataCU*  pcCU,
2505                                         UInt         uiAbsPtIdx,
2506                                         Pel*         piOrig,
2507                                         Pel*         piPredic,
2508                                         UInt         uiStride,
2509                                         UInt         uiWidth,
2510                                         UInt         uiHeight,
2511                                         UInt&        ruiTabIdx,
2512                                         Int&         riWedgeDeltaEnd,
2513                                         Int&         riDeltaDC1,
2514                                         Int&         riDeltaDC2,
2515                                         Bool         bAbove,
2516                                         Bool         bLeft,
2517                                         WedgeDist    eWedgeDist )
2518{
2519  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2520  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2521
2522  ruiTabIdx       = 0;
2523  riWedgeDeltaEnd = 0;
2524
2525  xSearchWedgePredDirMinDist( pcCU, uiAbsPtIdx, pacWedgeList, piOrig, uiStride, uiWidth, uiHeight, ruiTabIdx, riWedgeDeltaEnd );
2526
2527  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2528  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2529}
2530
2531Void TEncSearch::xSearchWedgePredDirMinDist( TComDataCU* pcCU, UInt uiAbsPtIdx, WedgeList* pacWedgeList, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx, Int& riWedgeDeltaEnd )
2532{
2533  ruiTabIdx       = 0;
2534  riWedgeDeltaEnd = 0;
2535
2536  // local pred buffer
2537  TComYuv cPredYuv;
2538  cPredYuv.create( uiWidth, uiHeight );
2539  cPredYuv.clear();
2540
2541  UInt uiPredStride = cPredYuv.getStride();
2542  Pel* piPred       = cPredYuv.getLumaAddr();
2543
2544  Int  iDC1 = 0;
2545  Int  iDC2 = 0;
2546
2547  // regular wedge search
2548  Dist uiBestDist    = RDO_DIST_MAX;
2549  UInt uiBestTabIdx  = 0;
2550  Int  iBestDeltaEnd = 0;
2551
2552  UInt uiIdx = 0;
2553  for( Int iTestDeltaEnd = -DMM_WEDGE_PREDDIR_DELTAEND_MAX; iTestDeltaEnd <= DMM_WEDGE_PREDDIR_DELTAEND_MAX; iTestDeltaEnd++ )
2554  {
2555    uiIdx = getBestContinueWedge( pcCU, uiAbsPtIdx, uiWidth, uiHeight, iTestDeltaEnd );
2556    calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piRef,  uiRefStride,  iDC1, iDC2 );
2557    assignWedgeDCs2Pred( &(pacWedgeList->at(uiIdx)), piPred, uiPredStride, iDC1, iDC2 );
2558
2559    Dist uiActDist = RDO_DIST_MAX;
2560#if HHI_VSO
2561    if( m_pcRdCost->getUseVSO() )
2562    {
2563      uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false, 0 );
2564    }
2565    else
2566    {
2567      uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2568    }
2569#else
2570    uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2571#endif
2572
2573    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2574    {
2575      uiBestDist    = uiActDist;
2576      uiBestTabIdx  = uiIdx;
2577      iBestDeltaEnd = iTestDeltaEnd;
2578    }
2579    else if( uiIdx == uiBestTabIdx && abs(iTestDeltaEnd) < abs(iBestDeltaEnd) )
2580    {
2581      iBestDeltaEnd = iTestDeltaEnd;
2582    }
2583  }
2584
2585  ruiTabIdx       = uiBestTabIdx;
2586  riWedgeDeltaEnd = iBestDeltaEnd;
2587
2588  cPredYuv.destroy();
2589  return;
2590}
2591#endif
2592
2593#if HHI_DMM_PRED_TEX
2594Void TEncSearch::findWedgeTexMinDist( TComDataCU*  pcCU, 
2595                                      UInt         uiAbsPtIdx, 
2596                                      Pel*         piOrig, 
2597                                      Pel*         piPredic, 
2598                                      UInt         uiStride, 
2599                                      UInt         uiWidth, 
2600                                      UInt         uiHeight, 
2601                                      UInt&        ruiTabIdx, 
2602                                      Int&         riDeltaDC1, 
2603                                      Int&         riDeltaDC2, 
2604                                      Bool         bAbove, 
2605                                      Bool         bLeft, 
2606                                      WedgeDist    eWedgeDist,
2607                                      Pel*         piTextureRef
2608                                    )
2609  {
2610  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2611  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2612
2613  ruiTabIdx = getBestWedgeFromText( pcCU, uiAbsPtIdx, uiWidth, uiHeight, eWedgeDist, piTextureRef );
2614
2615  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2616  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2617}
2618
2619Void TEncSearch::findContourPredTex( TComDataCU*  pcCU,
2620                                     UInt         uiAbsPtIdx,
2621                                     Pel*         piOrig,
2622                                     Pel*         piPredic,
2623                                     UInt         uiStride,
2624                                     UInt         uiWidth,
2625                                     UInt         uiHeight,
2626                                     Int&         riDeltaDC1,
2627                                     Int&         riDeltaDC2,
2628                                     Bool         bAbove,
2629                                     Bool         bLeft,
2630                                     Pel*         piTextureRef )
2631{
2632  // get contour pattern
2633  TComWedgelet* pcContourWedge = new TComWedgelet( uiWidth, uiHeight );
2634  getBestContourFromText( pcCU, uiAbsPtIdx, uiWidth, uiHeight, pcContourWedge, piTextureRef );
2635
2636  xGetWedgeDeltaDCsMinDist( pcContourWedge, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2637
2638  pcContourWedge->destroy();
2639  delete pcContourWedge;
2640}
2641#endif
2642#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2643Void TEncSearch::xGetWedgeDeltaDCsMinDist( TComWedgelet* pcWedgelet,
2644                                           TComDataCU*   pcCU,
2645                                           UInt          uiAbsPtIdx,
2646                                           Pel*          piOrig,
2647                                           Pel*          piPredic,
2648                                           UInt          uiStride,
2649                                           UInt          uiWidth,
2650                                           UInt          uiHeight,
2651                                           Int&          riDeltaDC1,
2652                                           Int&          riDeltaDC2,
2653                                           Bool          bAbove,
2654                                           Bool          bLeft )
2655{
2656  Int iDC1 = 0;
2657  Int iDC2 = 0;
2658  calcWedgeDCs       ( pcWedgelet, piOrig,   uiStride, iDC1, iDC2 );
2659  assignWedgeDCs2Pred( pcWedgelet, piPredic, uiStride, iDC1, iDC2 );
2660
2661  Int iPredDC1 = 0;
2662  Int iPredDC2 = 0;
2663  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt );
2664  Int iMaskStride = ( uiWidth<<1 ) + 1;
2665  piMask += iMaskStride+1;
2666  getWedgePredDCs( pcWedgelet, piMask, iMaskStride, iPredDC1, iPredDC2, bAbove, bLeft );
2667
2668  riDeltaDC1 = iDC1 - iPredDC1;
2669  riDeltaDC2 = iDC2 - iPredDC2;
2670
2671#if HHI_VSO
2672  if( m_pcRdCost->getUseVSO() )
2673  {
2674    Int iFullDeltaDC1 = riDeltaDC1;
2675    Int iFullDeltaDC2 = riDeltaDC2;
2676
2677    xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC1 );
2678    xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC2 );
2679
2680    Dist uiBestDist     = RDO_DIST_MAX;
2681    UInt  uiBestQStepDC1 = 0;
2682    UInt  uiBestQStepDC2 = 0;
2683
2684    UInt uiDeltaDC1Max = abs(iFullDeltaDC1);
2685    UInt uiDeltaDC2Max = abs(iFullDeltaDC2);
2686
2687    //VSO Level delta DC check range extension
2688    uiDeltaDC1Max += (uiDeltaDC1Max>>1);
2689    uiDeltaDC2Max += (uiDeltaDC2Max>>1);
2690
2691    for( UInt uiQStepDC1 = 1; uiQStepDC1 <= uiDeltaDC1Max; uiQStepDC1++  )
2692    {
2693      Int iLevelDeltaDC1 = (Int)(uiQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
2694      xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC1 );
2695
2696      Int iTestDC1 = Clip( iPredDC1 + iLevelDeltaDC1 );
2697      for( UInt uiQStepDC2 = 1; uiQStepDC2 <= uiDeltaDC2Max; uiQStepDC2++  )
2698      {
2699        Int iLevelDeltaDC2 = (Int)(uiQStepDC2) * (Int)(( iFullDeltaDC2 < 0 ) ? -1 : 1);
2700        xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC2 );
2701
2702        Int iTestDC2 = Clip( iPredDC2 + iLevelDeltaDC2 );
2703
2704        assignWedgeDCs2Pred( pcWedgelet, piPredic, uiStride, iTestDC1, iTestDC2 );
2705
2706        Dist uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPredic, uiStride,  piOrig, uiStride, uiWidth, uiHeight, false, 0 );
2707        if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2708        {
2709          uiBestDist     = uiActDist;
2710          uiBestQStepDC1 = uiQStepDC1;
2711          uiBestQStepDC2 = uiQStepDC2;
2712        }
2713      }
2714    }
2715
2716    iFullDeltaDC1 = (Int)(uiBestQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
2717    iFullDeltaDC2 = (Int)(uiBestQStepDC2) * (Int)(( iFullDeltaDC2 < 0 ) ? -1 : 1);
2718    xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC1 );
2719    xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC2 );
2720    riDeltaDC1 = iFullDeltaDC1;
2721    riDeltaDC2 = iFullDeltaDC2;
2722  }
2723#endif
2724
2725  xDeltaDCQuantScaleDown( pcCU, riDeltaDC1 );
2726  xDeltaDCQuantScaleDown( pcCU, riDeltaDC2 );
2727}
2728
2729Bool TEncSearch::predIntraLumaDMMAvailable( UInt uiMode, UInt uiWidth, UInt uiHeight )
2730{
2731  if( uiMode <= MAX_MODE_ID_INTRA_DIR ) return true;
2732
2733  Bool bDMMAvailable = m_pcEncCfg->getUseDMM();
2734
2735#if HHI_DMM_WEDGE_INTRA
2736  if( uiMode == DMM_WEDGE_FULL_IDX        ||
2737      uiMode == DMM_WEDGE_FULL_D_IDX      ||
2738      uiMode == DMM_WEDGE_PREDDIR_IDX     ||
2739      uiMode == DMM_WEDGE_PREDDIR_D_IDX )
2740  {
2741    if( (uiWidth != uiHeight) || (uiWidth < DMM_WEDGEMODEL_MIN_SIZE) || (uiWidth > DMM_WEDGEMODEL_MAX_SIZE) || ( ( uiMode == DMM_WEDGE_PREDDIR_IDX || uiMode == DMM_WEDGE_PREDDIR_D_IDX ) && uiWidth == 4 ) )
2742    {
2743      bDMMAvailable = false;
2744    }
2745  }
2746#endif
2747#if HHI_DMM_PRED_TEX
2748  if( uiMode == DMM_WEDGE_PREDTEX_IDX     ||
2749      uiMode == DMM_WEDGE_PREDTEX_D_IDX   ||
2750      uiMode == DMM_CONTOUR_PREDTEX_IDX   ||
2751      uiMode == DMM_CONTOUR_PREDTEX_D_IDX )
2752  {
2753    if( (uiWidth != uiHeight) || (uiWidth < DMM_WEDGEMODEL_MIN_SIZE) || (uiWidth > DMM_WEDGEMODEL_MAX_SIZE) || ( ( uiMode == DMM_CONTOUR_PREDTEX_IDX || uiMode == DMM_CONTOUR_PREDTEX_D_IDX ) && uiWidth == 4 ) )
2754    {
2755      bDMMAvailable = false;
2756    }
2757  }
2758
2759#endif
2760
2761  return bDMMAvailable;
2762}
2763
2764Void TEncSearch::xDeltaDCQuantScaleDown( TComDataCU*  pcCU, Int& riDeltaDC )
2765{
2766  Int  iSign  = riDeltaDC < 0 ? -1 : 1;
2767  UInt uiAbs  = abs( riDeltaDC );
2768
2769  Int riB = 0;
2770  Int iQp = pcCU->getQP(0);
2771  Int iMax = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) );
2772  Double dStepSize = Clip3( 1, iMax, pow( 2.0, iQp/10.0 + g_dDeltaDCsQuantOffset ) );
2773
2774  riB = roftoi( uiAbs / dStepSize );
2775
2776  riDeltaDC = riB * iSign;
2777  return;
2778}
2779#endif
2780
2781
2782Void TEncSearch::xGetInterPredictionError( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, UInt& ruiErr, Bool bHadamard )
2783{
2784  TComYuv cYuvPred;
2785  cYuvPred.create( pcYuvOrg->getWidth(), pcYuvOrg->getHeight() );
2786
2787#ifdef WEIGHT_PRED
2788  UInt uiAbsPartIdx = 0;
2789  Int iWidth = 0;
2790  Int iHeight = 0;
2791  Int iRefIdx[2];
2792  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2793
2794  iRefIdx[0] = pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiAbsPartIdx );
2795  iRefIdx[1] = pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiAbsPartIdx );
2796  if ( iRefIdx[0]>=0 && iRefIdx[1]<1 )
2797    setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_0);
2798  else
2799    setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_1);
2800
2801  motionCompensation( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2802#else
2803  motionCompensation( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2804
2805  UInt uiAbsPartIdx = 0;
2806  Int iWidth = 0;
2807  Int iHeight = 0;
2808  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2809#endif
2810
2811  DistParam cDistParam;
2812#ifdef WEIGHT_PRED
2813  cDistParam.applyWeight = false;
2814#endif
2815  m_pcRdCost->setDistParam( cDistParam,
2816                            pcYuvOrg->getLumaAddr( uiAbsPartIdx ), pcYuvOrg->getStride(),
2817                            cYuvPred .getLumaAddr( uiAbsPartIdx ), cYuvPred .getStride(),
2818                            iWidth, iHeight, m_pcEncCfg->getUseHADME() );
2819  ruiErr = cDistParam.DistFunc( &cDistParam );
2820
2821  cYuvPred.destroy();
2822}
2823
2824#if POZNAN_EIVD
2825Void TEncSearch::xGetInterPredictionError_EIVD( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, UInt& ruiErr, Bool bHadamard )
2826{
2827  TComYuv cYuvPred;
2828  cYuvPred.create( pcYuvOrg->getWidth(), pcYuvOrg->getHeight() );
2829
2830#ifdef WEIGHT_PRED
2831  UInt uiAbsPartIdx = 0;
2832  Int iWidth = 0;
2833  Int iHeight = 0;
2834  //Int iRefIdx[2];
2835  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2836
2837//???????????????????????????????????????????????????????????????????????????????????
2838  //iRefIdx[0] = pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiAbsPartIdx );
2839  //iRefIdx[1] = pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiAbsPartIdx );
2840  //if ( iRefIdx[0]>=0 && iRefIdx[1]<1 )
2841  //  setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_0);
2842  //else
2843  //  setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_1);
2844  setWpScalingDistParam( pcCU, -1, -1, REF_PIC_LIST_X);//???
2845//???????????????????????????????????????????????????????????????????????????????????
2846  motionCompensation_EIVD( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2847#else
2848  motionCompensation_EIVD( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2849
2850  UInt uiAbsPartIdx = 0;
2851  Int iWidth = 0;
2852  Int iHeight = 0;
2853  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2854#endif
2855
2856  DistParam cDistParam;
2857#ifdef WEIGHT_PRED
2858  cDistParam.applyWeight = false;
2859#endif
2860  m_pcRdCost->setDistParam( cDistParam, 
2861                            pcYuvOrg->getLumaAddr( uiAbsPartIdx ), pcYuvOrg->getStride(), 
2862                            cYuvPred .getLumaAddr( uiAbsPartIdx ), cYuvPred .getStride(), 
2863                            iWidth, iHeight, m_pcEncCfg->getUseHADME() );
2864  ruiErr = cDistParam.DistFunc( &cDistParam );
2865
2866  cYuvPred.destroy();
2867}
2868#endif
2869
2870/** estimation of best merge coding
2871 * \param pcCU
2872 * \param pcYuvOrg
2873 * \param iPUIdx
2874 * \param uiInterDir
2875 * \param pacMvField
2876 * \param uiMergeIndex
2877 * \param ruiCost
2878 * \param ruiBits
2879 * \param puhNeighCands
2880 * \param bValid
2881 * \returns Void
2882 */
2883Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost, UInt& ruiBits, UChar* puhNeighCands,Bool& bValid )
2884{
2885  TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
2886  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
2887  UInt uiNeighbourCandIdx[MRG_MAX_NUM_CANDS]; //MVs with same idx => same cand
2888
2889  for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ++ui )
2890  {
2891    uhInterDirNeighbours[ui] = 0;
2892    uiNeighbourCandIdx[ui] = 0;
2893  }
2894
2895  UInt uiAbsPartIdx = 0;
2896  Int iWidth = 0;
2897  Int iHeight = 0;
2898
2899  pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
2900  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
2901  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, uiNeighbourCandIdx );
2902
2903  UInt uiNumCand = 0;
2904  for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; ++uiMergeCand )
2905  {
2906    if( uiNeighbourCandIdx[uiMergeCand] == ( uiMergeCand + 1 ) )
2907    {
2908      uiNumCand++;
2909    }
2910  }
2911
2912  UInt uiBestSAD = MAX_UINT;
2913  UInt uiBestBitCost = MAX_UINT;
2914  UInt uiBestBits = MAX_UINT;
2915
2916  ruiCost = MAX_UINT;
2917  ruiBits = MAX_UINT;
2918
2919  bValid = false;
2920
2921  for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; ++uiMergeCand )
2922  {
2923    if( uiNeighbourCandIdx[uiMergeCand] == ( uiMergeCand + 1 ) )
2924    {
2925      bValid = true;
2926      UInt uiCostCand = MAX_UINT;
2927      UInt uiBitsCand = 0;
2928
2929      PartSize ePartSize = pcCU->getPartitionSize( 0 );
2930
2931#if POZNAN_EIVD_CALC_PRED_DATA
2932          if(uiMergeCand==POZNAN_EIVD_MRG_CAND)
2933          {
2934                pcCU->getCUMvField2nd( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[0 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2935                pcCU->getCUMvField2nd( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[1 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2936          }
2937          else
2938#endif
2939          {
2940      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[0 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2941      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[1 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2942          }
2943
2944#if POZNAN_EIVD
2945          if(uiMergeCand==POZNAN_EIVD_MRG_CAND)
2946                xGetInterPredictionError_EIVD( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2947          else
2948      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2949#else
2950      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2951#endif
2952
2953      if( uiNumCand == 1 )
2954      {
2955        uiBitsCand = 1;
2956      }
2957      else
2958      {
2959        UInt uiMergeCandIdx = uiMergeCand;
2960#if POZNAN_EIVD
2961                if(pcCU->getSlice()->getMP()->isEIVDEnabled())
2962                {
2963                        if(uiMergeCand == POZNAN_EIVD_MRG_CAND) uiMergeCandIdx = POZNAN_EIVD_MERGE_POS;
2964                        else if(uiMergeCand >= POZNAN_EIVD_MERGE_POS) uiMergeCandIdx++;
2965                }
2966#endif
2967
2968        if( uiMergeCandIdx == 0 || uiNumCand == 2 )
2969        {
2970          uiBitsCand = 2;
2971        }
2972        else if( uiMergeCandIdx == 1 || uiNumCand == 3 )
2973        {
2974          uiBitsCand = 3;
2975        }
2976        else if( uiMergeCandIdx == 2 || uiNumCand == 4 )
2977        {
2978          uiBitsCand = 4;
2979        }
2980                else if( uiMergeCandIdx == 3 || uiNumCand == 5 )
2981        {
2982          uiBitsCand = 5;
2983        }
2984        else
2985        {
2986          uiBitsCand = 6;
2987        }
2988      }
2989
2990      if ( uiCostCand < ruiCost )
2991      {
2992        ruiCost = uiCostCand;
2993        ruiBits = uiBitsCand;
2994        pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
2995        pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
2996
2997#if POZNAN_EIVD_CALC_PRED_DATA
2998                if(uiMergeCand==POZNAN_EIVD_MRG_CAND)
2999                {
3000                        TComCUMvField* pcEIVDPredMvField;
3001
3002                        pcEIVDPredMvField = pcCU->getSlice()->getMP()->getEIVDPredMVField(REF_PIC_LIST_0);
3003                        pcEIVDPredMvField->setMv(pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(uiAbsPartIdx),0);
3004                        pcEIVDPredMvField->setRefIdx(pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx),0);
3005
3006                        pcEIVDPredMvField = pcCU->getSlice()->getMP()->getEIVDPredMVField(REF_PIC_LIST_1);
3007                        pcEIVDPredMvField->setMv(pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(uiAbsPartIdx),0);
3008                        pcEIVDPredMvField->setRefIdx(pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx),0);
3009                }
3010#endif
3011
3012        uiInterDir = uhInterDirNeighbours[uiMergeCand];
3013        uiMergeIndex = uiMergeCand;
3014        for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3015        {
3016          UChar uhNeighCand = uiNeighbourCandIdx[ui];
3017          puhNeighCands[ui] = uhNeighCand;
3018        }
3019
3020        uiBestSAD = uiCostCand;
3021        uiBestBitCost = m_pcRdCost->getCost( uiBitsCand );
3022        uiBestBits = uiBitsCand;
3023      }
3024    }
3025  }
3026}
3027
3028/** search of the best candidate for inter prediction
3029 * \param pcCU
3030 * \param pcOrgYuv
3031 * \param rpcPredYuv
3032 * \param rpcResiYuv
3033 * \param rpcRecoYuv
3034 * \param bUseRes
3035 * \returns Void
3036 */
3037Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes )
3038{
3039  m_acYuvPred[0].clear();
3040  m_acYuvPred[1].clear();
3041  m_cYuvPredTemp.clear();
3042  rpcPredYuv->clear();
3043
3044  if ( !bUseRes )
3045  {
3046    rpcResiYuv->clear();
3047  }
3048
3049  rpcRecoYuv->clear();
3050
3051  TComMv        cMvSrchRngLT;
3052  TComMv        cMvSrchRngRB;
3053
3054  TComMv        cMvZero;
3055  TComMv        TempMv; //kolya
3056
3057  TComMv        cMv[2];
3058  TComMv        cMvBi[2];
3059  TComMv        cMvTemp[2][33];
3060
3061  Int           iNumPart    = pcCU->getNumPartInter();
3062  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
3063
3064  TComMv        cMvPred[2][33];
3065
3066  TComMv        cMvPredBi[2][33];
3067  Int           aaiMvpIdxBi[2][33];
3068
3069  Int           aaiMvpIdx[2][33];
3070  Int           aaiMvpNum[2][33];
3071
3072  AMVPInfo aacAMVPInfo[2][33];
3073
3074#ifdef WEIGHT_PRED
3075  Int           iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
3076#else
3077  Int           iRefIdx[2];
3078#endif
3079  Int           iRefIdxBi[2];
3080
3081  UInt          uiPartAddr;
3082  Int           iRoiWidth, iRoiHeight;
3083
3084  UInt          uiMbBits[3] = {1, 1, 0};
3085
3086  UInt          uiLastMode = 0;
3087  Int           iRefStart, iRefEnd;
3088
3089  PartSize      ePartSize = pcCU->getPartitionSize( 0 );
3090
3091#if ZERO_MVD_EST
3092  Int           aiZeroMvdMvpIdx[2] = {-1, -1};
3093  Int           aiZeroMvdRefIdx[2] = {0, 0};
3094  Int           iZeroMvdDir = -1;
3095#endif
3096
3097  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3098  {
3099    UInt          uiCost[2] = { MAX_UINT, MAX_UINT };
3100    UInt          uiCostBi  =   MAX_UINT;
3101    UInt          uiCostTemp;
3102
3103    UInt          uiBits[3];
3104    UInt          uiBitsTemp;
3105#if ZERO_MVD_EST
3106    UInt          uiZeroMvdCost = MAX_UINT;
3107    UInt          uiZeroMvdCostTemp;
3108    UInt          uiZeroMvdBitsTemp;
3109    UInt          uiZeroMvdDistTemp = MAX_UINT;
3110    UInt          auiZeroMvdBits[3];
3111#endif
3112
3113#if DCM_COMB_LIST
3114    UInt          uiCostTempL0[MAX_NUM_REF];
3115    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) uiCostTempL0[iNumRef] = MAX_UINT;
3116#endif
3117
3118    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
3119
3120    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3121
3122#if PART_MRG
3123    Bool bTestNormalMC = true;
3124    if (pcCU->getWidth( 0 ) > 8 && iNumPart == 2 && iPartIdx == 0)
3125      bTestNormalMC = false;
3126    if (bTestNormalMC)
3127    {
3128#endif
3129
3130    //  Uni-directional prediction
3131    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
3132    {
3133      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3134
3135      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
3136      {
3137#ifdef WEIGHT_PRED
3138        if ( eRefPicList == REF_PIC_LIST_0 ) setWpScalingDistParam( pcCU, iRefIdxTemp, -1 , eRefPicList);
3139        if ( eRefPicList == REF_PIC_LIST_1 ) setWpScalingDistParam( pcCU, -1, iRefIdxTemp , eRefPicList);
3140#endif
3141        uiBitsTemp = uiMbBits[iRefList];
3142        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3143        {
3144          uiBitsTemp += iRefIdxTemp+1;
3145          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3146        }
3147#if ZERO_MVD_EST
3148        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &uiZeroMvdDistTemp);
3149#else
3150        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp]);
3151#endif
3152        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
3153        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
3154
3155        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][aaiMvpNum[iRefList][iRefIdxTemp]];
3156#if ZERO_MVD_EST
3157#if DCM_COMB_LIST
3158        if ((iRefList != 1 || !pcCU->getSlice()->getNoBackPredFlag()) &&
3159            (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) <= 0 || pcCU->getSlice()->getRefIdxOfLC(eRefPicList, iRefIdxTemp)>=0))
3160#endif
3161        {
3162          uiZeroMvdBitsTemp = uiBitsTemp;
3163          uiZeroMvdBitsTemp += 2; //zero mvd bits
3164
3165          m_pcRdCost->getMotionCost( 1, 0 );
3166          uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost(uiZeroMvdBitsTemp);
3167
3168          if (uiZeroMvdCostTemp < uiZeroMvdCost)
3169          {
3170            uiZeroMvdCost = uiZeroMvdCostTemp;
3171            iZeroMvdDir = iRefList + 1;
3172            aiZeroMvdRefIdx[iRefList] = iRefIdxTemp;
3173            aiZeroMvdMvpIdx[iRefList] = aaiMvpIdx[iRefList][iRefIdxTemp];
3174            auiZeroMvdBits[iRefList] = uiZeroMvdBitsTemp;
3175          }
3176        }
3177#endif
3178
3179#if GPB_SIMPLE_UNI
3180#if DCM_COMB_LIST
3181        if ( pcCU->getSlice()->getSPS()->getUseLDC() || pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0)
3182#else
3183        if ( pcCU->getSlice()->getSPS()->getUseLDC() )
3184#endif
3185        {
3186#if DCM_COMB_LIST
3187          if ( iRefList && ( (pcCU->getSlice()->getSPS()->getUseLDC() && (iRefIdxTemp != iRefIdx[0])) || pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag() && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)>=0 ) ) )
3188#else
3189          if ( iRefList && ( iRefIdxTemp != iRefIdx[0] || pcCU->getSlice()->getNoBackPredFlag() ) )
3190#endif
3191            {
3192#if DCM_COMB_LIST
3193              if (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
3194              {
3195                uiCostTemp = uiCostTempL0[pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
3196              }
3197              else
3198              {
3199                uiCostTemp = MAX_UINT;
3200              }
3201#else
3202              uiCostTemp = MAX_UINT;
3203#endif
3204#if DCM_COMB_LIST
3205              if ( pcCU->getSlice()->getNoBackPredFlag() || pcCU->getSlice()->getSPS()->getUseLDC() )
3206#else
3207              if ( pcCU->getSlice()->getNoBackPredFlag() )
3208#endif
3209              {
3210                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3211              }
3212#if DCM_COMB_LIST
3213              else
3214              {
3215                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
3216              }
3217#endif
3218            }
3219            else
3220            {
3221              xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3222            }
3223        }
3224        else
3225        {
3226          if (iRefList && pcCU->getSlice()->getNoBackPredFlag())
3227          {
3228            uiCostTemp = MAX_UINT;
3229            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3230          }
3231          else
3232          {
3233            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3234          }
3235        }
3236#else
3237        xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3238#endif
3239        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
3240        if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3241        {
3242          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3243        }
3244
3245#if DCM_COMB_LIST
3246        if(pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
3247        {
3248          if(iRefList==REF_PIC_LIST_0)
3249          {
3250            uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3251            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_0, iRefIdxTemp)<0)
3252            {
3253              uiCostTemp = MAX_UINT;
3254            }
3255          }
3256          else
3257          {
3258            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_1, iRefIdxTemp)<0)
3259            {
3260              uiCostTemp = MAX_UINT;
3261            }
3262          }
3263        }
3264#endif
3265
3266        if ( ( iRefList == 0 && uiCostTemp < uiCost[iRefList] ) ||
3267            ( iRefList == 1 &&  pcCU->getSlice()->getNoBackPredFlag() && iRefIdxTemp == iRefIdx[0] ) ||
3268#if DCM_COMB_LIST
3269            ( iRefList == 1 && (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0) && (iRefIdxTemp==0 || iRefIdxTemp == iRefIdx[0]) && !pcCU->getSlice()->getNoBackPredFlag() && (iRefIdxTemp == pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)) ) ||
3270#endif
3271            ( iRefList == 1 && !pcCU->getSlice()->getNoBackPredFlag() && uiCostTemp < uiCost[iRefList] ) )
3272          {
3273            uiCost[iRefList] = uiCostTemp;
3274            uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3275
3276            // set motion
3277            cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3278            iRefIdx[iRefList] = iRefIdxTemp;
3279            pcCU->getCUMvField(eRefPicList)->setAllMvField( cMv[iRefList], iRefIdx[iRefList], ePartSize, uiPartAddr, iPartIdx, 0 );
3280
3281            // storing list 1 prediction signal for iterative bi-directional prediction
3282            if ( eRefPicList == REF_PIC_LIST_1 )
3283            {
3284              TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3285              motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3286            }
3287#if DCM_COMB_LIST
3288            if ( (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) && eRefPicList == REF_PIC_LIST_0 )
3289#else
3290            if ( pcCU->getSlice()->getNoBackPredFlag() && eRefPicList == REF_PIC_LIST_0 )
3291#endif
3292            {
3293              TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3294              motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3295            }
3296          }
3297      }
3298    }
3299    //  Bi-directional prediction
3300    if ( pcCU->getSlice()->isInterB() )
3301    {
3302
3303      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
3304      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
3305
3306      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
3307      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
3308
3309      UInt uiMotBits[2] = { uiBits[0] - uiMbBits[0], uiBits[1] - uiMbBits[1] };
3310      uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3311
3312      // 4-times iteration (default)
3313      Int iNumIter = 4;
3314
3315      // fast encoder setting: only one iteration
3316      if ( m_pcEncCfg->getUseFastEnc() )
3317      {
3318        iNumIter = 1;
3319      }
3320
3321      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3322      {
3323
3324        Int         iRefList    = iIter % 2;
3325#if DCM_COMB_LIST
3326        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3327#else
3328        if ( m_pcEncCfg->getUseFastEnc() && pcCU->getSlice()->getNoBackPredFlag() )
3329#endif
3330        {
3331          iRefList = 1;
3332        }
3333        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3334
3335        Bool bChanged = false;
3336
3337#if GPB_SIMPLE
3338        if ( pcCU->getSlice()->getSPS()->getUseLDC() && iRefList )
3339        {
3340          iRefStart = iRefIdxBi[1-iRefList];
3341          iRefEnd   = iRefIdxBi[1-iRefList];
3342        }
3343        else
3344        {
3345          iRefStart = 0;
3346          iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3347        }
3348#else
3349        iRefStart = 0;
3350        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3351#endif
3352
3353#if DCM_COMB_LIST
3354        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3355#else
3356        if ( m_pcEncCfg->getUseFastEnc() && pcCU->getSlice()->getNoBackPredFlag() )
3357#endif
3358        {
3359          iRefStart = 0;
3360          iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3361        }
3362
3363        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3364        {
3365#ifdef WEIGHT_PRED
3366          if ( eRefPicList == REF_PIC_LIST_0 ) setWpScalingDistParam( pcCU, iRefIdxTemp, -1 , eRefPicList);
3367          if ( eRefPicList == REF_PIC_LIST_1 ) setWpScalingDistParam( pcCU, -1, iRefIdxTemp , eRefPicList);
3368#endif
3369          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3370          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3371          {
3372            uiBitsTemp += iRefIdxTemp+1;
3373            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3374          }
3375
3376          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][aaiMvpNum[iRefList][iRefIdxTemp]];
3377          // call ME
3378          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3379          if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3380          {
3381            xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3382            xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3383          }
3384
3385          if ( uiCostTemp < uiCostBi )
3386          {
3387            bChanged = true;
3388
3389            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3390            iRefIdxBi[iRefList] = iRefIdxTemp;
3391
3392            uiCostBi            = uiCostTemp;
3393            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3394            uiBits[2]           = uiBitsTemp;
3395
3396            //  Set motion
3397            pcCU->getCUMvField( eRefPicList )->setAllMvField( cMvBi[iRefList], iRefIdxBi[iRefList], ePartSize, uiPartAddr, iPartIdx, 0 );
3398
3399            TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3400            motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3401          }
3402        } // for loop-iRefIdxTemp
3403
3404        if ( !bChanged )
3405        {
3406          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3407          {
3408            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3409            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3410            xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3411            xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3412          }
3413          break;
3414        }
3415      } // for loop-iter
3416    } // if (B_SLICE)
3417#if ZERO_MVD_EST
3418    if ( pcCU->getSlice()->isInterB() )
3419    {
3420      m_pcRdCost->getMotionCost( 1, 0 );
3421
3422      for ( Int iL0RefIdxTemp = 0; iL0RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1; iL0RefIdxTemp++ )
3423      for ( Int iL1RefIdxTemp = 0; iL1RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1; iL1RefIdxTemp++ )
3424      {
3425        UInt uiRefIdxBitsTemp = 0;
3426        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 1 )
3427        {
3428          uiRefIdxBitsTemp += iL0RefIdxTemp+1;
3429          if ( iL0RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1 ) uiRefIdxBitsTemp--;
3430        }
3431        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3432        {
3433          uiRefIdxBitsTemp += iL1RefIdxTemp+1;
3434          if ( iL1RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiRefIdxBitsTemp--;
3435        }
3436
3437        Int iL0MVPIdx = 0;
3438        Int iL1MVPIdx = 0;
3439
3440        for (iL0MVPIdx = 0; iL0MVPIdx < aaiMvpNum[0][iL0RefIdxTemp]; iL0MVPIdx++)
3441        {
3442          for (iL1MVPIdx = 0; iL1MVPIdx < aaiMvpNum[1][iL1RefIdxTemp]; iL1MVPIdx++)
3443          {
3444            uiZeroMvdBitsTemp = uiRefIdxBitsTemp;
3445            uiZeroMvdBitsTemp += uiMbBits[2];
3446            uiZeroMvdBitsTemp += m_auiMVPIdxCost[iL0MVPIdx][aaiMvpNum[0][iL0RefIdxTemp]] + m_auiMVPIdxCost[iL1MVPIdx][aaiMvpNum[1][iL1RefIdxTemp]];
3447            uiZeroMvdBitsTemp += 4; //zero mvd for both directions
3448            pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( aacAMVPInfo[0][iL0RefIdxTemp].m_acMvCand[iL0MVPIdx], iL0RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3449            pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( aacAMVPInfo[1][iL1RefIdxTemp].m_acMvCand[iL1MVPIdx], iL1RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3450
3451            xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiZeroMvdDistTemp, m_pcEncCfg->getUseHADME() );
3452            uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost( uiZeroMvdBitsTemp );
3453            if (uiZeroMvdCostTemp < uiZeroMvdCost)
3454            {
3455              uiZeroMvdCost = uiZeroMvdCostTemp;
3456              iZeroMvdDir = 3;
3457              aiZeroMvdMvpIdx[0] = iL0MVPIdx;
3458              aiZeroMvdMvpIdx[1] = iL1MVPIdx;
3459              aiZeroMvdRefIdx[0] = iL0RefIdxTemp;
3460              aiZeroMvdRefIdx[1] = iL1RefIdxTemp;
3461              auiZeroMvdBits[2] = uiZeroMvdBitsTemp;
3462            }
3463          }
3464        }
3465      }
3466    }
3467#endif
3468#if PART_MRG
3469    } //end if bTestNormalMC
3470#endif
3471    //  Clear Motion Field
3472    {
3473      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvZero, NOT_VALID, ePartSize, uiPartAddr, iPartIdx, 0 );
3474      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvZero, NOT_VALID, ePartSize, uiPartAddr, iPartIdx, 0 );
3475    }
3476    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3477    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3478
3479    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3480    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3481    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3482    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3483
3484    UInt uiMEBits = 0;
3485    // Set Motion Field_
3486#if DCM_COMB_LIST
3487    if ( pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 ) )
3488#else
3489    if ( pcCU->getSlice()->getNoBackPredFlag() )
3490#endif
3491    {
3492      uiCost[1] = MAX_UINT;
3493    }
3494#if PART_MRG
3495    if (bTestNormalMC)
3496    {
3497#endif
3498#if ZERO_MVD_EST
3499    if (uiZeroMvdCost <= uiCostBi && uiZeroMvdCost <= uiCost[0] && uiZeroMvdCost <= uiCost[1])
3500    {
3501      if (iZeroMvdDir == 3)
3502      {
3503        uiLastMode = 2;
3504
3505        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3506        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3507
3508        pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3509
3510        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3511        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3512        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3513        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3514        uiMEBits = auiZeroMvdBits[2];
3515      }
3516      else if (iZeroMvdDir == 1)
3517      {
3518        uiLastMode = 0;
3519
3520        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3521
3522        pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3523
3524        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3525        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3526        uiMEBits = auiZeroMvdBits[0];
3527      }
3528      else if (iZeroMvdDir == 2)
3529      {
3530        uiLastMode = 1;
3531
3532        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3533
3534        pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3535
3536        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3537        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3538        uiMEBits = auiZeroMvdBits[1];
3539      }
3540      else
3541      {
3542        assert(0);
3543      }
3544    }
3545    else
3546#endif
3547    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3548    {
3549      uiLastMode = 2;
3550      {
3551        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvBi[0], iRefIdxBi[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3552        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvBi[1], iRefIdxBi[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3553      }
3554      {
3555        TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3556        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3557#if DCM_SIMPLIFIED_MVP==0
3558        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[0][iRefIdxBi[0]]))
3559        {
3560          aaiMvpIdxBi[0][iRefIdxBi[0]] = pcCU->searchMVPIdx(cMvPredBi[0][iRefIdxBi[0]], &aacAMVPInfo[0][iRefIdxBi[0]]);
3561          aaiMvpNum[0][iRefIdxBi[0]] = aacAMVPInfo[0][iRefIdxBi[0]].iN;
3562        }
3563#endif
3564      }
3565      {
3566        TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3567        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3568#if DCM_SIMPLIFIED_MVP==0
3569        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[1][iRefIdxBi[1]]))
3570        {
3571          aaiMvpIdxBi[1][iRefIdxBi[1]] = pcCU->searchMVPIdx(cMvPredBi[1][iRefIdxBi[1]], &aacAMVPInfo[1][iRefIdxBi[1]]);
3572          aaiMvpNum[1][iRefIdxBi[1]] = aacAMVPInfo[1][iRefIdxBi[1]].iN;
3573        }
3574#endif
3575      }
3576
3577      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3578
3579      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3580      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3581      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3582      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3583
3584      uiMEBits = uiBits[2];
3585    }
3586    else if ( uiCost[0] <= uiCost[1] )
3587    {
3588      uiLastMode = 0;
3589      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMv[0],   iRefIdx[0],   ePartSize, uiPartAddr, iPartIdx, 0 );
3590
3591      {
3592        TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3593        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3594#if DCM_SIMPLIFIED_MVP==0
3595        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[0][iRefIdx[0]]))
3596        {
3597          aaiMvpIdx[0][iRefIdx[0]] = pcCU->searchMVPIdx(cMvPred[0][iRefIdx[0]], &aacAMVPInfo[0][iRefIdx[0]]);
3598          aaiMvpNum[0][iRefIdx[0]] = aacAMVPInfo[0][iRefIdx[0]].iN;
3599        }
3600#endif
3601      }
3602      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3603
3604      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3605      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3606
3607      uiMEBits = uiBits[0];
3608    }
3609    else
3610    {
3611      uiLastMode = 1;
3612      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMv[1],   iRefIdx[1],   ePartSize, uiPartAddr, iPartIdx, 0 );
3613
3614      {
3615        TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3616        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3617#if DCM_SIMPLIFIED_MVP==0
3618        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[1][iRefIdx[1]]))
3619        {
3620          aaiMvpIdx[1][iRefIdx[1]] = pcCU->searchMVPIdx(cMvPred[1][iRefIdx[1]], &aacAMVPInfo[1][iRefIdx[1]]);
3621          aaiMvpNum[1][iRefIdx[1]] = aacAMVPInfo[1][iRefIdx[1]].iN;
3622        }
3623#endif
3624      }
3625      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3626
3627      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3628      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3629
3630      uiMEBits = uiBits[1];
3631    }
3632#if PART_MRG
3633    } // end if bTestNormalMC
3634#endif
3635
3636    if ( pcCU->getSlice()->getSPS()->getUseMRG() && pcCU->getPartitionSize( uiPartAddr ) == SIZE_2Nx2N )
3637    {
3638      UChar       uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
3639      UInt        uiNeighbourCandIdx  [MRG_MAX_NUM_CANDS];
3640      TComMvField cMvFieldNeighbours  [MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
3641      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3642      {
3643        uhInterDirNeighbours[ui] = 0;
3644        uiNeighbourCandIdx  [ui] = 0;
3645      }
3646      pcCU->getInterMergeCandidates( uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ), cMvFieldNeighbours, uhInterDirNeighbours, uiNeighbourCandIdx );
3647      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3648      {
3649        pcCU->setNeighbourCandIdxSubParts( ui, uiNeighbourCandIdx[ui], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3650      }
3651    }
3652
3653    if ( pcCU->getSlice()->getSPS()->getUseMRG() && pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3654    {
3655      UInt uiMRGInterDir = 0;
3656      TComMvField cMRGMvField[2];
3657      UInt uiMRGIndex = 0;
3658
3659      UInt uiMEInterDir = 0;
3660      TComMvField cMEMvField[2];
3661
3662      m_pcRdCost->getMotionCost( 1, 0 );
3663#if PART_MRG
3664      // calculate ME cost
3665      UInt uiMEError = MAX_UINT;
3666      UInt uiMECost = MAX_UINT;
3667
3668      if (bTestNormalMC)
3669      {
3670        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3671        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3672      }
3673#else
3674      // calculate ME cost
3675      UInt uiMEError = MAX_UINT;
3676      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3677      UInt uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3678#endif
3679      // save ME result.
3680      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3681      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3682      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3683
3684      // find Merge result
3685      UInt uiMRGError = MAX_UINT;
3686      UInt uiMRGBits = MAX_UINT;
3687      Bool bMergeValid = false;
3688      UChar ucNeighCand[MRG_MAX_NUM_CANDS];
3689      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3690      {
3691        ucNeighCand[ui] = 0;
3692      }
3693      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGError, uiMRGBits, ucNeighCand, bMergeValid );
3694      UInt uiMRGCost = uiMRGError + m_pcRdCost->getCost( uiMRGBits );
3695
3696      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3697      {
3698        pcCU->setNeighbourCandIdxSubParts( ui, ucNeighCand[ui], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3699      }
3700      if ( bMergeValid && uiMRGCost < uiMECost )
3701      {
3702        // set Merge result
3703        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3704        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3705        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3706
3707#if POZNAN_EIVD_CALC_PRED_DATA
3708                if(uiMRGIndex==POZNAN_EIVD_MRG_CAND)
3709                {
3710                        TComCUMvField* pcEIVDPredMvField;
3711                        pcEIVDPredMvField = pcCU->getSlice()->getMP()->getEIVDPredMVField(REF_PIC_LIST_0);
3712                        pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( pcEIVDPredMvField->getMv(0), pcEIVDPredMvField->getRefIdx(0), ePartSize, uiPartAddr, iPartIdx, 0 );                       
3713                        pcEIVDPredMvField = pcCU->getSlice()->getMP()->getEIVDPredMVField(REF_PIC_LIST_1);
3714                        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( pcEIVDPredMvField->getMv(0), pcEIVDPredMvField->getRefIdx(0), ePartSize, uiPartAddr, iPartIdx, 0 );
3715
3716                        pcCU->getCUMvField2nd( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0].getMv(), cMRGMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3717                        pcCU->getCUMvField2nd( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1].getMv(), cMRGMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3718                }
3719                else
3720#endif
3721        {
3722          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0].getMv(), cMRGMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3723          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1].getMv(), cMRGMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3724        }
3725
3726        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3727        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3728        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3729        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3730        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3731        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3732      }
3733      else
3734      {
3735        // set ME result
3736        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3737        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3738        {
3739          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0].getMv(), cMEMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3740          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1].getMv(), cMEMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3741        }
3742      }
3743#if PART_MRG
3744      if (!bTestNormalMC && !bMergeValid)
3745      {
3746        assert(pcCU->getWidth( 0 ) > 8 && iNumPart == 2 && iPartIdx == 0);
3747        return;
3748      }
3749#endif
3750    }
3751
3752    //  MC
3753    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
3754
3755  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3756
3757#ifdef WEIGHT_PRED
3758  setWpScalingDistParam( pcCU, -1, -1, REF_PIC_LIST_X );
3759#endif
3760  return;
3761}
3762
3763// AMVP
3764#if ZERO_MVD_EST
3765Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDist )
3766#else
3767Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled )
3768#endif
3769{
3770  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3771
3772  TComMv  cBestMv;
3773  Int     iBestIdx = 0;
3774  TComMv  cZeroMv;
3775  TComMv  cMvPred;
3776  UInt    uiBestCost = MAX_INT;
3777  UInt    uiPartAddr = 0;
3778  Int     iRoiWidth, iRoiHeight;
3779  Int     i;
3780
3781  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3782  // Fill the MV Candidates
3783  if (!bFilled)
3784  {
3785    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
3786  }
3787
3788  // initialize Mvp index & Mvp
3789  iBestIdx = 0;
3790  cBestMv  = pcAMVPInfo->m_acMvCand[0];
3791#if !ZERO_MVD_EST
3792  if( pcCU->getAMVPMode(uiPartAddr) == AM_NONE || (pcAMVPInfo->iN <= 1 && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL) )
3793  {
3794    rcMvPred = cBestMv;
3795
3796    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3797    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3798    return;
3799  }
3800#endif
3801  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL && bFilled)
3802  {
3803    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
3804    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
3805    return;
3806  }
3807
3808  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL)
3809  {
3810    m_cYuvPredTemp.clear();
3811#if ZERO_MVD_EST
3812    UInt uiDist;
3813#endif
3814    //-- Check Minimum Cost.
3815    for ( i = 0 ; i < pcAMVPInfo->iN; i++)
3816    {
3817      UInt uiTmpCost;
3818#if ZERO_MVD_EST
3819      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, pcAMVPInfo->iN, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3820#else
3821      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, pcAMVPInfo->iN, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3822#endif
3823      if ( uiBestCost > uiTmpCost )
3824      {
3825        uiBestCost = uiTmpCost;
3826        cBestMv   = pcAMVPInfo->m_acMvCand[i];
3827        iBestIdx  = i;
3828        #if ZERO_MVD_EST
3829        (*puiDist) = uiDist;
3830        #endif
3831      }
3832    }
3833
3834    m_cYuvPredTemp.clear();
3835  }
3836
3837  // Setting Best MVP
3838  rcMvPred = cBestMv;
3839  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3840  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3841  return;
3842}
3843
3844UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
3845{
3846  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
3847
3848  if (iNum == 1)
3849    return 0;
3850
3851  UInt uiLength = 1;
3852  Int iTemp = iIdx;
3853  if ( iTemp == 0 )
3854  {
3855    return uiLength;
3856  }
3857
3858  Bool bCodeLast = ( iNum-1 > iTemp );
3859
3860  uiLength += (iTemp-1);
3861
3862  if( bCodeLast )
3863  {
3864    uiLength++;
3865  }
3866
3867  return uiLength;
3868}
3869
3870Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
3871{
3872  if ( eCUMode == SIZE_2Nx2N )
3873  {
3874    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3875    uiBlkBit[1] = 3;
3876    uiBlkBit[2] = 5;
3877  }
3878  else if ( eCUMode == SIZE_2NxN )
3879  {
3880    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} } };
3881    if ( bPSlice )
3882    {
3883      uiBlkBit[0] = 3;
3884      uiBlkBit[1] = 0;
3885      uiBlkBit[2] = 0;
3886    }
3887    else
3888    {
3889      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3890    }
3891  }
3892  else if ( eCUMode == SIZE_Nx2N )
3893  {
3894    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} } };
3895    if ( bPSlice )
3896    {
3897      uiBlkBit[0] = 3;
3898      uiBlkBit[1] = 0;
3899      uiBlkBit[2] = 0;
3900    }
3901    else
3902    {
3903      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3904    }
3905  }
3906  else if ( eCUMode == SIZE_NxN )
3907  {
3908    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3909    uiBlkBit[1] = 3;
3910    uiBlkBit[2] = 5;
3911  }
3912  else
3913  {
3914    printf("Wrong!\n");
3915    assert( 0 );
3916  }
3917}
3918
3919Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
3920{
3921  pDst->iN = pSrc->iN;
3922  for (Int i = 0; i < pSrc->iN; i++)
3923  {
3924    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
3925  }
3926}
3927
3928Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, UInt& ruiCost )
3929{
3930  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3931
3932  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
3933
3934  if (pcAMVPInfo->iN < 2) return;
3935
3936  m_pcRdCost->getMotionCost( 1, 0 );
3937  m_pcRdCost->setCostScale ( 0    );
3938
3939  Int iBestMVPIdx = riMVPIdx;
3940
3941  m_pcRdCost->setPredictor( rcMvPred );
3942  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3943  Int iBestMvBits = iOrgMvBits;
3944
3945  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
3946  {
3947    if (iMVPIdx == riMVPIdx) continue;
3948
3949    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
3950
3951    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3952
3953    if (iMvBits < iBestMvBits)
3954    {
3955      iBestMvBits = iMvBits;
3956      iBestMVPIdx = iMVPIdx;
3957    }
3958  }
3959
3960  if (iBestMVPIdx != riMVPIdx)  //if changed
3961  {
3962    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
3963
3964    iOrgMvBits  += m_auiMVPIdxCost[riMVPIdx][pcAMVPInfo->iN];
3965    iBestMvBits += m_auiMVPIdxCost[iBestMVPIdx][pcAMVPInfo->iN];
3966
3967    riMVPIdx = iBestMVPIdx;
3968    UInt uiOrgBits = ruiBits;
3969    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
3970    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
3971  }
3972}
3973
3974UInt TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
3975                                  UInt        uiPartIdx,
3976                                  UInt      uiPartAddr,
3977                                  TComYuv*    pcOrgYuv,
3978                                  TComYuv*    pcTemplateCand,
3979                                  TComMv      cMvCand,
3980                                  Int         iMVPIdx,
3981                                  Int     iMVPNum,
3982                                  RefPicList  eRefPicList,
3983                                  Int         iRefIdx,
3984                                  Int         iSizeX,
3985                                  Int         iSizeY
3986                               #if ZERO_MVD_EST
3987                                , UInt&       ruiDist
3988                               #endif
3989                                  )
3990{
3991  UInt uiCost  = MAX_INT;
3992
3993  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
3994
3995  // prediction pattern
3996  xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand );
3997
3998#ifdef WEIGHT_PRED
3999  if ( pcCU->getSlice()->getPPS()->getUseWP() )
4000  {
4001    PartSize  ePartSize = pcCU->getPartitionSize( 0 );
4002    pcCU->getCUMvField(eRefPicList)->setAllMvField( cMvCand, iRefIdx, ePartSize, uiPartAddr, uiPartIdx, 0 );
4003#if 0
4004    TComMvField mvField;
4005    mvField.setMvField( cMvCand, iRefIdx);
4006    pcCU->getCUMvField(eRefPicList)->setAllMvField( mvField, ePartSize, uiPartAddr, 0 );
4007#endif
4008    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, uiPartIdx );
4009  }
4010#endif
4011
4012  // calc distortion
4013#if ZERO_MVD_EST
4014  m_pcRdCost->getMotionCost( 1, 0 );
4015  DistParam cDistParam;
4016  m_pcRdCost->setDistParam( cDistParam,
4017                            pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(),
4018                            pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(),
4019                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME() );
4020  // MW: check VSO here
4021  ruiDist = cDistParam.DistFunc( &cDistParam );
4022  uiCost = ruiDist + m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] );
4023#else
4024#if HHI_VSO
4025  if ( false /*m_pcRdCost->getUseVSO()*/ ) // GT: currently disabled
4026  {
4027    uiCost = m_pcRdCost->getDistVS  ( pcCU, uiPartAddr,  pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, true, 0);
4028    uiCost = (UInt) m_pcRdCost->calcRdCostVSO( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
4029  }
4030  else
4031#endif
4032  {
4033    uiCost = m_pcRdCost->getDistPart( pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, DF_SAD );
4034    uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
4035  }
4036#endif
4037  return uiCost;
4038}
4039
4040Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, UInt& ruiCost, Bool bBi  )
4041{
4042  UInt          uiPartAddr;
4043  Int           iRoiWidth;
4044  Int           iRoiHeight;
4045
4046  TComMv        cMvHalf, cMvQter;
4047  TComMv        cMvSrchRngLT;
4048  TComMv        cMvSrchRngRB;
4049
4050  TComYuv*      pcYuv = pcYuvOrg;
4051#ifdef ROUNDING_CONTROL_BIPRED
4052  Pel           pRefBufY[16384];  // 128x128
4053#endif
4054  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
4055
4056  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
4057  TComPattern*  pcPatternKey  = pcCU->getPattern        ();
4058
4059  Double        fWeight       = 1.0;
4060
4061  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
4062
4063  if ( bBi )
4064  {
4065    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
4066    pcYuv                = &m_cYuvPredTemp;
4067
4068    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
4069
4070#ifdef ROUNDING_CONTROL_BIPRED
4071    Int y;
4072    //Int x;
4073    Pel *pRefY = pcYuvOther->getLumaAddr(uiPartAddr);
4074    Int iRefStride = pcYuvOther->getStride();
4075
4076    // copy the MC block into pRefBufY
4077    for( y = 0; y < iRoiHeight; y++)
4078    {
4079      memcpy(pRefBufY+y*iRoiWidth,pRefY,sizeof(Pel)*iRoiWidth);
4080      pRefY += iRefStride;
4081    }
4082#else
4083    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight );
4084#endif
4085
4086    fWeight = 0.5;
4087  }
4088
4089  //  Search key pattern initialization
4090  pcPatternKey->initPattern( pcYuv->getLumaAddr( uiPartAddr ),
4091                            pcYuv->getCbAddr  ( uiPartAddr ),
4092                            pcYuv->getCrAddr  ( uiPartAddr ),
4093                            iRoiWidth,
4094                            iRoiHeight,
4095                            pcYuv->getStride(),
4096                            0, 0, 0, 0 );
4097
4098  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr );
4099  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride();
4100
4101  TComMv      cMvPred = *pcMvPred;
4102
4103  if ( bBi )  xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4104  else        xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4105
4106  m_pcRdCost->getMotionCost ( 1, 0 );
4107
4108  m_pcRdCost->setPredictor  ( *pcMvPred );
4109#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4110  if( pcCU->getSlice()->getSPS()->isDepth() )
4111    m_pcRdCost->setCostScale  ( 0 );
4112  else
4113#endif
4114  m_pcRdCost->setCostScale  ( 2 );
4115
4116#if HHI_INTER_VIEW_MOTION_PRED
4117  { // init inter-view regularization
4118    TComMv  cOrgDepthMapMv;
4119    Bool    bMultiviewReg = pcCU->getIViewOrgDepthMvPred( iPartIdx, eRefPicList, iRefIdxPred, cOrgDepthMapMv );
4120#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4121    if( bMultiviewReg && pcCU->getSlice()->getSPS()->isDepth() )
4122    {
4123      cOrgDepthMapMv += TComMv( 2, 2 );
4124      cOrgDepthMapMv >>= 2;
4125    }
4126#endif
4127    m_pcRdCost->setMultiviewReg( bMultiviewReg ? &cOrgDepthMapMv : 0 );
4128    if( bMultiviewReg && !bBi )
4129    {
4130      xSetSearchRange( pcCU, cOrgDepthMapMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4131    }
4132  }
4133#endif
4134
4135  //  Do integer search
4136#ifdef ROUNDING_CONTROL_BIPRED
4137  if( bBi )
4138  {
4139    xPatternSearch_Bi      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost, pRefBufY, pcCU->getSlice()->isRounding() );
4140  }
4141  else
4142  {
4143    if ( !m_iFastSearch)
4144    {
4145      xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4146    }
4147    else
4148    {
4149      rcMv = *pcMvPred;
4150      xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4151    }
4152  }
4153#else
4154  if ( !m_iFastSearch || bBi )
4155  {
4156    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4157  }
4158  else
4159  {
4160    rcMv = ( m_pcRdCost->useMultiviewReg() ? m_pcRdCost->getMultiviewOrgMvPred() : *pcMvPred );
4161    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4162  }
4163#endif
4164
4165
4166  m_pcRdCost->getMotionCost( 1, 0 );
4167#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4168  if( ! pcCU->getSlice()->getSPS()->isDepth() )
4169  {
4170#endif
4171  m_pcRdCost->setCostScale ( 1 );
4172
4173#ifdef ROUNDING_CONTROL_BIPRED
4174  if( bBi )
4175  {
4176    Bool bRound =  pcCU->getSlice()->isRounding() ;
4177    xPatternSearchFracDIF_Bi( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost, pRefBufY, bRound );
4178  }
4179  else
4180#endif
4181  {
4182    xPatternSearchFracDIF( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
4183  }
4184
4185
4186
4187  m_pcRdCost->setCostScale( 0 );
4188  rcMv <<= 2;
4189  rcMv += (cMvHalf <<= 1);
4190  rcMv +=  cMvQter;
4191#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4192  }
4193#endif
4194
4195  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
4196#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4197  if( pcCU->getSlice()->getSPS()->isDepth() )
4198    ruiCost += m_pcRdCost->getCost( uiMvBits );
4199#endif
4200
4201  ruiBits   += uiMvBits;
4202  ruiCost       = (UInt)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
4203}
4204
4205
4206Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
4207{
4208  Int  iMvShift = 2;
4209#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4210  if( pcCU->getSlice()->getSPS()->isDepth() )
4211    iMvShift = 0;
4212#endif
4213  pcCU->clipMv( cMvPred );
4214
4215  rcMvSrchRngLT.setHor( cMvPred.getHor() - (iSrchRng << iMvShift) );
4216  rcMvSrchRngLT.setVer( cMvPred.getVer() - (iSrchRng << iMvShift) );
4217
4218  rcMvSrchRngRB.setHor( cMvPred.getHor() + (iSrchRng << iMvShift) );
4219  rcMvSrchRngRB.setVer( cMvPred.getVer() + (iSrchRng << iMvShift) );
4220
4221  pcCU->clipMv        ( rcMvSrchRngLT );
4222  pcCU->clipMv        ( rcMvSrchRngRB );
4223
4224  rcMvSrchRngLT >>= iMvShift;
4225  rcMvSrchRngRB >>= iMvShift;
4226}
4227
4228#ifdef ROUNDING_CONTROL_BIPRED
4229Void TEncSearch::xPatternSearch_Bi( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD, Pel* pcRefY2, Bool bRound )
4230{
4231  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4232  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4233  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4234  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4235
4236  UInt  uiSad;
4237  Dist  uiSadBest         = RDO_DIST_MAX;
4238  Int   iBestX = 0;
4239  Int   iBestY = 0;
4240
4241  Pel*  piRefSrch;
4242
4243  //-- jclee for using the SAD function pointer
4244  m_pcRdCost->setDistParam_Bi( pcPatternKey, piRefY, iRefStride,  m_cDistParam);
4245
4246  // fast encoder decision: use subsampled SAD for integer ME
4247  if ( m_pcEncCfg->getUseFastEnc() )
4248  {
4249    if ( m_cDistParam.iRows > 8 )
4250    {
4251      m_cDistParam.iSubShift = 1;
4252    }
4253  }
4254
4255  piRefY += (iSrchRngVerTop * iRefStride);
4256  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4257  {
4258    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4259    {
4260      //  find min. distortion position
4261      piRefSrch = piRefY + x;
4262      m_cDistParam.pCur = piRefSrch;
4263      uiSad = m_cDistParam.DistFuncRnd( &m_cDistParam, pcRefY2, bRound );
4264
4265      // motion cost
4266      uiSad += m_pcRdCost->getCost( x, y );
4267
4268      // regularization cost
4269      if( m_pcRdCost->useMultiviewReg() )
4270      {
4271        uiSad += m_pcRdCost->getMultiviewRegCost( x, y );
4272      }
4273
4274      if ( uiSad < uiSadBest )
4275      {
4276        uiSadBest = uiSad;
4277        iBestX    = x;
4278        iBestY    = y;
4279      }
4280    }
4281    piRefY += iRefStride;
4282  }
4283
4284  rcMv.set( iBestX, iBestY );
4285  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4286  return;
4287}
4288#endif
4289
4290Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4291{
4292  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4293  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4294  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4295  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4296
4297  UInt  uiSad;
4298  UInt  uiSadBest         = MAX_UINT;
4299  Int   iBestX = 0;
4300  Int   iBestY = 0;
4301
4302  Pel*  piRefSrch;
4303
4304  //-- jclee for using the SAD function pointer
4305  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
4306
4307  // fast encoder decision: use subsampled SAD for integer ME
4308  if ( m_pcEncCfg->getUseFastEnc() )
4309  {
4310    if ( m_cDistParam.iRows > 8 )
4311    {
4312      m_cDistParam.iSubShift = 1;
4313    }
4314  }
4315
4316  piRefY += (iSrchRngVerTop * iRefStride);
4317  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4318  {
4319    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4320    {
4321      //  find min. distortion position
4322      piRefSrch = piRefY + x;
4323      m_cDistParam.pCur = piRefSrch;
4324#ifdef WEIGHT_PRED
4325      setDistParamComp(0);
4326#endif
4327      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
4328
4329      // motion cost
4330      uiSad += m_pcRdCost->getCost( x, y );
4331
4332      // regularization cost
4333      if( m_pcRdCost->useMultiviewReg() )
4334      {
4335        uiSad += m_pcRdCost->getMultiviewRegCost( x, y );
4336      }
4337
4338      if ( uiSad < uiSadBest )
4339      {
4340        uiSadBest = uiSad;
4341        iBestX    = x;
4342        iBestY    = y;
4343      }
4344    }
4345    piRefY += iRefStride;
4346  }
4347
4348  rcMv.set( iBestX, iBestY );
4349
4350  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4351  return;
4352}
4353
4354Void TEncSearch::xPatternSearchFast( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4355{
4356  pcCU->getMvPredLeft       ( m_acMvPredictors[0] );
4357  pcCU->getMvPredAbove      ( m_acMvPredictors[1] );
4358  pcCU->getMvPredAboveRight ( m_acMvPredictors[2] );
4359
4360  switch ( m_iFastSearch )
4361  {
4362    case 1:
4363      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD );
4364      break;
4365
4366    default:
4367      break;
4368  }
4369}
4370
4371Void TEncSearch::xTZSearch( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4372{
4373  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4374  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4375  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4376  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4377
4378  TZ_SEARCH_CONFIGURATION
4379
4380  UInt uiSearchRange = m_iSearchRange;
4381  pcCU->clipMv( rcMv );
4382#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4383  if( ! pcCU->getSlice()->getSPS()->isDepth() )
4384#endif
4385  rcMv >>= 2;
4386  // init TZSearchStruct
4387  IntTZSearchStruct cStruct;
4388  cStruct.iYStride    = iRefStride;
4389  cStruct.piRefY      = piRefY;
4390  cStruct.uiBestSad   = MAX_UINT;
4391
4392  // set rcMv (Median predictor) as start point and as best point
4393  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4394
4395  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4396  if ( bTestOtherPredictedMV )
4397  {
4398    for ( UInt index = 0; index < 3; index++ )
4399    {
4400      TComMv cMv = m_acMvPredictors[index];
4401      pcCU->clipMv( cMv );
4402#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4403      if( ! pcCU->getSlice()->getSPS()->isDepth() )
4404#endif
4405      cMv >>= 2;
4406      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4407    }
4408  }
4409
4410  // test whether zero Mv is better start point than Median predictor
4411  if ( bTestZeroVector )
4412  {
4413    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4414  }
4415
4416  // start search
4417  Int  iDist = 0;
4418  Int  iStartX = cStruct.iBestX;
4419  Int  iStartY = cStruct.iBestY;
4420
4421  // first search
4422  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4423  {
4424    if ( bFirstSearchDiamond == 1 )
4425    {
4426      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4427    }
4428    else
4429    {
4430      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4431    }
4432
4433    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4434    {
4435      break;
4436    }
4437  }
4438
4439  // test whether zero Mv is a better start point than Median predictor
4440  if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4441  {
4442    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4443    if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4444    {
4445      // test its neighborhood
4446      for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4447      {
4448        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
4449        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4450        {
4451          break;
4452        }
4453      }
4454    }
4455  }
4456
4457  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4458  if ( cStruct.uiBestDistance == 1 )
4459  {
4460    cStruct.uiBestDistance = 0;
4461    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4462  }
4463
4464  // raster search if distance is too big
4465  if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4466  {
4467    cStruct.uiBestDistance = iRaster;
4468    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4469    {
4470      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4471      {
4472        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4473      }
4474    }
4475  }
4476
4477  // raster refinement
4478  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4479  {
4480    while ( cStruct.uiBestDistance > 0 )
4481    {
4482      iStartX = cStruct.iBestX;
4483      iStartY = cStruct.iBestY;
4484      if ( cStruct.uiBestDistance > 1 )
4485      {
4486        iDist = cStruct.uiBestDistance >>= 1;
4487        if ( bRasterRefinementDiamond == 1 )
4488        {
4489          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4490        }
4491        else
4492        {
4493          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4494        }
4495      }
4496
4497      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4498      if ( cStruct.uiBestDistance == 1 )
4499      {
4500        cStruct.uiBestDistance = 0;
4501        if ( cStruct.ucPointNr != 0 )
4502        {
4503          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4504        }
4505      }
4506    }
4507  }
4508
4509  // start refinement
4510  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4511  {
4512    while ( cStruct.uiBestDistance > 0 )
4513    {
4514      iStartX = cStruct.iBestX;
4515      iStartY = cStruct.iBestY;
4516      cStruct.uiBestDistance = 0;
4517      cStruct.ucPointNr = 0;
4518      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4519      {
4520        if ( bStarRefinementDiamond == 1 )
4521        {
4522          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4523        }
4524        else
4525        {
4526          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4527        }
4528        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4529        {
4530          break;
4531        }
4532      }
4533
4534      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4535      if ( cStruct.uiBestDistance == 1 )
4536      {
4537        cStruct.uiBestDistance = 0;
4538        if ( cStruct.ucPointNr != 0 )
4539        {
4540          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4541        }
4542      }
4543    }
4544  }
4545
4546  // write out best match
4547  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4548  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4549}
4550
4551
4552#ifdef ROUNDING_CONTROL_BIPRED
4553Void TEncSearch::xPatternSearchFracDIF_Bi( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvInt, TComMv& rcMvHalf, TComMv& rcMvQter, UInt& ruiCost, Pel* piRefY2, Bool bRound )
4554{
4555  //  Reference pattern initialization (integer scale)
4556  TComPattern cPatternRoi;
4557  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4558  cPatternRoi.initPattern( piRefY +  iOffset,
4559                          NULL,
4560                          NULL,
4561                          pcPatternKey->getROIYWidth(),
4562                          pcPatternKey->getROIYHeight(),
4563                          iRefStride,
4564                          0, 0, 0, 0 );
4565  Pel*  piRef;
4566  iRefStride  = m_cYuvExt.getStride();
4567
4568  //  Half-pel refinement
4569  xExtDIFUpSamplingH ( &cPatternRoi, &m_cYuvExt );
4570  piRef = m_cYuvExt.getLumaAddr() + ((iRefStride + 4) << 2);
4571
4572  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4573  ruiCost = xPatternRefinement_Bi( pcPatternKey, piRef, iRefStride, 4, 2, rcMvHalf, piRefY2, bRound );
4574
4575  m_pcRdCost->setCostScale( 0 );
4576
4577  //  Quater-pel refinement
4578  Pel*  piSrcPel = cPatternRoi.getROIY() + (rcMvHalf.getHor() >> 1) + cPatternRoi.getPatternLStride() * (rcMvHalf.getVer() >> 1);
4579  Int*  piSrc    = m_piYuvExt  + ((m_iYuvExtStride + 4) << 2) + (rcMvHalf.getHor() << 1) + m_iYuvExtStride * (rcMvHalf.getVer() << 1);
4580  piRef += (rcMvHalf.getHor() << 1) + iRefStride * (rcMvHalf.getVer() << 1);
4581  xExtDIFUpSamplingQ ( pcPatternKey, piRef, iRefStride, piSrcPel, cPatternRoi.getPatternLStride(), piSrc, m_iYuvExtStride, m_puiDFilter[rcMvHalf.getHor()+rcMvHalf.getVer()*3] );
4582
4583  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4584  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4585  ruiCost = xPatternRefinement_Bi( pcPatternKey, piRef, iRefStride, 4, 1, rcMvQter, piRefY2, bRound );
4586}
4587
4588#endif
4589
4590Void TEncSearch::xPatternSearchFracDIF( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvInt, TComMv& rcMvHalf, TComMv& rcMvQter, UInt& ruiCost )
4591{
4592  //  Reference pattern initialization (integer scale)
4593  TComPattern cPatternRoi;
4594  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4595  cPatternRoi.initPattern( piRefY +  iOffset,
4596                          NULL,
4597                          NULL,
4598                          pcPatternKey->getROIYWidth(),
4599                          pcPatternKey->getROIYHeight(),
4600                          iRefStride,
4601                          0, 0, 0, 0 );
4602  Pel*  piRef;
4603  iRefStride  = m_cYuvExt.getStride();
4604
4605  //  Half-pel refinement
4606  xExtDIFUpSamplingH ( &cPatternRoi, &m_cYuvExt );
4607  piRef = m_cYuvExt.getLumaAddr() + ((iRefStride + 4) << 2);
4608
4609  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4610  ruiCost = xPatternRefinement( pcPatternKey, piRef, iRefStride, 4, 2, rcMvHalf   );
4611
4612  m_pcRdCost->setCostScale( 0 );
4613
4614  //  Quater-pel refinement
4615  Pel*  piSrcPel = cPatternRoi.getROIY() + (rcMvHalf.getHor() >> 1) + cPatternRoi.getPatternLStride() * (rcMvHalf.getVer() >> 1);
4616  Int*  piSrc    = m_piYuvExt  + ((m_iYuvExtStride + 4) << 2) + (rcMvHalf.getHor() << 1) + m_iYuvExtStride * (rcMvHalf.getVer() << 1);
4617  piRef += (rcMvHalf.getHor() << 1) + iRefStride * (rcMvHalf.getVer() << 1);
4618  xExtDIFUpSamplingQ ( pcPatternKey, piRef, iRefStride, piSrcPel, cPatternRoi.getPatternLStride(), piSrc, m_iYuvExtStride, m_puiDFilter[rcMvHalf.getHor()+rcMvHalf.getVer()*3] );
4619
4620  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4621  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4622  ruiCost = xPatternRefinement( pcPatternKey, piRef, iRefStride, 4, 1, rcMvQter );
4623}
4624
4625Void TEncSearch::predInterSkipSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv )
4626{
4627  SliceType eSliceType = pcCU->getSlice()->getSliceType();
4628  if ( eSliceType == I_SLICE )
4629    return;
4630
4631  if ( eSliceType == P_SLICE && pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 )
4632  {
4633    pcCU->setInterDirSubParts( 1, 0, 0, pcCU->getDepth( 0 ) );
4634
4635    TComMv cMv;
4636    TComMv cZeroMv;
4637    xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_0, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_0 )->getAMVPInfo()->iN > 0?  true:false) );
4638    pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4639    pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4640    pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cZeroMv, NOT_VALID, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4641    pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4642
4643    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, 0, 0, pcCU->getDepth(0));
4644    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, 0, 0, pcCU->getDepth(0));
4645
4646    //  Motion compensation
4647    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_0 );
4648
4649  }
4650  else if ( eSliceType == B_SLICE &&
4651           pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 &&
4652           pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0  )
4653  {
4654    TComMv cMv;
4655    TComMv cZeroMv;
4656
4657    if (pcCU->getInterDir(0)!=2)
4658    {
4659      xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_0, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_0 )->getAMVPInfo()->iN > 0?  true:false) );
4660      pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4661      pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 ); //unnecessary
4662    }
4663
4664    if (pcCU->getInterDir(0)!=1)
4665    {
4666      xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_1, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_1 )->getAMVPInfo()->iN > 0?  true:false) );
4667      pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4668      pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4669    }
4670
4671    motionCompensation ( pcCU, rpcPredYuv );
4672
4673  }
4674  else
4675  {
4676    assert( 0 );
4677  }
4678
4679  return;
4680}
4681
4682/** encode residual and calculate rate-distortion for a CU block
4683 * \param pcCU
4684 * \param pcYuvOrg
4685 * \param pcYuvPred
4686 * \param rpcYuvResi
4687 * \param rpcYuvResiBest
4688 * \param rpcYuvRec
4689 * \param bSkipRes
4690 * \returns Void
4691 */
4692Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred, TComYuv*& rpcYuvResi, TComYuv*& rpcYuvResiBest, TComYuv*& rpcYuvRec, TComYuv*& rpcYuvResPrd, Bool bSkipRes )
4693{
4694  if ( pcCU->isIntra(0) )
4695  {
4696    return;
4697  }
4698
4699  PredMode  ePredMode    = pcCU->getPredictionMode( 0 );
4700  Bool      bHighPass    = pcCU->getSlice()->getDepth() ? true : false;
4701  UInt      uiBits       = 0, uiBitsBest = 0;
4702  Dist      uiDistortion = 0, uiDistortionBest = 0;
4703
4704  UInt      uiWidth      = pcCU->getWidth ( 0 );
4705  UInt      uiHeight     = pcCU->getHeight( 0 );
4706
4707  //  No residual coding : SKIP mode
4708  if ( ePredMode == MODE_SKIP && bSkipRes )
4709  {
4710    rpcYuvResi->clear();
4711
4712    pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4713
4714#if HHI_INTER_VIEW_RESIDUAL_PRED
4715    // add residual prediction
4716    if( pcCU->getResPredFlag( 0 ) )
4717    {
4718      rpcYuvRec->add( rpcYuvResPrd, uiWidth, uiHeight );
4719      rpcYuvRec->clip( uiWidth, uiHeight );
4720    }
4721#endif
4722
4723#if HHI_VSO   
4724    if ( m_pcRdCost->getUseVSO() )
4725    {
4726      uiDistortion = m_pcRdCost->getDistVS( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight     , false, 0 );
4727    }
4728    else
4729#endif
4730    {
4731      uiDistortion = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4732      + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4733      + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4734    }
4735   
4736
4737    if( m_bUseSBACRD )
4738      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4739
4740    m_pcEntropyCoder->resetBits();
4741#if HHI_MPI
4742    if( pcCU->getTextureModeDepth( 0 ) == -1 )
4743    {
4744#endif
4745    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4746#if HHI_MRG_SKIP
4747    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, 0, true );
4748#else
4749    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 ) //if ( ref. frame list0 has at least 1 entry )
4750    {
4751      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_0);
4752    }
4753    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 ) //if ( ref. frame list1 has at least 1 entry )
4754    {
4755      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_1);
4756    }
4757#endif
4758#if HHI_INTER_VIEW_RESIDUAL_PRED
4759    m_pcEntropyCoder->encodeResPredFlag( pcCU, 0, 0, true );
4760#endif
4761#if HHI_MPI
4762    }
4763#endif
4764
4765    uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4766    pcCU->getTotalBits()       = uiBits;
4767    pcCU->getTotalDistortion() = uiDistortion;
4768
4769#if HHI_VSO
4770    if ( m_pcRdCost->getUseLambdaScaleVSO() )
4771    {
4772      pcCU->getTotalCost() = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );
4773    }
4774    else
4775#endif
4776    {
4777      pcCU->getTotalCost() = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4778    }
4779
4780    if( m_bUseSBACRD )
4781      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4782
4783    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4784    pcCU->setTrIdxSubParts( 0, 0, pcCU->getDepth(0) );
4785
4786#if HHI_VSO
4787    // set Model
4788    if( m_pcRdCost->getUseRenModel() )
4789    {
4790      Pel*  piSrc       = rpcYuvRec->getLumaAddr();
4791      UInt  uiSrcStride = rpcYuvRec->getStride();
4792      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4793    }
4794#endif
4795
4796    return;
4797  }
4798
4799  //  Residual coding.
4800  UInt    uiQp, uiQpBest = 0, uiQpMin, uiQpMax;
4801  Double  dCost, dCostBest = MAX_DOUBLE;
4802
4803  UInt uiBestTrMode = 0;
4804
4805  UInt uiTrLevel = 0;
4806  if( (pcCU->getWidth(0) > pcCU->getSlice()->getSPS()->getMaxTrSize()) )
4807  {
4808    while( pcCU->getWidth(0) > (pcCU->getSlice()->getSPS()->getMaxTrSize()<<uiTrLevel) ) uiTrLevel++;
4809  }
4810  UInt uiMaxTrMode = pcCU->getSlice()->getSPS()->getMaxTrDepth() + uiTrLevel;
4811
4812  while((uiWidth>>uiMaxTrMode) < (g_uiMaxCUWidth>>g_uiMaxCUDepth)) uiMaxTrMode--;
4813
4814  uiQpMin      = bHighPass ? Min( MAX_QP, Max( MIN_QP, pcCU->getQP(0) - m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4815  uiQpMax      = bHighPass ? Min( MAX_QP, Max( MIN_QP, pcCU->getQP(0) + m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4816
4817  pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4818
4819#if HHI_INTER_VIEW_RESIDUAL_PRED
4820  // add residual prediction
4821  if( pcCU->getResPredFlag( 0 ) )
4822  {
4823    rpcYuvRec->add( rpcYuvResPrd, uiWidth, uiHeight );
4824  }
4825#endif
4826#if HHI_INTERVIEW_SKIP
4827  if( bSkipRes)
4828  {
4829    rpcYuvResi->clear() ;
4830  }
4831  else
4832  {
4833    rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4834  }
4835#else
4836  rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4837#endif
4838
4839  for ( uiQp = uiQpMin; uiQp <= uiQpMax; uiQp++ )
4840  {
4841    pcCU->setQPSubParts( uiQp, 0, pcCU->getDepth(0) );
4842    dCost = 0.;
4843    uiBits = 0;
4844    uiDistortion = 0;
4845    if( m_bUseSBACRD )
4846    {
4847      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4848    }
4849
4850    Dist uiZeroDistortion = 0;
4851#if HHI_VSO
4852    if ( m_pcRdCost->getUseVSO() )
4853    {
4854      m_cYuvRecTemp.create( pcYuvPred->getWidth(), pcYuvPred->getHeight()  );
4855    }
4856#endif
4857
4858    xEstimateResidualQT( pcCU, 0, 0, pcYuvOrg, rpcYuvRec, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4859
4860#if HHI_VSO
4861    if ( m_pcRdCost->getUseVSO() )
4862    {
4863      m_cYuvRecTemp.destroy();
4864    }
4865#endif
4866
4867
4868    double dZeroCost;
4869#if HHI_VSO
4870    if( m_pcRdCost->getUseLambdaScaleVSO() )
4871    {
4872      dZeroCost = m_pcRdCost->calcRdCostVSO( 0, uiZeroDistortion );
4873    }
4874    else
4875#endif
4876    {
4877      dZeroCost = m_pcRdCost->calcRdCost( 0, uiZeroDistortion );
4878    }
4879
4880    if ( dZeroCost < dCost )
4881    {
4882      dCost        = dZeroCost;
4883      uiBits       = 0;
4884      uiDistortion = uiZeroDistortion;
4885
4886      const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4887      ::memset( pcCU->getTransformIdx()      , 0, uiQPartNum * sizeof(UChar) );
4888      ::memset( pcCU->getCbf( TEXT_LUMA )    , 0, uiQPartNum * sizeof(UChar) );
4889      ::memset( pcCU->getCbf( TEXT_CHROMA_U ), 0, uiQPartNum * sizeof(UChar) );
4890      ::memset( pcCU->getCbf( TEXT_CHROMA_V ), 0, uiQPartNum * sizeof(UChar) );
4891      ::memset( pcCU->getCoeffY()            , 0, uiWidth * uiHeight * sizeof( TCoeff )      );
4892      ::memset( pcCU->getCoeffCb()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4893      ::memset( pcCU->getCoeffCr()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4894    }
4895    else
4896    {
4897      xSetResidualQTData( pcCU, 0, NULL, pcCU->getDepth(0), false );
4898    }
4899
4900    if( m_bUseSBACRD )
4901    {
4902      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4903    }
4904#if 0 // check
4905    {
4906      m_pcEntropyCoder->resetBits();
4907      m_pcEntropyCoder->encodeCoeff( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
4908      const UInt uiBitsForCoeff = m_pcEntropyCoder->getNumberOfWrittenBits();
4909      if( m_bUseSBACRD )
4910      {
4911        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4912      }
4913      if( uiBitsForCoeff != uiBits )
4914        assert( 0 );
4915    }
4916#endif
4917    uiBits = 0;
4918    {
4919      TComYuv *pDummy = NULL;
4920      xAddSymbolBitsInter( pcCU, 0, 0, uiBits, pDummy, NULL, pDummy );
4921    }
4922
4923    Double dExactCost;
4924#if HHI_VSO
4925    if( m_pcRdCost->getUseLambdaScaleVSO() )
4926    {
4927      dExactCost = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );;
4928    }
4929    else
4930#endif
4931    {
4932      dExactCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4933    }
4934
4935    dCost = dExactCost;
4936
4937    if ( dCost < dCostBest )
4938    {
4939      if ( !pcCU->getQtRootCbf( 0 ) )
4940      {
4941        rpcYuvResiBest->clear();
4942      }
4943      else
4944      {
4945        xSetResidualQTData( pcCU, 0, rpcYuvResiBest, pcCU->getDepth(0), true );
4946      }
4947
4948      if( uiQpMin != uiQpMax && uiQp != uiQpMax )
4949      {
4950        const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4951        ::memcpy( m_puhQTTempTrIdx, pcCU->getTransformIdx(),        uiQPartNum * sizeof(UChar) );
4952        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA ),     uiQPartNum * sizeof(UChar) );
4953        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPartNum * sizeof(UChar) );
4954        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPartNum * sizeof(UChar) );
4955        ::memcpy( m_pcQTTempCoeffY,  pcCU->getCoeffY(),  uiWidth * uiHeight * sizeof( TCoeff )      );
4956        ::memcpy( m_pcQTTempCoeffCb, pcCU->getCoeffCb(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4957        ::memcpy( m_pcQTTempCoeffCr, pcCU->getCoeffCr(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4958      }
4959      uiBitsBest       = uiBits;
4960      uiDistortionBest = uiDistortion;
4961      dCostBest        = dCost;
4962      uiQpBest         = uiQp;
4963
4964      if( m_bUseSBACRD )
4965      {
4966        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4967      }
4968    }
4969
4970#if HHI_VSO
4971    // reset Model
4972    if( m_pcRdCost->getUseRenModel() )
4973    {
4974      Pel*  piSrc       = pcYuvOrg->getLumaAddr();
4975      UInt  uiSrcStride = pcYuvOrg->getStride();
4976      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4977    }
4978#endif
4979  }
4980
4981  assert ( dCostBest != MAX_DOUBLE );
4982
4983  if( uiQpMin != uiQpMax && uiQpBest != uiQpMax )
4984  {
4985    if( m_bUseSBACRD )
4986    {
4987      assert( 0 ); // check
4988      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4989    }
4990    // copy best cbf and trIdx to pcCU
4991    const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4992    ::memcpy( pcCU->getTransformIdx(),       m_puhQTTempTrIdx,  uiQPartNum * sizeof(UChar) );
4993    ::memcpy( pcCU->getCbf( TEXT_LUMA ),     m_puhQTTempCbf[0], uiQPartNum * sizeof(UChar) );
4994    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPartNum * sizeof(UChar) );
4995    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPartNum * sizeof(UChar) );
4996    ::memcpy( pcCU->getCoeffY(),  m_pcQTTempCoeffY,  uiWidth * uiHeight * sizeof( TCoeff )      );
4997    ::memcpy( pcCU->getCoeffCb(), m_pcQTTempCoeffCb, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4998    ::memcpy( pcCU->getCoeffCr(), m_pcQTTempCoeffCr, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4999  }
5000  rpcYuvRec->addClip ( rpcYuvRec, rpcYuvResiBest, 0, uiWidth );
5001
5002  // update with clipped distortion and cost (qp estimation loop uses unclipped values)
5003
5004#if HHI_VSO
5005  if ( m_pcRdCost->getUseVSO() )
5006  {
5007    uiDistortionBest = m_pcRdCost->getDistVS  ( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight, false, 0    );
5008  }
5009  else
5010#endif
5011  {
5012    uiDistortionBest = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
5013    + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
5014    + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
5015  }
5016
5017#if HHI_VSO
5018  if ( m_pcRdCost->getUseLambdaScaleVSO() )
5019  {
5020    dCostBest = m_pcRdCost->calcRdCostVSO( uiBitsBest, uiDistortionBest );
5021  }
5022  else
5023#endif
5024  {
5025    dCostBest = m_pcRdCost->calcRdCost( uiBitsBest, uiDistortionBest );
5026  }
5027
5028  pcCU->getTotalBits()       = uiBitsBest;
5029  pcCU->getTotalDistortion() = uiDistortionBest;
5030  pcCU->getTotalCost()       = dCostBest;
5031
5032  if ( pcCU->isSkipped(0) )
5033  {
5034    uiBestTrMode = 0;
5035    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
5036  }
5037
5038  pcCU->setQPSubParts( uiQpBest, 0, pcCU->getDepth(0) );
5039
5040  // set Model
5041#if HHI_VSO
5042  if( m_pcRdCost->getUseRenModel() )
5043  {
5044    Pel*  piSrc       = rpcYuvRec->getLumaAddr();
5045    UInt  uiSrcStride = rpcYuvRec->getStride();
5046    m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
5047  }
5048#endif
5049}
5050
5051Void TEncSearch::xEstimateResidualQT( TComDataCU* pcCU, UInt uiQuadrant, UInt uiAbsPartIdx, TComYuv* pcOrg, TComYuv* pcPred, TComYuv* pcResi, const UInt uiDepth, Double &rdCost, UInt &ruiBits, Dist &ruiDist, Dist *puiZeroDist )
5052{
5053  const UInt uiTrMode = uiDepth - pcCU->getDepth( 0 );
5054
5055  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5056  const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
5057
5058#if HHI_RQT_FORCE_SPLIT_ACC2_PU
5059#if HHI_RQT_FORCE_SPLIT_NxN
5060  const Bool bNxNOK = pcCU->getPartitionSize( 0 ) == SIZE_NxN && uiTrMode > 0;
5061#else
5062  const Bool bNxNOK = pcCU->getPartitionSize( 0 ) == SIZE_NxN;
5063#endif
5064#if HHI_RQT_FORCE_SPLIT_RECT
5065  const Bool bSymmetricOK  = pcCU->getPartitionSize( 0 ) >= SIZE_2NxN  && pcCU->getPartitionSize( 0 ) < SIZE_NxN   && uiTrMode > 0;
5066#else
5067  const Bool bSymmetricOK  = pcCU->getPartitionSize( 0 ) >= SIZE_2NxN  && pcCU->getPartitionSize( 0 ) < SIZE_NxN;
5068#endif
5069  const Bool bNoForceSplit = pcCU->getPartitionSize( 0 ) == SIZE_2Nx2N || bNxNOK || bSymmetricOK;
5070  const Bool bCheckFull    = bNoForceSplit && ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
5071#else
5072  const Bool bCheckFull    = ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
5073#endif
5074
5075  const Bool bCheckSplit  = ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
5076
5077  assert( bCheckFull || bCheckSplit );
5078
5079  Bool  bCodeChroma   = true;
5080  UInt  uiTrModeC     = uiTrMode;
5081  UInt  uiLog2TrSizeC = uiLog2TrSize-1;
5082  if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
5083  {
5084    uiLog2TrSizeC++;
5085    uiTrModeC    --;
5086    UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
5087    bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
5088  }
5089
5090  const UInt uiSetCbf = 1 << uiTrMode;
5091  // code full block
5092  Double dSingleCost = MAX_DOUBLE;
5093  UInt uiSingleBits = 0;
5094  Dist uiSingleDist = 0;
5095  UInt uiAbsSumY = 0, uiAbsSumU = 0, uiAbsSumV = 0;
5096
5097  if( m_bUseSBACRD )
5098  {
5099    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5100  }
5101
5102  if( bCheckFull )
5103  {
5104    const UInt uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
5105    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5106    TCoeff *pcCoeffCurrY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5107    TCoeff *pcCoeffCurrU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5108    TCoeff *pcCoeffCurrV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5109
5110    pcCU->setTrIdxSubParts( uiDepth - pcCU->getDepth( 0 ), uiAbsPartIdx, uiDepth );
5111    if (m_pcEncCfg->getUseRDOQ())
5112    {
5113      m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, 1<< uiLog2TrSize, TEXT_LUMA );
5114    }
5115#if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
5116    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ) + pcCU->getQpOffsetForTextCU(uiAbsPartIdx, false), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA );
5117#else
5118    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA );
5119#endif
5120    m_pcTrQuant->transformNxN( pcCU, pcResi->getLumaAddr( uiAbsPartIdx ), pcResi->getStride (), pcCoeffCurrY, 1<< uiLog2TrSize,    1<< uiLog2TrSize,    uiAbsSumY, TEXT_LUMA,     uiAbsPartIdx );
5121
5122    pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5123
5124    if( bCodeChroma )
5125    {
5126      if (m_pcEncCfg->getUseRDOQ())
5127      {
5128        m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, 1<<uiLog2TrSizeC, TEXT_CHROMA );
5129      }
5130#if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
5131      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ) + pcCU->getQpOffsetForTextCU(uiAbsPartIdx, false), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
5132#else
5133      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
5134#endif
5135      m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr( uiAbsPartIdx ), pcResi->getCStride(), pcCoeffCurrU, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiAbsSumU, TEXT_CHROMA_U, uiAbsPartIdx );
5136      m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr( uiAbsPartIdx ), pcResi->getCStride(), pcCoeffCurrV, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiAbsSumV, TEXT_CHROMA_V, uiAbsPartIdx );
5137      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5138      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5139    }
5140
5141    m_pcEntropyCoder->resetBits();
5142
5143    if (pcCU->getSlice()->getSymbolMode())
5144      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
5145
5146    m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx, 1<< uiLog2TrSize,    1<< uiLog2TrSize,    uiDepth, TEXT_LUMA,     false );
5147    const UInt uiSingleBitsY = m_pcEntropyCoder->getNumberOfWrittenBits();
5148
5149    UInt uiSingleBitsU = 0;
5150    UInt uiSingleBitsV = 0;
5151    if( bCodeChroma )
5152    {
5153      if (pcCU->getSlice()->getSymbolMode())
5154        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode );
5155      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_U, false );
5156      uiSingleBitsU = m_pcEntropyCoder->getNumberOfWrittenBits() - uiSingleBitsY;
5157
5158      if (pcCU->getSlice()->getSymbolMode())
5159        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode );
5160      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_V, false );
5161      uiSingle