source: 3DVCSoftware/branches/0.3-poznan-univ/source/Lib/TLibEncoder/TEncSearch.cpp @ 41

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

Adjustment for FlexCO, and high-level syntax improvement.

  • Property svn:eol-style set to native
File size: 223.0 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#if FLEX_CODING_ORDER
1937      if ( pcCU->getSlice()->getSPS()->getUseDMM34() )
1938      {
1939#endif
1940      TComYuv cTempYuv; cTempYuv.create( uiWidth, uiHeight ); cTempYuv.clear();
1941      Pel* piTempY      = cTempYuv.getLumaAddr();
1942
1943      fillTexturePicTempBlock( pcCU, uiPartOffset, piTempY, uiWidth, uiHeight );
1944
1945      piTempY = cTempYuv.getLumaAddr();
1946
1947      UInt uiTexTabIdx  = 0;
1948      Int  iTexDeltaDC1 = 0;
1949      Int  iTexDeltaDC2 = 0;
1950      findWedgeTexMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTexTabIdx, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail, WedgeDist_SAD, piTempY ); 
1951      pcCU->setWedgePredTexTabIdxSubParts  ( uiTexTabIdx,  uiPartOffset, uiDepth + uiInitTrDepth );
1952      pcCU->setWedgePredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1953      pcCU->setWedgePredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1954
1955      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDTEX_IDX;
1956      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDTEX_D_IDX;
1957
1958      if ( uiWidth > 4 )
1959      {
1960        piTempY = cTempYuv.getLumaAddr();
1961
1962        iTexDeltaDC1 = 0;
1963        iTexDeltaDC2 = 0;
1964
1965        findContourPredTex( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail, piTempY );
1966        pcCU->setContourPredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1967        pcCU->setContourPredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1968
1969        uiRdModeList[ uiNewMaxMode++ ] = DMM_CONTOUR_PREDTEX_IDX;
1970        uiRdModeList[ uiNewMaxMode++ ] = DMM_CONTOUR_PREDTEX_D_IDX;
1971      }
1972
1973      cTempYuv.destroy();
1974#if FLEX_CODING_ORDER
1975      }
1976#endif
1977#endif
1978    }
1979#endif
1980    //===== check modes (using r-d costs) =====
1981#if HHI_RQT_INTRA_SPEEDUP_MOD
1982    UInt   uiSecondBestMode  = MAX_UINT;
1983    Double dSecondBestPUCost = MAX_DOUBLE;
1984#endif
1985
1986    UInt    uiBestPUMode  = 0;
1987    Dist    uiBestPUDistY = 0;
1988    Dist    uiBestPUDistC = 0;
1989    Double  dBestPUCost   = MAX_DOUBLE;
1990    for( UInt uiMode = uiMinMode; uiMode < uiNewMaxMode; uiMode++ )
1991    {
1992      // set luma prediction mode
1993      UInt uiOrgMode = uiRdModeList[uiMode];
1994
1995#if (!REFERENCE_SAMPLE_PADDING)
1996#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1997      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail, uiWidth, uiHeight, pcCU, uiPartOffset ) )
1998        continue;
1999#else
2000      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
2001        continue;
2002#endif
2003#else
2004#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2005#if HHI_DMM_PRED_TEX && FLEX_CODING_ORDER
2006      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight, pcCU->getSlice()->getSPS()->getUseDMM34() ) )
2007#else
2008      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
2009#endif
2010        continue;
2011#endif
2012#endif
2013
2014      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2015
2016      // set context models
2017      if( m_bUseSBACRD )
2018      {
2019        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2020      }
2021
2022      // determine residual for partition
2023      Dist   uiPUDistY = 0;
2024      Dist   uiPUDistC = 0;
2025      Double dPUCost   = 0.0;
2026
2027
2028      // reset Model
2029#if HHI_VSO
2030      if( m_pcRdCost->getUseRenModel() )
2031      {
2032        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2033      }
2034#endif
2035
2036#if HHI_RQT_INTRA_SPEEDUP
2037      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );
2038#else
2039      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
2040#endif
2041
2042      // check r-d cost
2043      if( dPUCost < dBestPUCost )
2044      {
2045#if HHI_RQT_INTRA_SPEEDUP_MOD
2046        uiSecondBestMode  = uiBestPUMode;
2047        dSecondBestPUCost = dBestPUCost;
2048#endif
2049        uiBestPUMode  = uiOrgMode;
2050        uiBestPUDistY = uiPUDistY;
2051        uiBestPUDistC = uiPUDistC;
2052        dBestPUCost   = dPUCost;
2053
2054        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2055
2056        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2057        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2058        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2059        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2060        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2061
2062      }
2063#if HHI_RQT_INTRA_SPEEDUP_MOD
2064      else if( dPUCost < dSecondBestPUCost )
2065      {
2066        uiSecondBestMode  = uiOrgMode;
2067        dSecondBestPUCost = dPUCost;
2068      }
2069#endif
2070    } // Mode loop
2071
2072#if HHI_RQT_INTRA_SPEEDUP
2073#if HHI_RQT_INTRA_SPEEDUP_MOD
2074    for( UInt ui =0; ui < 2; ++ui )
2075#endif
2076    {
2077#if HHI_RQT_INTRA_SPEEDUP_MOD
2078      UInt uiOrgMode   = ui ? uiSecondBestMode  : uiBestPUMode;
2079      if( uiOrgMode == MAX_UINT )
2080      {
2081        break;
2082      }
2083#else
2084      UInt uiOrgMode = uiBestPUMode;
2085#endif
2086
2087#if (!REFERENCE_SAMPLE_PADDING)
2088#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2089      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail, uiWidth, uiHeight, pcCU, uiPartOffset ) )
2090        continue;
2091#else
2092      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
2093        continue;
2094#endif
2095#else
2096#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2097#if HHI_DMM_PRED_TEX && FLEX_CODING_ORDER
2098      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight, pcCU->getSlice()->getSPS()->getUseDMM34() ) )
2099#else
2100      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
2101#endif
2102        continue;
2103#endif
2104#endif
2105
2106      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2107
2108      // set context models
2109      if( m_bUseSBACRD )
2110      {
2111        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2112      }
2113
2114      // determine residual for partition
2115      Dist   uiPUDistY = 0;
2116      Dist   uiPUDistC = 0;
2117      Double dPUCost   = 0.0;
2118
2119#if HHI_VSO
2120      // reset Model
2121      if( m_pcRdCost->getUseRenModel() )
2122      {
2123        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2124      }
2125#endif
2126
2127      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, false, dPUCost );
2128
2129      // check r-d cost
2130      if( dPUCost < dBestPUCost )
2131      {
2132        uiBestPUMode  = uiOrgMode;
2133        uiBestPUDistY = uiPUDistY;
2134        uiBestPUDistC = uiPUDistC;
2135        dBestPUCost   = dPUCost;
2136
2137        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2138
2139        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2140        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2141        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2142        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2143        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2144
2145      }
2146    } // Mode loop
2147#endif
2148
2149    //--- update overall distortion ---
2150    uiOverallDistY += uiBestPUDistY;
2151    uiOverallDistC += uiBestPUDistC;
2152
2153    //--- update transform index and cbf ---
2154    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2155    ::memcpy( pcCU->getTransformIdx()       + uiPartOffset, m_puhQTTempTrIdx,  uiQPartNum * sizeof( UChar ) );
2156    ::memcpy( pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, m_puhQTTempCbf[0], uiQPartNum * sizeof( UChar ) );
2157    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, m_puhQTTempCbf[1], uiQPartNum * sizeof( UChar ) );
2158    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, m_puhQTTempCbf[2], uiQPartNum * sizeof( UChar ) );
2159
2160    //--- set reconstruction for next intra prediction blocks ---
2161    if( uiPU != uiNumPU - 1 )
2162    {
2163      Bool bSkipChroma  = false;
2164      Bool bChromaSame  = false;
2165      UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> ( pcCU->getDepth(0) + uiInitTrDepth ) ] + 2;
2166      if( !bLumaOnly && uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
2167      {
2168        assert( uiInitTrDepth  > 0 );
2169        bSkipChroma  = ( uiPU != 0 );
2170        bChromaSame  = true;
2171      }
2172
2173      UInt    uiCompWidth   = pcCU->getWidth ( 0 ) >> uiInitTrDepth;
2174      UInt    uiCompHeight  = pcCU->getHeight( 0 ) >> uiInitTrDepth;
2175      UInt    uiZOrder      = pcCU->getZorderIdxInCU() + uiPartOffset;
2176      Pel*    piDes         = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
2177      UInt    uiDesStride   = pcCU->getPic()->getPicYuvRec()->getStride();
2178      Pel*    piSrc         = pcRecoYuv->getLumaAddr( uiPartOffset );
2179      UInt    uiSrcStride   = pcRecoYuv->getStride();
2180      for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2181      {
2182        for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2183        {
2184          piDes[ uiX ] = piSrc[ uiX ];
2185        }
2186      }
2187
2188#if HHI_VSO
2189      // set model
2190      if( m_pcRdCost->getUseRenModel() )
2191      {
2192        piSrc = pcRecoYuv->getLumaAddr( uiPartOffset );
2193        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piSrc, uiSrcStride, uiCompWidth, uiCompHeight);
2194      }
2195#endif
2196
2197      if( !bLumaOnly && !bSkipChroma )
2198      {
2199        if( !bChromaSame )
2200        {
2201          uiCompWidth   >>= 1;
2202          uiCompHeight  >>= 1;
2203        }
2204        piDes         = pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder );
2205        uiDesStride   = pcCU->getPic()->getPicYuvRec()->getCStride();
2206        piSrc         = pcRecoYuv->getCbAddr( uiPartOffset );
2207        uiSrcStride   = pcRecoYuv->getCStride();
2208        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2209        {
2210          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2211          {
2212            piDes[ uiX ] = piSrc[ uiX ];
2213          }
2214        }
2215        piDes         = pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder );
2216        piSrc         = pcRecoYuv->getCrAddr( uiPartOffset );
2217        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2218        {
2219          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2220          {
2221            piDes[ uiX ] = piSrc[ uiX ];
2222          }
2223        }
2224      }
2225    }
2226
2227    //=== update PU data ====
2228    pcCU->setLumaIntraDirSubParts     ( uiBestPUMode, uiPartOffset, uiDepth + uiInitTrDepth );
2229    pcCU->copyToPic                   ( uiDepth, uiPU, uiInitTrDepth );
2230  } // PU loop
2231
2232
2233  if( uiNumPU > 1 )
2234  { // set Cbf for all blocks
2235    UInt uiCombCbfY = 0;
2236    UInt uiCombCbfU = 0;
2237    UInt uiCombCbfV = 0;
2238    UInt uiPartIdx  = 0;
2239    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += uiQNumParts )
2240    {
2241      uiCombCbfY |= pcCU->getCbf( uiPartIdx, TEXT_LUMA,     1 );
2242      uiCombCbfU |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_U, 1 );
2243      uiCombCbfV |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_V, 1 );
2244    }
2245    for( UInt uiOffs = 0; uiOffs < 4 * uiQNumParts; uiOffs++ )
2246    {
2247      pcCU->getCbf( TEXT_LUMA     )[ uiOffs ] |= uiCombCbfY;
2248      pcCU->getCbf( TEXT_CHROMA_U )[ uiOffs ] |= uiCombCbfU;
2249      pcCU->getCbf( TEXT_CHROMA_V )[ uiOffs ] |= uiCombCbfV;
2250    }
2251  }
2252
2253  //===== reset context models =====
2254  if(m_bUseSBACRD)
2255  {
2256    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2257  }
2258
2259  //===== set distortion (rate and r-d costs are determined later) =====
2260  ruiDistC                   = uiOverallDistC;
2261  pcCU->getTotalDistortion() = uiOverallDistY + uiOverallDistC;
2262}
2263
2264
2265
2266Void
2267TEncSearch::estIntraPredChromaQT( TComDataCU* pcCU,
2268                                 TComYuv*    pcOrgYuv,
2269                                 TComYuv*    pcPredYuv,
2270                                 TComYuv*    pcResiYuv,
2271                                 TComYuv*    pcRecoYuv,
2272                                 Dist        uiPreCalcDistC )
2273{
2274  UInt    uiDepth     = pcCU->getDepth(0);
2275  UInt    uiBestMode  = 0;
2276  Dist    uiBestDist  = 0;
2277  Double  dBestCost   = MAX_DOUBLE;
2278
2279  //----- init mode list -----
2280#if ADD_PLANAR_MODE
2281  UInt  uiModeList[6];
2282  uiModeList[0] = PLANAR_IDX;
2283  for( Int i = 0; i < 5; i++ )
2284  {
2285    uiModeList[i+1] = i;
2286  }
2287  UInt uiLumaMode = pcCU->getLumaIntraDir(0);
2288#else
2289  UInt  uiModeList[5];
2290  for( Int i = 0; i < 4; i++ )
2291  {
2292    uiModeList[i] = i;
2293  }
2294
2295  uiModeList[4]   = pcCU->getLumaIntraDir(0);
2296#endif
2297
2298  UInt  uiMinMode = 0;
2299#if CHROMA_CODEWORD
2300#if ADD_PLANAR_MODE
2301  UInt  uiMaxMode = 6;
2302
2303#if LM_CHROMA
2304  UInt  uiIgnore;
2305  if(pcCU->getSlice()->getSPS()->getUseLMChroma())
2306  {
2307    uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 3) ) ? uiMaxMode : uiLumaMode );
2308  }
2309  else
2310  {
2311    uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? uiMaxMode : uiLumaMode );
2312  }
2313#else
2314  UInt  uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? uiMaxMode : uiLumaMode );
2315#endif
2316
2317#else
2318  UInt  uiMaxMode = 5;
2319
2320#if LM_CHROMA
2321  UInt  uiIgnore;
2322  if(pcCU->getSlice()->getSPS()->getUseLMChroma())
2323  {
2324    uiIgnore = (uiModeList[4] >= 0 && uiModeList[4] < 3) ? uiModeList[4] : 6;
2325  }
2326  else
2327  {
2328    uiIgnore = (uiModeList[4] >= 0 && uiModeList[4] < 4) ? uiModeList[4] : 6;
2329  }
2330#else
2331  UInt  uiIgnore = (uiModeList[4] < 4) ? uiModeList[4] : 6;
2332#endif
2333
2334#endif
2335#else
2336#if ADD_PLANAR_MODE
2337  UInt  uiMaxMode = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? 6 : 5 );
2338#else
2339  UInt  uiMaxMode = ( uiModeList[4] >= 4 ? 5 : 4 );
2340#endif
2341#endif
2342
2343  //----- check chroma modes -----
2344  for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )
2345  {
2346#if CHROMA_CODEWORD
2347#if ADD_PLANAR_MODE
2348    if ( uiModeList[uiMode] == uiIgnore )
2349#else
2350    if (uiMode == uiIgnore)
2351#endif
2352    {
2353      continue;
2354    }
2355#endif
2356#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2357#if ADD_PLANAR_MODE
2358    if ( uiModeList[uiMode] == 4 && pcCU->getLumaIntraDir(0) > MAX_MODE_ID_INTRA_DIR )
2359    {
2360      continue;
2361    }
2362#else
2363    if ( uiMode == 4 && pcCU->getLumaIntraDir(0) > MAX_MODE_ID_INTRA_DIR )
2364    {
2365      continue;
2366    }
2367#endif
2368#endif
2369    //----- restore context models -----
2370    if( m_bUseSBACRD )
2371    {
2372      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2373    }
2374
2375    //----- chroma coding -----
2376    Dist    uiDist = 0;
2377#if ADD_PLANAR_MODE
2378    pcCU->setChromIntraDirSubParts  ( uiModeList[uiMode], 0, uiDepth );
2379#else
2380    pcCU->setChromIntraDirSubParts  ( uiMode, 0, uiDepth );
2381#endif
2382    xRecurIntraChromaCodingQT       ( pcCU,   0, 0, pcOrgYuv, pcPredYuv, pcResiYuv, uiDist );
2383    UInt    uiBits = xGetIntraBitsQT( pcCU,   0, 0, false, true, false );
2384    Double  dCost  = m_pcRdCost->calcRdCost( uiBits, uiDist );
2385
2386    //----- compare -----
2387    if( dCost < dBestCost )
2388    {
2389      dBestCost   = dCost;
2390      uiBestDist  = uiDist;
2391#if ADD_PLANAR_MODE
2392      uiBestMode  = uiModeList[uiMode];
2393#else
2394      uiBestMode  = uiMode;
2395#endif
2396      UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2397      xSetIntraResultChromaQT( pcCU, 0, 0, pcRecoYuv );
2398      ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
2399      ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
2400    }
2401  }
2402
2403  //----- set data -----
2404  UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2405  ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPN * sizeof( UChar ) );
2406  ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPN * sizeof( UChar ) );
2407  pcCU->setChromIntraDirSubParts( uiBestMode, 0, uiDepth );
2408  pcCU->getTotalDistortion      () += uiBestDist - uiPreCalcDistC;
2409
2410  //----- restore context models -----
2411  if( m_bUseSBACRD )
2412  {
2413    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2414  }
2415}
2416
2417#if (!REFERENCE_SAMPLE_PADDING)
2418#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2419Bool TEncSearch::predIntraLumaDirAvailable( UInt uiMode, UInt uiWidthBit, Bool bAboveAvail, Bool bLeftAvail, UInt uiWidth, UInt uiHeight, TComDataCU* pcCU, UInt uiAbsPartIdx   )
2420#else
2421Bool TEncSearch::predIntraLumaDirAvailable( UInt uiMode, UInt uiWidthBit, Bool bAboveAvail, Bool bLeftAvail )
2422#endif
2423{
2424  Bool bDirAvailable;
2425#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2426  if( uiMode > MAX_MODE_ID_INTRA_DIR )
2427  {
2428    return predIntraLumaDMMAvailable( uiMode, bAboveAvail, bLeftAvail, uiWidth, uiHeight );
2429  }
2430  else
2431#endif
2432  {
2433    bDirAvailable = true;
2434    UInt uiNewMode = g_aucAngIntraModeOrder[uiMode];
2435    if ( uiNewMode > 0 && ( ( (!bAboveAvail) && uiNewMode < 18 ) || ( (!bLeftAvail) && uiNewMode > 17 ) ) )
2436    {
2437      bDirAvailable = false;
2438    }
2439  }
2440
2441  return bDirAvailable;
2442}
2443#endif
2444
2445#if HHI_DMM_WEDGE_INTRA
2446Void TEncSearch::findWedgeFullMinDist( TComDataCU*  pcCU,
2447                                      UInt         uiAbsPtIdx,
2448                                      Pel*         piOrig,
2449                                      Pel*         piPredic,
2450                                      UInt         uiStride,
2451                                      UInt         uiWidth,
2452                                      UInt         uiHeight,
2453                                      UInt&        ruiTabIdx,
2454                                      Int&         riDeltaDC1,
2455                                      Int&         riDeltaDC2,
2456                                      Bool         bAbove,
2457                                      Bool         bLeft,
2458                                      WedgeDist    eWedgeDist
2459                                      )
2460{
2461  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2462
2463  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2464  xSearchWedgeFullMinDist( pcCU, uiAbsPtIdx, pacWedgeList, piOrig, uiStride, uiWidth, uiHeight, ruiTabIdx );
2465
2466  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2467  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2468}
2469
2470Void TEncSearch::xSearchWedgeFullMinDist( TComDataCU* pcCU, UInt uiAbsPtIdx, WedgeList* pacWedgeList, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx )
2471{
2472  ruiTabIdx = 0;
2473
2474  // local pred buffer
2475  TComYuv cPredYuv;
2476  cPredYuv.create( uiWidth, uiHeight );
2477  cPredYuv.clear();
2478
2479  UInt uiPredStride = cPredYuv.getStride();
2480  Pel* piPred       = cPredYuv.getLumaAddr();
2481
2482  Int  iDC1 = 0;
2483  Int  iDC2 = 0;
2484  // regular wedge search
2485  Dist uiBestDist   = RDO_DIST_MAX;
2486  UInt uiBestTabIdx = 0;
2487
2488  for( UInt uiIdx = 0; uiIdx < pacWedgeList->size(); uiIdx++ )
2489  {
2490    calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piRef,  uiRefStride,  iDC1, iDC2 );
2491    assignWedgeDCs2Pred( &(pacWedgeList->at(uiIdx)), piPred, uiPredStride, iDC1, iDC2 );
2492
2493    Dist uiActDist = RDO_DIST_MAX;
2494#if HHI_VSO
2495    if( m_pcRdCost->getUseVSO() )
2496    {
2497      uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false, 0 );
2498    }
2499    else
2500    {
2501      uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2502    }
2503#else
2504    uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2505#endif
2506
2507    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2508    {
2509      uiBestDist   = uiActDist;
2510      uiBestTabIdx = uiIdx;
2511    }
2512  }
2513  ruiTabIdx = uiBestTabIdx;
2514
2515  cPredYuv.destroy();
2516  return;
2517}
2518
2519Void TEncSearch::findWedgePredDirMinDist( TComDataCU*  pcCU,
2520                                         UInt         uiAbsPtIdx,
2521                                         Pel*         piOrig,
2522                                         Pel*         piPredic,
2523                                         UInt         uiStride,
2524                                         UInt         uiWidth,
2525                                         UInt         uiHeight,
2526                                         UInt&        ruiTabIdx,
2527                                         Int&         riWedgeDeltaEnd,
2528                                         Int&         riDeltaDC1,
2529                                         Int&         riDeltaDC2,
2530                                         Bool         bAbove,
2531                                         Bool         bLeft,
2532                                         WedgeDist    eWedgeDist )
2533{
2534  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2535  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2536
2537  ruiTabIdx       = 0;
2538  riWedgeDeltaEnd = 0;
2539
2540  xSearchWedgePredDirMinDist( pcCU, uiAbsPtIdx, pacWedgeList, piOrig, uiStride, uiWidth, uiHeight, ruiTabIdx, riWedgeDeltaEnd );
2541
2542  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2543  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2544}
2545
2546Void TEncSearch::xSearchWedgePredDirMinDist( TComDataCU* pcCU, UInt uiAbsPtIdx, WedgeList* pacWedgeList, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx, Int& riWedgeDeltaEnd )
2547{
2548  ruiTabIdx       = 0;
2549  riWedgeDeltaEnd = 0;
2550
2551  // local pred buffer
2552  TComYuv cPredYuv;
2553  cPredYuv.create( uiWidth, uiHeight );
2554  cPredYuv.clear();
2555
2556  UInt uiPredStride = cPredYuv.getStride();
2557  Pel* piPred       = cPredYuv.getLumaAddr();
2558
2559  Int  iDC1 = 0;
2560  Int  iDC2 = 0;
2561
2562  // regular wedge search
2563  Dist uiBestDist    = RDO_DIST_MAX;
2564  UInt uiBestTabIdx  = 0;
2565  Int  iBestDeltaEnd = 0;
2566
2567  UInt uiIdx = 0;
2568  for( Int iTestDeltaEnd = -DMM_WEDGE_PREDDIR_DELTAEND_MAX; iTestDeltaEnd <= DMM_WEDGE_PREDDIR_DELTAEND_MAX; iTestDeltaEnd++ )
2569  {
2570    uiIdx = getBestContinueWedge( pcCU, uiAbsPtIdx, uiWidth, uiHeight, iTestDeltaEnd );
2571    calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piRef,  uiRefStride,  iDC1, iDC2 );
2572    assignWedgeDCs2Pred( &(pacWedgeList->at(uiIdx)), piPred, uiPredStride, iDC1, iDC2 );
2573
2574    Dist uiActDist = RDO_DIST_MAX;
2575#if HHI_VSO
2576    if( m_pcRdCost->getUseVSO() )
2577    {
2578      uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false, 0 );
2579    }
2580    else
2581    {
2582      uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2583    }
2584#else
2585    uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2586#endif
2587
2588    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2589    {
2590      uiBestDist    = uiActDist;
2591      uiBestTabIdx  = uiIdx;
2592      iBestDeltaEnd = iTestDeltaEnd;
2593    }
2594    else if( uiIdx == uiBestTabIdx && abs(iTestDeltaEnd) < abs(iBestDeltaEnd) )
2595    {
2596      iBestDeltaEnd = iTestDeltaEnd;
2597    }
2598  }
2599
2600  ruiTabIdx       = uiBestTabIdx;
2601  riWedgeDeltaEnd = iBestDeltaEnd;
2602
2603  cPredYuv.destroy();
2604  return;
2605}
2606#endif
2607
2608#if HHI_DMM_PRED_TEX
2609Void TEncSearch::findWedgeTexMinDist( TComDataCU*  pcCU, 
2610                                      UInt         uiAbsPtIdx, 
2611                                      Pel*         piOrig, 
2612                                      Pel*         piPredic, 
2613                                      UInt         uiStride, 
2614                                      UInt         uiWidth, 
2615                                      UInt         uiHeight, 
2616                                      UInt&        ruiTabIdx, 
2617                                      Int&         riDeltaDC1, 
2618                                      Int&         riDeltaDC2, 
2619                                      Bool         bAbove, 
2620                                      Bool         bLeft, 
2621                                      WedgeDist    eWedgeDist,
2622                                      Pel*         piTextureRef
2623                                    )
2624  {
2625  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2626  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2627
2628  ruiTabIdx = getBestWedgeFromText( pcCU, uiAbsPtIdx, uiWidth, uiHeight, eWedgeDist, piTextureRef );
2629
2630  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2631  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2632}
2633
2634Void TEncSearch::findContourPredTex( TComDataCU*  pcCU,
2635                                     UInt         uiAbsPtIdx,
2636                                     Pel*         piOrig,
2637                                     Pel*         piPredic,
2638                                     UInt         uiStride,
2639                                     UInt         uiWidth,
2640                                     UInt         uiHeight,
2641                                     Int&         riDeltaDC1,
2642                                     Int&         riDeltaDC2,
2643                                     Bool         bAbove,
2644                                     Bool         bLeft,
2645                                     Pel*         piTextureRef )
2646{
2647  // get contour pattern
2648  TComWedgelet* pcContourWedge = new TComWedgelet( uiWidth, uiHeight );
2649  getBestContourFromText( pcCU, uiAbsPtIdx, uiWidth, uiHeight, pcContourWedge, piTextureRef );
2650
2651  xGetWedgeDeltaDCsMinDist( pcContourWedge, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2652
2653  pcContourWedge->destroy();
2654  delete pcContourWedge;
2655}
2656#endif
2657#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2658Void TEncSearch::xGetWedgeDeltaDCsMinDist( TComWedgelet* pcWedgelet,
2659                                           TComDataCU*   pcCU,
2660                                           UInt          uiAbsPtIdx,
2661                                           Pel*          piOrig,
2662                                           Pel*          piPredic,
2663                                           UInt          uiStride,
2664                                           UInt          uiWidth,
2665                                           UInt          uiHeight,
2666                                           Int&          riDeltaDC1,
2667                                           Int&          riDeltaDC2,
2668                                           Bool          bAbove,
2669                                           Bool          bLeft )
2670{
2671  Int iDC1 = 0;
2672  Int iDC2 = 0;
2673  calcWedgeDCs       ( pcWedgelet, piOrig,   uiStride, iDC1, iDC2 );
2674  assignWedgeDCs2Pred( pcWedgelet, piPredic, uiStride, iDC1, iDC2 );
2675
2676  Int iPredDC1 = 0;
2677  Int iPredDC2 = 0;
2678  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt );
2679  Int iMaskStride = ( uiWidth<<1 ) + 1;
2680  piMask += iMaskStride+1;
2681  getWedgePredDCs( pcWedgelet, piMask, iMaskStride, iPredDC1, iPredDC2, bAbove, bLeft );
2682
2683  riDeltaDC1 = iDC1 - iPredDC1;
2684  riDeltaDC2 = iDC2 - iPredDC2;
2685
2686#if HHI_VSO
2687  if( m_pcRdCost->getUseVSO() )
2688  {
2689    Int iFullDeltaDC1 = riDeltaDC1;
2690    Int iFullDeltaDC2 = riDeltaDC2;
2691
2692    xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC1 );
2693    xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC2 );
2694
2695    Dist uiBestDist     = RDO_DIST_MAX;
2696    UInt  uiBestQStepDC1 = 0;
2697    UInt  uiBestQStepDC2 = 0;
2698
2699    UInt uiDeltaDC1Max = abs(iFullDeltaDC1);
2700    UInt uiDeltaDC2Max = abs(iFullDeltaDC2);
2701
2702    //VSO Level delta DC check range extension
2703    uiDeltaDC1Max += (uiDeltaDC1Max>>1);
2704    uiDeltaDC2Max += (uiDeltaDC2Max>>1);
2705
2706    for( UInt uiQStepDC1 = 1; uiQStepDC1 <= uiDeltaDC1Max; uiQStepDC1++  )
2707    {
2708      Int iLevelDeltaDC1 = (Int)(uiQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
2709      xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC1 );
2710
2711      Int iTestDC1 = Clip( iPredDC1 + iLevelDeltaDC1 );
2712      for( UInt uiQStepDC2 = 1; uiQStepDC2 <= uiDeltaDC2Max; uiQStepDC2++  )
2713      {
2714        Int iLevelDeltaDC2 = (Int)(uiQStepDC2) * (Int)(( iFullDeltaDC2 < 0 ) ? -1 : 1);
2715        xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC2 );
2716
2717        Int iTestDC2 = Clip( iPredDC2 + iLevelDeltaDC2 );
2718
2719        assignWedgeDCs2Pred( pcWedgelet, piPredic, uiStride, iTestDC1, iTestDC2 );
2720
2721        Dist uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPredic, uiStride,  piOrig, uiStride, uiWidth, uiHeight, false, 0 );
2722        if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2723        {
2724          uiBestDist     = uiActDist;
2725          uiBestQStepDC1 = uiQStepDC1;
2726          uiBestQStepDC2 = uiQStepDC2;
2727        }
2728      }
2729    }
2730
2731    iFullDeltaDC1 = (Int)(uiBestQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
2732    iFullDeltaDC2 = (Int)(uiBestQStepDC2) * (Int)(( iFullDeltaDC2 < 0 ) ? -1 : 1);
2733    xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC1 );
2734    xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC2 );
2735    riDeltaDC1 = iFullDeltaDC1;
2736    riDeltaDC2 = iFullDeltaDC2;
2737  }
2738#endif
2739
2740  xDeltaDCQuantScaleDown( pcCU, riDeltaDC1 );
2741  xDeltaDCQuantScaleDown( pcCU, riDeltaDC2 );
2742}
2743
2744#if HHI_DMM_PRED_TEX && FLEX_CODING_ORDER
2745Bool TEncSearch::predIntraLumaDMMAvailable( UInt uiMode, UInt uiWidth, UInt uiHeight, Bool bDMMAvailable34 )
2746#else
2747Bool TEncSearch::predIntraLumaDMMAvailable( UInt uiMode, UInt uiWidth, UInt uiHeight )
2748#endif
2749{
2750  if( uiMode <= MAX_MODE_ID_INTRA_DIR ) return true;
2751
2752  Bool bDMMAvailable = m_pcEncCfg->getUseDMM();
2753
2754#if HHI_DMM_WEDGE_INTRA
2755  if( uiMode == DMM_WEDGE_FULL_IDX        ||
2756      uiMode == DMM_WEDGE_FULL_D_IDX      ||
2757      uiMode == DMM_WEDGE_PREDDIR_IDX     ||
2758      uiMode == DMM_WEDGE_PREDDIR_D_IDX )
2759  {
2760    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 ) )
2761    {
2762      bDMMAvailable = false;
2763    }
2764  }
2765#endif
2766#if HHI_DMM_PRED_TEX
2767  if( uiMode == DMM_WEDGE_PREDTEX_IDX     ||
2768      uiMode == DMM_WEDGE_PREDTEX_D_IDX   ||
2769      uiMode == DMM_CONTOUR_PREDTEX_IDX   ||
2770      uiMode == DMM_CONTOUR_PREDTEX_D_IDX )
2771  {
2772    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 ) )
2773    {
2774      bDMMAvailable = false;
2775    }
2776#if FLEX_CODING_ORDER
2777    if ( !bDMMAvailable34 )
2778    {
2779      bDMMAvailable = false;
2780    }
2781#endif
2782  }
2783
2784#endif
2785
2786  return bDMMAvailable;
2787}
2788
2789Void TEncSearch::xDeltaDCQuantScaleDown( TComDataCU*  pcCU, Int& riDeltaDC )
2790{
2791  Int  iSign  = riDeltaDC < 0 ? -1 : 1;
2792  UInt uiAbs  = abs( riDeltaDC );
2793
2794  Int riB = 0;
2795  Int iQp = pcCU->getQP(0);
2796  Int iMax = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) );
2797  Double dStepSize = Clip3( 1, iMax, pow( 2.0, iQp/10.0 + g_dDeltaDCsQuantOffset ) );
2798
2799  riB = roftoi( uiAbs / dStepSize );
2800
2801  riDeltaDC = riB * iSign;
2802  return;
2803}
2804#endif
2805
2806
2807Void TEncSearch::xGetInterPredictionError( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, UInt& ruiErr, Bool bHadamard )
2808{
2809  TComYuv cYuvPred;
2810  cYuvPred.create( pcYuvOrg->getWidth(), pcYuvOrg->getHeight() );
2811
2812#ifdef WEIGHT_PRED
2813  UInt uiAbsPartIdx = 0;
2814  Int iWidth = 0;
2815  Int iHeight = 0;
2816  Int iRefIdx[2];
2817  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2818
2819  iRefIdx[0] = pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiAbsPartIdx );
2820  iRefIdx[1] = pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiAbsPartIdx );
2821  if ( iRefIdx[0]>=0 && iRefIdx[1]<1 )
2822    setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_0);
2823  else
2824    setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_1);
2825
2826  motionCompensation( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2827#else
2828  motionCompensation( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2829
2830  UInt uiAbsPartIdx = 0;
2831  Int iWidth = 0;
2832  Int iHeight = 0;
2833  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2834#endif
2835
2836  DistParam cDistParam;
2837#ifdef WEIGHT_PRED
2838  cDistParam.applyWeight = false;
2839#endif
2840  m_pcRdCost->setDistParam( cDistParam,
2841                            pcYuvOrg->getLumaAddr( uiAbsPartIdx ), pcYuvOrg->getStride(),
2842                            cYuvPred .getLumaAddr( uiAbsPartIdx ), cYuvPred .getStride(),
2843                            iWidth, iHeight, m_pcEncCfg->getUseHADME() );
2844  ruiErr = cDistParam.DistFunc( &cDistParam );
2845
2846  cYuvPred.destroy();
2847}
2848
2849#if POZNAN_DBMP
2850Void TEncSearch::xGetInterPredictionError_DBMP( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, UInt& ruiErr, Bool bHadamard )
2851{
2852  TComYuv cYuvPred;
2853  cYuvPred.create( pcYuvOrg->getWidth(), pcYuvOrg->getHeight() );
2854
2855#ifdef WEIGHT_PRED
2856  UInt uiAbsPartIdx = 0;
2857  Int iWidth = 0;
2858  Int iHeight = 0;
2859  //Int iRefIdx[2];
2860  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2861
2862//???????????????????????????????????????????????????????????????????????????????????
2863  //iRefIdx[0] = pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiAbsPartIdx );
2864  //iRefIdx[1] = pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiAbsPartIdx );
2865  //if ( iRefIdx[0]>=0 && iRefIdx[1]<1 )
2866  //  setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_0);
2867  //else
2868  //  setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_1);
2869  setWpScalingDistParam( pcCU, -1, -1, REF_PIC_LIST_X);//???
2870//???????????????????????????????????????????????????????????????????????????????????
2871  motionCompensation_DBMP( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2872#else
2873  motionCompensation_DBMP( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2874
2875  UInt uiAbsPartIdx = 0;
2876  Int iWidth = 0;
2877  Int iHeight = 0;
2878  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2879#endif
2880
2881  DistParam cDistParam;
2882#ifdef WEIGHT_PRED
2883  cDistParam.applyWeight = false;
2884#endif
2885  m_pcRdCost->setDistParam( cDistParam, 
2886                            pcYuvOrg->getLumaAddr( uiAbsPartIdx ), pcYuvOrg->getStride(), 
2887                            cYuvPred .getLumaAddr( uiAbsPartIdx ), cYuvPred .getStride(), 
2888                            iWidth, iHeight, m_pcEncCfg->getUseHADME() );
2889  ruiErr = cDistParam.DistFunc( &cDistParam );
2890
2891  cYuvPred.destroy();
2892}
2893#endif
2894
2895/** estimation of best merge coding
2896 * \param pcCU
2897 * \param pcYuvOrg
2898 * \param iPUIdx
2899 * \param uiInterDir
2900 * \param pacMvField
2901 * \param uiMergeIndex
2902 * \param ruiCost
2903 * \param ruiBits
2904 * \param puhNeighCands
2905 * \param bValid
2906 * \returns Void
2907 */
2908Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost, UInt& ruiBits, UChar* puhNeighCands,Bool& bValid )
2909{
2910  TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
2911  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
2912  UInt uiNeighbourCandIdx[MRG_MAX_NUM_CANDS]; //MVs with same idx => same cand
2913
2914  for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ++ui )
2915  {
2916    uhInterDirNeighbours[ui] = 0;
2917    uiNeighbourCandIdx[ui] = 0;
2918  }
2919
2920  UInt uiAbsPartIdx = 0;
2921  Int iWidth = 0;
2922  Int iHeight = 0;
2923
2924  pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
2925  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
2926  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, uiNeighbourCandIdx );
2927
2928  UInt uiNumCand = 0;
2929  for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; ++uiMergeCand )
2930  {
2931    if( uiNeighbourCandIdx[uiMergeCand] == ( uiMergeCand + 1 ) )
2932    {
2933      uiNumCand++;
2934    }
2935  }
2936
2937  UInt uiBestSAD = MAX_UINT;
2938  UInt uiBestBitCost = MAX_UINT;
2939  UInt uiBestBits = MAX_UINT;
2940
2941  ruiCost = MAX_UINT;
2942  ruiBits = MAX_UINT;
2943
2944  bValid = false;
2945
2946  for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; ++uiMergeCand )
2947  {
2948    if( uiNeighbourCandIdx[uiMergeCand] == ( uiMergeCand + 1 ) )
2949    {
2950      bValid = true;
2951      UInt uiCostCand = MAX_UINT;
2952      UInt uiBitsCand = 0;
2953
2954      PartSize ePartSize = pcCU->getPartitionSize( 0 );
2955
2956#if POZNAN_DBMP_CALC_PRED_DATA
2957          if(uiMergeCand==POZNAN_DBMP_MRG_CAND)
2958          {
2959                pcCU->getCUMvField2nd( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[0 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2960                pcCU->getCUMvField2nd( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[1 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2961          }
2962          else
2963#endif
2964          {
2965      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[0 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2966      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[1 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2967          }
2968
2969#if POZNAN_DBMP
2970          if(uiMergeCand==POZNAN_DBMP_MRG_CAND)
2971                xGetInterPredictionError_DBMP( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2972          else
2973      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2974#else
2975      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2976#endif
2977
2978      if( uiNumCand == 1 )
2979      {
2980        uiBitsCand = 1;
2981      }
2982      else
2983      {
2984        UInt uiMergeCandIdx = uiMergeCand;
2985#if POZNAN_DBMP
2986                if(pcCU->getSlice()->getMP()->isDBMPEnabled())
2987                {
2988                        if(uiMergeCand == POZNAN_DBMP_MRG_CAND) uiMergeCandIdx = POZNAN_DBMP_MERGE_POS;
2989                        else if(uiMergeCand >= POZNAN_DBMP_MERGE_POS) uiMergeCandIdx++;
2990                }
2991#endif
2992
2993        if( uiMergeCandIdx == 0 || uiNumCand == 2 )
2994        {
2995          uiBitsCand = 2;
2996        }
2997        else if( uiMergeCandIdx == 1 || uiNumCand == 3 )
2998        {
2999          uiBitsCand = 3;
3000        }
3001        else if( uiMergeCandIdx == 2 || uiNumCand == 4 )
3002        {
3003          uiBitsCand = 4;
3004        }
3005                else if( uiMergeCandIdx == 3 || uiNumCand == 5 )
3006        {
3007          uiBitsCand = 5;
3008        }
3009        else
3010        {
3011          uiBitsCand = 6;
3012        }
3013      }
3014
3015      if ( uiCostCand < ruiCost )
3016      {
3017        ruiCost = uiCostCand;
3018        ruiBits = uiBitsCand;
3019        pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
3020        pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
3021
3022#if POZNAN_DBMP_CALC_PRED_DATA
3023                if(uiMergeCand==POZNAN_DBMP_MRG_CAND)
3024                {
3025                        TComCUMvField* pcDBMPPredMvField;
3026
3027                        pcDBMPPredMvField = pcCU->getSlice()->getMP()->getDBMPPredMVField(REF_PIC_LIST_0);
3028                        pcDBMPPredMvField->setMv(pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(uiAbsPartIdx),0);
3029                        pcDBMPPredMvField->setRefIdx(pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx),0);
3030
3031                        pcDBMPPredMvField = pcCU->getSlice()->getMP()->getDBMPPredMVField(REF_PIC_LIST_1);
3032                        pcDBMPPredMvField->setMv(pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(uiAbsPartIdx),0);
3033                        pcDBMPPredMvField->setRefIdx(pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx),0);
3034                }
3035#endif
3036
3037        uiInterDir = uhInterDirNeighbours[uiMergeCand];
3038        uiMergeIndex = uiMergeCand;
3039        for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3040        {
3041          UChar uhNeighCand = uiNeighbourCandIdx[ui];
3042          puhNeighCands[ui] = uhNeighCand;
3043        }
3044
3045        uiBestSAD = uiCostCand;
3046        uiBestBitCost = m_pcRdCost->getCost( uiBitsCand );
3047        uiBestBits = uiBitsCand;
3048      }
3049    }
3050  }
3051}
3052
3053/** search of the best candidate for inter prediction
3054 * \param pcCU
3055 * \param pcOrgYuv
3056 * \param rpcPredYuv
3057 * \param rpcResiYuv
3058 * \param rpcRecoYuv
3059 * \param bUseRes
3060 * \returns Void
3061 */
3062Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes )
3063{
3064  m_acYuvPred[0].clear();
3065  m_acYuvPred[1].clear();
3066  m_cYuvPredTemp.clear();
3067  rpcPredYuv->clear();
3068
3069  if ( !bUseRes )
3070  {
3071    rpcResiYuv->clear();
3072  }
3073
3074  rpcRecoYuv->clear();
3075
3076  TComMv        cMvSrchRngLT;
3077  TComMv        cMvSrchRngRB;
3078
3079  TComMv        cMvZero;
3080  TComMv        TempMv; //kolya
3081
3082  TComMv        cMv[2];
3083  TComMv        cMvBi[2];
3084  TComMv        cMvTemp[2][33];
3085
3086  Int           iNumPart    = pcCU->getNumPartInter();
3087  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
3088
3089  TComMv        cMvPred[2][33];
3090
3091  TComMv        cMvPredBi[2][33];
3092  Int           aaiMvpIdxBi[2][33];
3093
3094  Int           aaiMvpIdx[2][33];
3095  Int           aaiMvpNum[2][33];
3096
3097  AMVPInfo aacAMVPInfo[2][33];
3098
3099#ifdef WEIGHT_PRED
3100  Int           iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
3101#else
3102  Int           iRefIdx[2];
3103#endif
3104  Int           iRefIdxBi[2];
3105
3106  UInt          uiPartAddr;
3107  Int           iRoiWidth, iRoiHeight;
3108
3109  UInt          uiMbBits[3] = {1, 1, 0};
3110
3111  UInt          uiLastMode = 0;
3112  Int           iRefStart, iRefEnd;
3113
3114  PartSize      ePartSize = pcCU->getPartitionSize( 0 );
3115
3116#if ZERO_MVD_EST
3117  Int           aiZeroMvdMvpIdx[2] = {-1, -1};
3118  Int           aiZeroMvdRefIdx[2] = {0, 0};
3119  Int           iZeroMvdDir = -1;
3120#endif
3121
3122  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3123  {
3124    UInt          uiCost[2] = { MAX_UINT, MAX_UINT };
3125    UInt          uiCostBi  =   MAX_UINT;
3126    UInt          uiCostTemp;
3127
3128    UInt          uiBits[3];
3129    UInt          uiBitsTemp;
3130#if ZERO_MVD_EST
3131    UInt          uiZeroMvdCost = MAX_UINT;
3132    UInt          uiZeroMvdCostTemp;
3133    UInt          uiZeroMvdBitsTemp;
3134    UInt          uiZeroMvdDistTemp = MAX_UINT;
3135    UInt          auiZeroMvdBits[3];
3136#endif
3137
3138#if DCM_COMB_LIST
3139    UInt          uiCostTempL0[MAX_NUM_REF];
3140    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) uiCostTempL0[iNumRef] = MAX_UINT;
3141#endif
3142
3143    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
3144
3145    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3146
3147#if PART_MRG
3148    Bool bTestNormalMC = true;
3149    if (pcCU->getWidth( 0 ) > 8 && iNumPart == 2 && iPartIdx == 0)
3150      bTestNormalMC = false;
3151    if (bTestNormalMC)
3152    {
3153#endif
3154
3155    //  Uni-directional prediction
3156    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
3157    {
3158      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3159
3160      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
3161      {
3162#ifdef WEIGHT_PRED
3163        if ( eRefPicList == REF_PIC_LIST_0 ) setWpScalingDistParam( pcCU, iRefIdxTemp, -1 , eRefPicList);
3164        if ( eRefPicList == REF_PIC_LIST_1 ) setWpScalingDistParam( pcCU, -1, iRefIdxTemp , eRefPicList);
3165#endif
3166        uiBitsTemp = uiMbBits[iRefList];
3167        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3168        {
3169          uiBitsTemp += iRefIdxTemp+1;
3170          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3171        }
3172#if ZERO_MVD_EST
3173        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &uiZeroMvdDistTemp);
3174#else
3175        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp]);
3176#endif
3177        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
3178        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
3179
3180        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][aaiMvpNum[iRefList][iRefIdxTemp]];
3181#if ZERO_MVD_EST
3182#if DCM_COMB_LIST
3183        if ((iRefList != 1 || !pcCU->getSlice()->getNoBackPredFlag()) &&
3184            (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) <= 0 || pcCU->getSlice()->getRefIdxOfLC(eRefPicList, iRefIdxTemp)>=0))
3185#endif
3186        {
3187          uiZeroMvdBitsTemp = uiBitsTemp;
3188          uiZeroMvdBitsTemp += 2; //zero mvd bits
3189
3190          m_pcRdCost->getMotionCost( 1, 0 );
3191          uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost(uiZeroMvdBitsTemp);
3192
3193          if (uiZeroMvdCostTemp < uiZeroMvdCost)
3194          {
3195            uiZeroMvdCost = uiZeroMvdCostTemp;
3196            iZeroMvdDir = iRefList + 1;
3197            aiZeroMvdRefIdx[iRefList] = iRefIdxTemp;
3198            aiZeroMvdMvpIdx[iRefList] = aaiMvpIdx[iRefList][iRefIdxTemp];
3199            auiZeroMvdBits[iRefList] = uiZeroMvdBitsTemp;
3200          }
3201        }
3202#endif
3203
3204#if GPB_SIMPLE_UNI
3205#if DCM_COMB_LIST
3206        if ( pcCU->getSlice()->getSPS()->getUseLDC() || pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0)
3207#else
3208        if ( pcCU->getSlice()->getSPS()->getUseLDC() )
3209#endif
3210        {
3211#if DCM_COMB_LIST
3212          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 ) ) )
3213#else
3214          if ( iRefList && ( iRefIdxTemp != iRefIdx[0] || pcCU->getSlice()->getNoBackPredFlag() ) )
3215#endif
3216            {
3217#if DCM_COMB_LIST
3218              if (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
3219              {
3220                uiCostTemp = uiCostTempL0[pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
3221              }
3222              else
3223              {
3224                uiCostTemp = MAX_UINT;
3225              }
3226#else
3227              uiCostTemp = MAX_UINT;
3228#endif
3229#if DCM_COMB_LIST
3230              if ( pcCU->getSlice()->getNoBackPredFlag() || pcCU->getSlice()->getSPS()->getUseLDC() )
3231#else
3232              if ( pcCU->getSlice()->getNoBackPredFlag() )
3233#endif
3234              {
3235                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3236              }
3237#if DCM_COMB_LIST
3238              else
3239              {
3240                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
3241              }
3242#endif
3243            }
3244            else
3245            {
3246              xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3247            }
3248        }
3249        else
3250        {
3251          if (iRefList && pcCU->getSlice()->getNoBackPredFlag())
3252          {
3253            uiCostTemp = MAX_UINT;
3254            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3255          }
3256          else
3257          {
3258            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3259          }
3260        }
3261#else
3262        xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3263#endif
3264        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
3265        if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3266        {
3267          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3268        }
3269
3270#if DCM_COMB_LIST
3271        if(pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
3272        {
3273          if(iRefList==REF_PIC_LIST_0)
3274          {
3275            uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3276            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_0, iRefIdxTemp)<0)
3277            {
3278              uiCostTemp = MAX_UINT;
3279            }
3280          }
3281          else
3282          {
3283            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_1, iRefIdxTemp)<0)
3284            {
3285              uiCostTemp = MAX_UINT;
3286            }
3287          }
3288        }
3289#endif
3290
3291        if ( ( iRefList == 0 && uiCostTemp < uiCost[iRefList] ) ||
3292            ( iRefList == 1 &&  pcCU->getSlice()->getNoBackPredFlag() && iRefIdxTemp == iRefIdx[0] ) ||
3293#if DCM_COMB_LIST
3294            ( iRefList == 1 && (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0) && (iRefIdxTemp==0 || iRefIdxTemp == iRefIdx[0]) && !pcCU->getSlice()->getNoBackPredFlag() && (iRefIdxTemp == pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)) ) ||
3295#endif
3296            ( iRefList == 1 && !pcCU->getSlice()->getNoBackPredFlag() && uiCostTemp < uiCost[iRefList] ) )
3297          {
3298            uiCost[iRefList] = uiCostTemp;
3299            uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3300
3301            // set motion
3302            cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3303            iRefIdx[iRefList] = iRefIdxTemp;
3304            pcCU->getCUMvField(eRefPicList)->setAllMvField( cMv[iRefList], iRefIdx[iRefList], ePartSize, uiPartAddr, iPartIdx, 0 );
3305
3306            // storing list 1 prediction signal for iterative bi-directional prediction
3307            if ( eRefPicList == REF_PIC_LIST_1 )
3308            {
3309              TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3310              motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3311            }
3312#if DCM_COMB_LIST
3313            if ( (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) && eRefPicList == REF_PIC_LIST_0 )
3314#else
3315            if ( pcCU->getSlice()->getNoBackPredFlag() && eRefPicList == REF_PIC_LIST_0 )
3316#endif
3317            {
3318              TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3319              motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3320            }
3321          }
3322      }
3323    }
3324    //  Bi-directional prediction
3325    if ( pcCU->getSlice()->isInterB() )
3326    {
3327
3328      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
3329      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
3330
3331      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
3332      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
3333
3334      UInt uiMotBits[2] = { uiBits[0] - uiMbBits[0], uiBits[1] - uiMbBits[1] };
3335      uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3336
3337      // 4-times iteration (default)
3338      Int iNumIter = 4;
3339
3340      // fast encoder setting: only one iteration
3341      if ( m_pcEncCfg->getUseFastEnc() )
3342      {
3343        iNumIter = 1;
3344      }
3345
3346      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3347      {
3348
3349        Int         iRefList    = iIter % 2;
3350#if DCM_COMB_LIST
3351        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3352#else
3353        if ( m_pcEncCfg->getUseFastEnc() && pcCU->getSlice()->getNoBackPredFlag() )
3354#endif
3355        {
3356          iRefList = 1;
3357        }
3358        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3359
3360        Bool bChanged = false;
3361
3362#if GPB_SIMPLE
3363        if ( pcCU->getSlice()->getSPS()->getUseLDC() && iRefList )
3364        {
3365          iRefStart = iRefIdxBi[1-iRefList];
3366          iRefEnd   = iRefIdxBi[1-iRefList];
3367        }
3368        else
3369        {
3370          iRefStart = 0;
3371          iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3372        }
3373#else
3374        iRefStart = 0;
3375        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3376#endif
3377
3378#if DCM_COMB_LIST
3379        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3380#else
3381        if ( m_pcEncCfg->getUseFastEnc() && pcCU->getSlice()->getNoBackPredFlag() )
3382#endif
3383        {
3384          iRefStart = 0;
3385          iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3386        }
3387
3388        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3389        {
3390#ifdef WEIGHT_PRED
3391          if ( eRefPicList == REF_PIC_LIST_0 ) setWpScalingDistParam( pcCU, iRefIdxTemp, -1 , eRefPicList);
3392          if ( eRefPicList == REF_PIC_LIST_1 ) setWpScalingDistParam( pcCU, -1, iRefIdxTemp , eRefPicList);
3393#endif
3394          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3395          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3396          {
3397            uiBitsTemp += iRefIdxTemp+1;
3398            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3399          }
3400
3401          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][aaiMvpNum[iRefList][iRefIdxTemp]];
3402          // call ME
3403          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3404          if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3405          {
3406            xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3407            xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3408          }
3409
3410          if ( uiCostTemp < uiCostBi )
3411          {
3412            bChanged = true;
3413
3414            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3415            iRefIdxBi[iRefList] = iRefIdxTemp;
3416
3417            uiCostBi            = uiCostTemp;
3418            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3419            uiBits[2]           = uiBitsTemp;
3420
3421            //  Set motion
3422            pcCU->getCUMvField( eRefPicList )->setAllMvField( cMvBi[iRefList], iRefIdxBi[iRefList], ePartSize, uiPartAddr, iPartIdx, 0 );
3423
3424            TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3425            motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3426          }
3427        } // for loop-iRefIdxTemp
3428
3429        if ( !bChanged )
3430        {
3431          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3432          {
3433            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3434            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3435            xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3436            xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3437          }
3438          break;
3439        }
3440      } // for loop-iter
3441    } // if (B_SLICE)
3442#if ZERO_MVD_EST
3443    if ( pcCU->getSlice()->isInterB() )
3444    {
3445      m_pcRdCost->getMotionCost( 1, 0 );
3446
3447      for ( Int iL0RefIdxTemp = 0; iL0RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1; iL0RefIdxTemp++ )
3448      for ( Int iL1RefIdxTemp = 0; iL1RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1; iL1RefIdxTemp++ )
3449      {
3450        UInt uiRefIdxBitsTemp = 0;
3451        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 1 )
3452        {
3453          uiRefIdxBitsTemp += iL0RefIdxTemp+1;
3454          if ( iL0RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1 ) uiRefIdxBitsTemp--;
3455        }
3456        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3457        {
3458          uiRefIdxBitsTemp += iL1RefIdxTemp+1;
3459          if ( iL1RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiRefIdxBitsTemp--;
3460        }
3461
3462        Int iL0MVPIdx = 0;
3463        Int iL1MVPIdx = 0;
3464
3465        for (iL0MVPIdx = 0; iL0MVPIdx < aaiMvpNum[0][iL0RefIdxTemp]; iL0MVPIdx++)
3466        {
3467          for (iL1MVPIdx = 0; iL1MVPIdx < aaiMvpNum[1][iL1RefIdxTemp]; iL1MVPIdx++)
3468          {
3469            uiZeroMvdBitsTemp = uiRefIdxBitsTemp;
3470            uiZeroMvdBitsTemp += uiMbBits[2];
3471            uiZeroMvdBitsTemp += m_auiMVPIdxCost[iL0MVPIdx][aaiMvpNum[0][iL0RefIdxTemp]] + m_auiMVPIdxCost[iL1MVPIdx][aaiMvpNum[1][iL1RefIdxTemp]];
3472            uiZeroMvdBitsTemp += 4; //zero mvd for both directions
3473            pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( aacAMVPInfo[0][iL0RefIdxTemp].m_acMvCand[iL0MVPIdx], iL0RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3474            pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( aacAMVPInfo[1][iL1RefIdxTemp].m_acMvCand[iL1MVPIdx], iL1RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3475
3476            xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiZeroMvdDistTemp, m_pcEncCfg->getUseHADME() );
3477            uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost( uiZeroMvdBitsTemp );
3478            if (uiZeroMvdCostTemp < uiZeroMvdCost)
3479            {
3480              uiZeroMvdCost = uiZeroMvdCostTemp;
3481              iZeroMvdDir = 3;
3482              aiZeroMvdMvpIdx[0] = iL0MVPIdx;
3483              aiZeroMvdMvpIdx[1] = iL1MVPIdx;
3484              aiZeroMvdRefIdx[0] = iL0RefIdxTemp;
3485              aiZeroMvdRefIdx[1] = iL1RefIdxTemp;
3486              auiZeroMvdBits[2] = uiZeroMvdBitsTemp;
3487            }
3488          }
3489        }
3490      }
3491    }
3492#endif
3493#if PART_MRG
3494    } //end if bTestNormalMC
3495#endif
3496    //  Clear Motion Field
3497    {
3498      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvZero, NOT_VALID, ePartSize, uiPartAddr, iPartIdx, 0 );
3499      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvZero, NOT_VALID, ePartSize, uiPartAddr, iPartIdx, 0 );
3500    }
3501    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3502    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3503
3504    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3505    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3506    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3507    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3508
3509    UInt uiMEBits = 0;
3510    // Set Motion Field_
3511#if DCM_COMB_LIST
3512    if ( pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 ) )
3513#else
3514    if ( pcCU->getSlice()->getNoBackPredFlag() )
3515#endif
3516    {
3517      uiCost[1] = MAX_UINT;
3518    }
3519#if PART_MRG
3520    if (bTestNormalMC)
3521    {
3522#endif
3523#if ZERO_MVD_EST
3524    if (uiZeroMvdCost <= uiCostBi && uiZeroMvdCost <= uiCost[0] && uiZeroMvdCost <= uiCost[1])
3525    {
3526      if (iZeroMvdDir == 3)
3527      {
3528        uiLastMode = 2;
3529
3530        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3531        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3532
3533        pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3534
3535        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3536        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3537        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3538        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3539        uiMEBits = auiZeroMvdBits[2];
3540      }
3541      else if (iZeroMvdDir == 1)
3542      {
3543        uiLastMode = 0;
3544
3545        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3546
3547        pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3548
3549        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3550        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3551        uiMEBits = auiZeroMvdBits[0];
3552      }
3553      else if (iZeroMvdDir == 2)
3554      {
3555        uiLastMode = 1;
3556
3557        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3558
3559        pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3560
3561        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3562        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3563        uiMEBits = auiZeroMvdBits[1];
3564      }
3565      else
3566      {
3567        assert(0);
3568      }
3569    }
3570    else
3571#endif
3572    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3573    {
3574      uiLastMode = 2;
3575      {
3576        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvBi[0], iRefIdxBi[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3577        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvBi[1], iRefIdxBi[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3578      }
3579      {
3580        TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3581        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3582#if DCM_SIMPLIFIED_MVP==0
3583        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[0][iRefIdxBi[0]]))
3584        {
3585          aaiMvpIdxBi[0][iRefIdxBi[0]] = pcCU->searchMVPIdx(cMvPredBi[0][iRefIdxBi[0]], &aacAMVPInfo[0][iRefIdxBi[0]]);
3586          aaiMvpNum[0][iRefIdxBi[0]] = aacAMVPInfo[0][iRefIdxBi[0]].iN;
3587        }
3588#endif
3589      }
3590      {
3591        TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3592        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3593#if DCM_SIMPLIFIED_MVP==0
3594        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[1][iRefIdxBi[1]]))
3595        {
3596          aaiMvpIdxBi[1][iRefIdxBi[1]] = pcCU->searchMVPIdx(cMvPredBi[1][iRefIdxBi[1]], &aacAMVPInfo[1][iRefIdxBi[1]]);
3597          aaiMvpNum[1][iRefIdxBi[1]] = aacAMVPInfo[1][iRefIdxBi[1]].iN;
3598        }
3599#endif
3600      }
3601
3602      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3603
3604      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3605      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3606      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3607      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3608
3609      uiMEBits = uiBits[2];
3610    }
3611    else if ( uiCost[0] <= uiCost[1] )
3612    {
3613      uiLastMode = 0;
3614      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMv[0],   iRefIdx[0],   ePartSize, uiPartAddr, iPartIdx, 0 );
3615
3616      {
3617        TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3618        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3619#if DCM_SIMPLIFIED_MVP==0
3620        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[0][iRefIdx[0]]))
3621        {
3622          aaiMvpIdx[0][iRefIdx[0]] = pcCU->searchMVPIdx(cMvPred[0][iRefIdx[0]], &aacAMVPInfo[0][iRefIdx[0]]);
3623          aaiMvpNum[0][iRefIdx[0]] = aacAMVPInfo[0][iRefIdx[0]].iN;
3624        }
3625#endif
3626      }
3627      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3628
3629      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3630      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3631
3632      uiMEBits = uiBits[0];
3633    }
3634    else
3635    {
3636      uiLastMode = 1;
3637      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMv[1],   iRefIdx[1],   ePartSize, uiPartAddr, iPartIdx, 0 );
3638
3639      {
3640        TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3641        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3642#if DCM_SIMPLIFIED_MVP==0
3643        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[1][iRefIdx[1]]))
3644        {
3645          aaiMvpIdx[1][iRefIdx[1]] = pcCU->searchMVPIdx(cMvPred[1][iRefIdx[1]], &aacAMVPInfo[1][iRefIdx[1]]);
3646          aaiMvpNum[1][iRefIdx[1]] = aacAMVPInfo[1][iRefIdx[1]].iN;
3647        }
3648#endif
3649      }
3650      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3651
3652      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3653      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3654
3655      uiMEBits = uiBits[1];
3656    }
3657#if PART_MRG
3658    } // end if bTestNormalMC
3659#endif
3660
3661    if ( pcCU->getSlice()->getSPS()->getUseMRG() && pcCU->getPartitionSize( uiPartAddr ) == SIZE_2Nx2N )
3662    {
3663      UChar       uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
3664      UInt        uiNeighbourCandIdx  [MRG_MAX_NUM_CANDS];
3665      TComMvField cMvFieldNeighbours  [MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
3666      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3667      {
3668        uhInterDirNeighbours[ui] = 0;
3669        uiNeighbourCandIdx  [ui] = 0;
3670      }
3671      pcCU->getInterMergeCandidates( uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ), cMvFieldNeighbours, uhInterDirNeighbours, uiNeighbourCandIdx );
3672      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3673      {
3674        pcCU->setNeighbourCandIdxSubParts( ui, uiNeighbourCandIdx[ui], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3675      }
3676    }
3677
3678    if ( pcCU->getSlice()->getSPS()->getUseMRG() && pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3679    {
3680      UInt uiMRGInterDir = 0;
3681      TComMvField cMRGMvField[2];
3682      UInt uiMRGIndex = 0;
3683
3684      UInt uiMEInterDir = 0;
3685      TComMvField cMEMvField[2];
3686
3687      m_pcRdCost->getMotionCost( 1, 0 );
3688#if PART_MRG
3689      // calculate ME cost
3690      UInt uiMEError = MAX_UINT;
3691      UInt uiMECost = MAX_UINT;
3692
3693      if (bTestNormalMC)
3694      {
3695        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3696        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3697      }
3698#else
3699      // calculate ME cost
3700      UInt uiMEError = MAX_UINT;
3701      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3702      UInt uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3703#endif
3704      // save ME result.
3705      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3706      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3707      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3708
3709      // find Merge result
3710      UInt uiMRGError = MAX_UINT;
3711      UInt uiMRGBits = MAX_UINT;
3712      Bool bMergeValid = false;
3713      UChar ucNeighCand[MRG_MAX_NUM_CANDS];
3714      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3715      {
3716        ucNeighCand[ui] = 0;
3717      }
3718      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGError, uiMRGBits, ucNeighCand, bMergeValid );
3719      UInt uiMRGCost = uiMRGError + m_pcRdCost->getCost( uiMRGBits );
3720
3721      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3722      {
3723        pcCU->setNeighbourCandIdxSubParts( ui, ucNeighCand[ui], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3724      }
3725      if ( bMergeValid && uiMRGCost < uiMECost )
3726      {
3727        // set Merge result
3728        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3729        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3730        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3731
3732#if POZNAN_DBMP_CALC_PRED_DATA
3733                if(uiMRGIndex==POZNAN_DBMP_MRG_CAND)
3734                {
3735                        TComCUMvField* pcDBMPPredMvField;
3736                        pcDBMPPredMvField = pcCU->getSlice()->getMP()->getDBMPPredMVField(REF_PIC_LIST_0);
3737                        pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( pcDBMPPredMvField->getMv(0), pcDBMPPredMvField->getRefIdx(0), ePartSize, uiPartAddr, iPartIdx, 0 );                       
3738                        pcDBMPPredMvField = pcCU->getSlice()->getMP()->getDBMPPredMVField(REF_PIC_LIST_1);
3739                        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( pcDBMPPredMvField->getMv(0), pcDBMPPredMvField->getRefIdx(0), ePartSize, uiPartAddr, iPartIdx, 0 );
3740
3741                        pcCU->getCUMvField2nd( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0].getMv(), cMRGMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3742                        pcCU->getCUMvField2nd( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1].getMv(), cMRGMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3743                }
3744                else
3745#endif
3746        {
3747          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0].getMv(), cMRGMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3748          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1].getMv(), cMRGMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3749        }
3750
3751        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3752        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3753        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3754        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3755        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3756        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3757      }
3758      else
3759      {
3760        // set ME result
3761        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3762        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3763        {
3764          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0].getMv(), cMEMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3765          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1].getMv(), cMEMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3766        }
3767      }
3768#if PART_MRG
3769      if (!bTestNormalMC && !bMergeValid)
3770      {
3771        assert(pcCU->getWidth( 0 ) > 8 && iNumPart == 2 && iPartIdx == 0);
3772        return;
3773      }
3774#endif
3775    }
3776
3777    //  MC
3778    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
3779
3780  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3781
3782#ifdef WEIGHT_PRED
3783  setWpScalingDistParam( pcCU, -1, -1, REF_PIC_LIST_X );
3784#endif
3785  return;
3786}
3787
3788// AMVP
3789#if ZERO_MVD_EST
3790Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDist )
3791#else
3792Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled )
3793#endif
3794{
3795  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3796
3797  TComMv  cBestMv;
3798  Int     iBestIdx = 0;
3799  TComMv  cZeroMv;
3800  TComMv  cMvPred;
3801  UInt    uiBestCost = MAX_INT;
3802  UInt    uiPartAddr = 0;
3803  Int     iRoiWidth, iRoiHeight;
3804  Int     i;
3805
3806  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3807  // Fill the MV Candidates
3808  if (!bFilled)
3809  {
3810    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
3811  }
3812
3813  // initialize Mvp index & Mvp
3814  iBestIdx = 0;
3815  cBestMv  = pcAMVPInfo->m_acMvCand[0];
3816#if !ZERO_MVD_EST
3817  if( pcCU->getAMVPMode(uiPartAddr) == AM_NONE || (pcAMVPInfo->iN <= 1 && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL) )
3818  {
3819    rcMvPred = cBestMv;
3820
3821    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3822    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3823    return;
3824  }
3825#endif
3826  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL && bFilled)
3827  {
3828    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
3829    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
3830    return;
3831  }
3832
3833  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL)
3834  {
3835    m_cYuvPredTemp.clear();
3836#if ZERO_MVD_EST
3837    UInt uiDist;
3838#endif
3839    //-- Check Minimum Cost.
3840    for ( i = 0 ; i < pcAMVPInfo->iN; i++)
3841    {
3842      UInt uiTmpCost;
3843#if ZERO_MVD_EST
3844      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, pcAMVPInfo->iN, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3845#else
3846      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, pcAMVPInfo->iN, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3847#endif
3848      if ( uiBestCost > uiTmpCost )
3849      {
3850        uiBestCost = uiTmpCost;
3851        cBestMv   = pcAMVPInfo->m_acMvCand[i];
3852        iBestIdx  = i;
3853        #if ZERO_MVD_EST
3854        (*puiDist) = uiDist;
3855        #endif
3856      }
3857    }
3858
3859    m_cYuvPredTemp.clear();
3860  }
3861
3862  // Setting Best MVP
3863  rcMvPred = cBestMv;
3864  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3865  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3866  return;
3867}
3868
3869UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
3870{
3871  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
3872
3873  if (iNum == 1)
3874    return 0;
3875
3876  UInt uiLength = 1;
3877  Int iTemp = iIdx;
3878  if ( iTemp == 0 )
3879  {
3880    return uiLength;
3881  }
3882
3883  Bool bCodeLast = ( iNum-1 > iTemp );
3884
3885  uiLength += (iTemp-1);
3886
3887  if( bCodeLast )
3888  {
3889    uiLength++;
3890  }
3891
3892  return uiLength;
3893}
3894
3895Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
3896{
3897  if ( eCUMode == SIZE_2Nx2N )
3898  {
3899    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3900    uiBlkBit[1] = 3;
3901    uiBlkBit[2] = 5;
3902  }
3903  else if ( eCUMode == SIZE_2NxN )
3904  {
3905    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} } };
3906    if ( bPSlice )
3907    {
3908      uiBlkBit[0] = 3;
3909      uiBlkBit[1] = 0;
3910      uiBlkBit[2] = 0;
3911    }
3912    else
3913    {
3914      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3915    }
3916  }
3917  else if ( eCUMode == SIZE_Nx2N )
3918  {
3919    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} } };
3920    if ( bPSlice )
3921    {
3922      uiBlkBit[0] = 3;
3923      uiBlkBit[1] = 0;
3924      uiBlkBit[2] = 0;
3925    }
3926    else
3927    {
3928      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3929    }
3930  }
3931  else if ( eCUMode == SIZE_NxN )
3932  {
3933    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3934    uiBlkBit[1] = 3;
3935    uiBlkBit[2] = 5;
3936  }
3937  else
3938  {
3939    printf("Wrong!\n");
3940    assert( 0 );
3941  }
3942}
3943
3944Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
3945{
3946  pDst->iN = pSrc->iN;
3947  for (Int i = 0; i < pSrc->iN; i++)
3948  {
3949    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
3950  }
3951}
3952
3953Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, UInt& ruiCost )
3954{
3955  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3956
3957  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
3958
3959  if (pcAMVPInfo->iN < 2) return;
3960
3961  m_pcRdCost->getMotionCost( 1, 0 );
3962  m_pcRdCost->setCostScale ( 0    );
3963
3964  Int iBestMVPIdx = riMVPIdx;
3965
3966  m_pcRdCost->setPredictor( rcMvPred );
3967  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3968  Int iBestMvBits = iOrgMvBits;
3969
3970  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
3971  {
3972    if (iMVPIdx == riMVPIdx) continue;
3973
3974    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
3975
3976    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3977
3978    if (iMvBits < iBestMvBits)
3979    {
3980      iBestMvBits = iMvBits;
3981      iBestMVPIdx = iMVPIdx;
3982    }
3983  }
3984
3985  if (iBestMVPIdx != riMVPIdx)  //if changed
3986  {
3987    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
3988
3989    iOrgMvBits  += m_auiMVPIdxCost[riMVPIdx][pcAMVPInfo->iN];
3990    iBestMvBits += m_auiMVPIdxCost[iBestMVPIdx][pcAMVPInfo->iN];
3991
3992    riMVPIdx = iBestMVPIdx;
3993    UInt uiOrgBits = ruiBits;
3994    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
3995    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
3996  }
3997}
3998
3999UInt TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
4000                                  UInt        uiPartIdx,
4001                                  UInt      uiPartAddr,
4002                                  TComYuv*    pcOrgYuv,
4003                                  TComYuv*    pcTemplateCand,
4004                                  TComMv      cMvCand,
4005                                  Int         iMVPIdx,
4006                                  Int     iMVPNum,
4007                                  RefPicList  eRefPicList,
4008                                  Int         iRefIdx,
4009                                  Int         iSizeX,
4010                                  Int         iSizeY
4011                               #if ZERO_MVD_EST
4012                                , UInt&       ruiDist
4013                               #endif
4014                                  )
4015{
4016  UInt uiCost  = MAX_INT;
4017
4018  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
4019
4020  // prediction pattern
4021  xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand );
4022
4023#ifdef WEIGHT_PRED
4024  if ( pcCU->getSlice()->getPPS()->getUseWP() )
4025  {
4026    PartSize  ePartSize = pcCU->getPartitionSize( 0 );
4027    pcCU->getCUMvField(eRefPicList)->setAllMvField( cMvCand, iRefIdx, ePartSize, uiPartAddr, uiPartIdx, 0 );
4028#if 0
4029    TComMvField mvField;
4030    mvField.setMvField( cMvCand, iRefIdx);
4031    pcCU->getCUMvField(eRefPicList)->setAllMvField( mvField, ePartSize, uiPartAddr, 0 );
4032#endif
4033    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, uiPartIdx );
4034  }
4035#endif
4036
4037  // calc distortion
4038#if ZERO_MVD_EST
4039  m_pcRdCost->getMotionCost( 1, 0 );
4040  DistParam cDistParam;
4041  m_pcRdCost->setDistParam( cDistParam,
4042                            pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(),
4043                            pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(),
4044                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME() );
4045  // MW: check VSO here
4046  ruiDist = cDistParam.DistFunc( &cDistParam );
4047  uiCost = ruiDist + m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] );
4048#else
4049#if HHI_VSO
4050  if ( false /*m_pcRdCost->getUseVSO()*/ ) // GT: currently disabled
4051  {
4052    uiCost = m_pcRdCost->getDistVS  ( pcCU, uiPartAddr,  pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, true, 0);
4053    uiCost = (UInt) m_pcRdCost->calcRdCostVSO( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
4054  }
4055  else
4056#endif
4057  {
4058    uiCost = m_pcRdCost->getDistPart( pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, DF_SAD );
4059    uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
4060  }
4061#endif
4062  return uiCost;
4063}
4064
4065Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, UInt& ruiCost, Bool bBi  )
4066{
4067  UInt          uiPartAddr;
4068  Int           iRoiWidth;
4069  Int           iRoiHeight;
4070
4071  TComMv        cMvHalf, cMvQter;
4072  TComMv        cMvSrchRngLT;
4073  TComMv        cMvSrchRngRB;
4074
4075  TComYuv*      pcYuv = pcYuvOrg;
4076#ifdef ROUNDING_CONTROL_BIPRED
4077  Pel           pRefBufY[16384];  // 128x128
4078#endif
4079  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
4080
4081  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
4082  TComPattern*  pcPatternKey  = pcCU->getPattern        ();
4083
4084  Double        fWeight       = 1.0;
4085
4086  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
4087
4088  if ( bBi )
4089  {
4090    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
4091    pcYuv                = &m_cYuvPredTemp;
4092
4093    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
4094
4095#ifdef ROUNDING_CONTROL_BIPRED
4096    Int y;
4097    //Int x;
4098    Pel *pRefY = pcYuvOther->getLumaAddr(uiPartAddr);
4099    Int iRefStride = pcYuvOther->getStride();
4100
4101    // copy the MC block into pRefBufY
4102    for( y = 0; y < iRoiHeight; y++)
4103    {
4104      memcpy(pRefBufY+y*iRoiWidth,pRefY,sizeof(Pel)*iRoiWidth);
4105      pRefY += iRefStride;
4106    }
4107#else
4108    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight );
4109#endif
4110
4111    fWeight = 0.5;
4112  }
4113
4114  //  Search key pattern initialization
4115  pcPatternKey->initPattern( pcYuv->getLumaAddr( uiPartAddr ),
4116                            pcYuv->getCbAddr  ( uiPartAddr ),
4117                            pcYuv->getCrAddr  ( uiPartAddr ),
4118                            iRoiWidth,
4119                            iRoiHeight,
4120                            pcYuv->getStride(),
4121                            0, 0, 0, 0 );
4122
4123  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr );
4124  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride();
4125
4126  TComMv      cMvPred = *pcMvPred;
4127
4128  if ( bBi )  xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4129  else        xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4130
4131  m_pcRdCost->getMotionCost ( 1, 0 );
4132
4133  m_pcRdCost->setPredictor  ( *pcMvPred );
4134#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4135  if( pcCU->getSlice()->getSPS()->isDepth() )
4136    m_pcRdCost->setCostScale  ( 0 );
4137  else
4138#endif
4139  m_pcRdCost->setCostScale  ( 2 );
4140
4141#if HHI_INTER_VIEW_MOTION_PRED
4142  { // init inter-view regularization
4143    TComMv  cOrgDepthMapMv;
4144    Bool    bMultiviewReg = pcCU->getIViewOrgDepthMvPred( iPartIdx, eRefPicList, iRefIdxPred, cOrgDepthMapMv );
4145#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4146    if( bMultiviewReg && pcCU->getSlice()->getSPS()->isDepth() )
4147    {
4148      cOrgDepthMapMv += TComMv( 2, 2 );
4149      cOrgDepthMapMv >>= 2;
4150    }
4151#endif
4152    m_pcRdCost->setMultiviewReg( bMultiviewReg ? &cOrgDepthMapMv : 0 );
4153    if( bMultiviewReg && !bBi )
4154    {
4155      xSetSearchRange( pcCU, cOrgDepthMapMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4156    }
4157  }
4158#endif
4159
4160  //  Do integer search
4161#ifdef ROUNDING_CONTROL_BIPRED
4162  if( bBi )
4163  {
4164    xPatternSearch_Bi      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost, pRefBufY, pcCU->getSlice()->isRounding() );
4165  }
4166  else
4167  {
4168    if ( !m_iFastSearch)
4169    {
4170      xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4171    }
4172    else
4173    {
4174      rcMv = *pcMvPred;
4175      xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4176    }
4177  }
4178#else
4179  if ( !m_iFastSearch || bBi )
4180  {
4181    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4182  }
4183  else
4184  {
4185    rcMv = ( m_pcRdCost->useMultiviewReg() ? m_pcRdCost->getMultiviewOrgMvPred() : *pcMvPred );
4186    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4187  }
4188#endif
4189
4190
4191  m_pcRdCost->getMotionCost( 1, 0 );
4192#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4193  if( ! pcCU->getSlice()->getSPS()->isDepth() )
4194  {
4195#endif
4196  m_pcRdCost->setCostScale ( 1 );
4197
4198#ifdef ROUNDING_CONTROL_BIPRED
4199  if( bBi )
4200  {
4201    Bool bRound =  pcCU->getSlice()->isRounding() ;
4202    xPatternSearchFracDIF_Bi( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost, pRefBufY, bRound );
4203  }
4204  else
4205#endif
4206  {
4207    xPatternSearchFracDIF( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
4208  }
4209
4210
4211
4212  m_pcRdCost->setCostScale( 0 );
4213  rcMv <<= 2;
4214  rcMv += (cMvHalf <<= 1);
4215  rcMv +=  cMvQter;
4216#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4217  }
4218#endif
4219
4220  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
4221#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4222  if( pcCU->getSlice()->getSPS()->isDepth() )
4223    ruiCost += m_pcRdCost->getCost( uiMvBits );
4224#endif
4225
4226  ruiBits   += uiMvBits;
4227  ruiCost       = (UInt)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
4228}
4229
4230
4231Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
4232{
4233  Int  iMvShift = 2;
4234#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4235  if( pcCU->getSlice()->getSPS()->isDepth() )
4236    iMvShift = 0;
4237#endif
4238  pcCU->clipMv( cMvPred );
4239
4240  rcMvSrchRngLT.setHor( cMvPred.getHor() - (iSrchRng << iMvShift) );
4241  rcMvSrchRngLT.setVer( cMvPred.getVer() - (iSrchRng << iMvShift) );
4242
4243  rcMvSrchRngRB.setHor( cMvPred.getHor() + (iSrchRng << iMvShift) );
4244  rcMvSrchRngRB.setVer( cMvPred.getVer() + (iSrchRng << iMvShift) );
4245
4246  pcCU->clipMv        ( rcMvSrchRngLT );
4247  pcCU->clipMv        ( rcMvSrchRngRB );
4248
4249  rcMvSrchRngLT >>= iMvShift;
4250  rcMvSrchRngRB >>= iMvShift;
4251}
4252
4253#ifdef ROUNDING_CONTROL_BIPRED
4254Void TEncSearch::xPatternSearch_Bi( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD, Pel* pcRefY2, Bool bRound )
4255{
4256  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4257  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4258  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4259  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4260
4261  UInt  uiSad;
4262  Dist  uiSadBest         = RDO_DIST_MAX;
4263  Int   iBestX = 0;
4264  Int   iBestY = 0;
4265
4266  Pel*  piRefSrch;
4267
4268  //-- jclee for using the SAD function pointer
4269  m_pcRdCost->setDistParam_Bi( pcPatternKey, piRefY, iRefStride,  m_cDistParam);
4270
4271  // fast encoder decision: use subsampled SAD for integer ME
4272  if ( m_pcEncCfg->getUseFastEnc() )
4273  {
4274    if ( m_cDistParam.iRows > 8 )
4275    {
4276      m_cDistParam.iSubShift = 1;
4277    }
4278  }
4279
4280  piRefY += (iSrchRngVerTop * iRefStride);
4281  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4282  {
4283    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4284    {
4285      //  find min. distortion position
4286      piRefSrch = piRefY + x;
4287      m_cDistParam.pCur = piRefSrch;
4288      uiSad = m_cDistParam.DistFuncRnd( &m_cDistParam, pcRefY2, bRound );
4289
4290      // motion cost
4291      uiSad += m_pcRdCost->getCost( x, y );
4292
4293      // regularization cost
4294      if( m_pcRdCost->useMultiviewReg() )
4295      {
4296        uiSad += m_pcRdCost->getMultiviewRegCost( x, y );
4297      }
4298
4299      if ( uiSad < uiSadBest )
4300      {
4301        uiSadBest = uiSad;
4302        iBestX    = x;
4303        iBestY    = y;
4304      }
4305    }
4306    piRefY += iRefStride;
4307  }
4308
4309  rcMv.set( iBestX, iBestY );
4310  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4311  return;
4312}
4313#endif
4314
4315Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4316{
4317  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4318  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4319  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4320  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4321
4322  UInt  uiSad;
4323  UInt  uiSadBest         = MAX_UINT;
4324  Int   iBestX = 0;
4325  Int   iBestY = 0;
4326
4327  Pel*  piRefSrch;
4328
4329  //-- jclee for using the SAD function pointer
4330  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
4331
4332  // fast encoder decision: use subsampled SAD for integer ME
4333  if ( m_pcEncCfg->getUseFastEnc() )
4334  {
4335    if ( m_cDistParam.iRows > 8 )
4336    {
4337      m_cDistParam.iSubShift = 1;
4338    }
4339  }
4340
4341  piRefY += (iSrchRngVerTop * iRefStride);
4342  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4343  {
4344    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4345    {
4346      //  find min. distortion position
4347      piRefSrch = piRefY + x;
4348      m_cDistParam.pCur = piRefSrch;
4349#ifdef WEIGHT_PRED
4350      setDistParamComp(0);
4351#endif
4352      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
4353
4354      // motion cost
4355      uiSad += m_pcRdCost->getCost( x, y );
4356
4357      // regularization cost
4358      if( m_pcRdCost->useMultiviewReg() )
4359      {
4360        uiSad += m_pcRdCost->getMultiviewRegCost( x, y );
4361      }
4362
4363      if ( uiSad < uiSadBest )
4364      {
4365        uiSadBest = uiSad;
4366        iBestX    = x;
4367        iBestY    = y;
4368      }
4369    }
4370    piRefY += iRefStride;
4371  }
4372
4373  rcMv.set( iBestX, iBestY );
4374
4375  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4376  return;
4377}
4378
4379Void TEncSearch::xPatternSearchFast( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4380{
4381  pcCU->getMvPredLeft       ( m_acMvPredictors[0] );
4382  pcCU->getMvPredAbove      ( m_acMvPredictors[1] );
4383  pcCU->getMvPredAboveRight ( m_acMvPredictors[2] );
4384
4385  switch ( m_iFastSearch )
4386  {
4387    case 1:
4388      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD );
4389      break;
4390
4391    default:
4392      break;
4393  }
4394}
4395
4396Void TEncSearch::xTZSearch( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4397{
4398  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4399  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4400  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4401  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4402
4403  TZ_SEARCH_CONFIGURATION
4404
4405  UInt uiSearchRange = m_iSearchRange;
4406  pcCU->clipMv( rcMv );
4407#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4408  if( ! pcCU->getSlice()->getSPS()->isDepth() )
4409#endif
4410  rcMv >>= 2;
4411  // init TZSearchStruct
4412  IntTZSearchStruct cStruct;
4413  cStruct.iYStride    = iRefStride;
4414  cStruct.piRefY      = piRefY;
4415  cStruct.uiBestSad   = MAX_UINT;
4416
4417  // set rcMv (Median predictor) as start point and as best point
4418  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4419
4420  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4421  if ( bTestOtherPredictedMV )
4422  {
4423    for ( UInt index = 0; index < 3; index++ )
4424    {
4425      TComMv cMv = m_acMvPredictors[index];
4426      pcCU->clipMv( cMv );
4427#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4428      if( ! pcCU->getSlice()->getSPS()->isDepth() )
4429#endif
4430      cMv >>= 2;
4431      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4432    }
4433  }
4434
4435  // test whether zero Mv is better start point than Median predictor
4436  if ( bTestZeroVector )
4437  {
4438    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4439  }
4440
4441  // start search
4442  Int  iDist = 0;
4443  Int  iStartX = cStruct.iBestX;
4444  Int  iStartY = cStruct.iBestY;
4445
4446  // first search
4447  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4448  {
4449    if ( bFirstSearchDiamond == 1 )
4450    {
4451      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4452    }
4453    else
4454    {
4455      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4456    }
4457
4458    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4459    {
4460      break;
4461    }
4462  }
4463
4464  // test whether zero Mv is a better start point than Median predictor
4465  if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4466  {
4467    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4468    if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4469    {
4470      // test its neighborhood
4471      for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4472      {
4473        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
4474        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4475        {
4476          break;
4477        }
4478      }
4479    }
4480  }
4481
4482  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4483  if ( cStruct.uiBestDistance == 1 )
4484  {
4485    cStruct.uiBestDistance = 0;
4486    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4487  }
4488
4489  // raster search if distance is too big
4490  if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4491  {
4492    cStruct.uiBestDistance = iRaster;
4493    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4494    {
4495      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4496      {
4497        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4498      }
4499    }
4500  }
4501
4502  // raster refinement
4503  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4504  {
4505    while ( cStruct.uiBestDistance > 0 )
4506    {
4507      iStartX = cStruct.iBestX;
4508      iStartY = cStruct.iBestY;
4509      if ( cStruct.uiBestDistance > 1 )
4510      {
4511        iDist = cStruct.uiBestDistance >>= 1;
4512        if ( bRasterRefinementDiamond == 1 )
4513        {
4514          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4515        }
4516        else
4517        {
4518          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4519        }
4520      }
4521
4522      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4523      if ( cStruct.uiBestDistance == 1 )
4524      {
4525        cStruct.uiBestDistance = 0;
4526        if ( cStruct.ucPointNr != 0 )
4527        {
4528          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4529        }
4530      }
4531    }
4532  }
4533
4534  // start refinement
4535  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4536  {
4537    while ( cStruct.uiBestDistance > 0 )
4538    {
4539      iStartX = cStruct.iBestX;
4540      iStartY = cStruct.iBestY;
4541      cStruct.uiBestDistance = 0;
4542      cStruct.ucPointNr = 0;
4543      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4544      {
4545        if ( bStarRefinementDiamond == 1 )
4546        {
4547          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4548        }
4549        else
4550        {
4551          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4552        }
4553        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4554        {
4555          break;
4556        }
4557      }
4558
4559      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4560      if ( cStruct.uiBestDistance == 1 )
4561      {
4562        cStruct.uiBestDistance = 0;
4563        if ( cStruct.ucPointNr != 0 )
4564        {
4565          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4566        }
4567      }
4568    }
4569  }
4570
4571  // write out best match
4572  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4573  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4574}
4575
4576
4577#ifdef ROUNDING_CONTROL_BIPRED
4578Void TEncSearch::xPatternSearchFracDIF_Bi( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvInt, TComMv& rcMvHalf, TComMv& rcMvQter, UInt& ruiCost, Pel* piRefY2, Bool bRound )
4579{
4580  //  Reference pattern initialization (integer scale)
4581  TComPattern cPatternRoi;
4582  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4583  cPatternRoi.initPattern( piRefY +  iOffset,
4584                          NULL,
4585                          NULL,
4586                          pcPatternKey->getROIYWidth(),
4587                          pcPatternKey->getROIYHeight(),
4588                          iRefStride,
4589                          0, 0, 0, 0 );
4590  Pel*  piRef;
4591  iRefStride  = m_cYuvExt.getStride();
4592
4593  //  Half-pel refinement
4594  xExtDIFUpSamplingH ( &cPatternRoi, &m_cYuvExt );
4595  piRef = m_cYuvExt.getLumaAddr() + ((iRefStride + 4) << 2);
4596
4597  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4598  ruiCost = xPatternRefinement_Bi( pcPatternKey, piRef, iRefStride, 4, 2, rcMvHalf, piRefY2, bRound );
4599
4600  m_pcRdCost->setCostScale( 0 );
4601
4602  //  Quater-pel refinement
4603  Pel*  piSrcPel = cPatternRoi.getROIY() + (rcMvHalf.getHor() >> 1) + cPatternRoi.getPatternLStride() * (rcMvHalf.getVer() >> 1);
4604  Int*  piSrc    = m_piYuvExt  + ((m_iYuvExtStride + 4) << 2) + (rcMvHalf.getHor() << 1) + m_iYuvExtStride * (rcMvHalf.getVer() << 1);
4605  piRef += (rcMvHalf.getHor() << 1) + iRefStride * (rcMvHalf.getVer() << 1);
4606  xExtDIFUpSamplingQ ( pcPatternKey, piRef, iRefStride, piSrcPel, cPatternRoi.getPatternLStride(), piSrc, m_iYuvExtStride, m_puiDFilter[rcMvHalf.getHor()+rcMvHalf.getVer()*3] );
4607
4608  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4609  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4610  ruiCost = xPatternRefinement_Bi( pcPatternKey, piRef, iRefStride, 4, 1, rcMvQter, piRefY2, bRound );
4611}
4612
4613#endif
4614
4615Void TEncSearch::xPatternSearchFracDIF( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvInt, TComMv& rcMvHalf, TComMv& rcMvQter, UInt& ruiCost )
4616{
4617  //  Reference pattern initialization (integer scale)
4618  TComPattern cPatternRoi;
4619  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4620  cPatternRoi.initPattern( piRefY +  iOffset,
4621                          NULL,
4622                          NULL,
4623                          pcPatternKey->getROIYWidth(),
4624                          pcPatternKey->getROIYHeight(),
4625                          iRefStride,
4626                          0, 0, 0, 0 );
4627  Pel*  piRef;
4628  iRefStride  = m_cYuvExt.getStride();
4629
4630  //  Half-pel refinement
4631  xExtDIFUpSamplingH ( &cPatternRoi, &m_cYuvExt );
4632  piRef = m_cYuvExt.getLumaAddr() + ((iRefStride + 4) << 2);
4633
4634  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4635  ruiCost = xPatternRefinement( pcPatternKey, piRef, iRefStride, 4, 2, rcMvHalf   );
4636
4637  m_pcRdCost->setCostScale( 0 );
4638
4639  //  Quater-pel refinement
4640  Pel*  piSrcPel = cPatternRoi.getROIY() + (rcMvHalf.getHor() >> 1) + cPatternRoi.getPatternLStride() * (rcMvHalf.getVer() >> 1);
4641  Int*  piSrc    = m_piYuvExt  + ((m_iYuvExtStride + 4) << 2) + (rcMvHalf.getHor() << 1) + m_iYuvExtStride * (rcMvHalf.getVer() << 1);
4642  piRef += (rcMvHalf.getHor() << 1) + iRefStride * (rcMvHalf.getVer() << 1);
4643  xExtDIFUpSamplingQ ( pcPatternKey, piRef, iRefStride, piSrcPel, cPatternRoi.getPatternLStride(), piSrc, m_iYuvExtStride, m_puiDFilter[rcMvHalf.getHor()+rcMvHalf.getVer()*3] );
4644
4645  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4646  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4647  ruiCost = xPatternRefinement( pcPatternKey, piRef, iRefStride, 4, 1, rcMvQter );
4648}
4649
4650Void TEncSearch::predInterSkipSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv )
4651{
4652  SliceType eSliceType = pcCU->getSlice()->getSliceType();
4653  if ( eSliceType == I_SLICE )
4654    return;
4655
4656  if ( eSliceType == P_SLICE && pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 )
4657  {
4658    pcCU->setInterDirSubParts( 1, 0, 0, pcCU->getDepth( 0 ) );
4659
4660    TComMv cMv;
4661    TComMv cZeroMv;
4662    xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_0, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_0 )->getAMVPInfo()->iN > 0?  true:false) );
4663    pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4664    pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4665    pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cZeroMv, NOT_VALID, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4666    pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4667
4668    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, 0, 0, pcCU->getDepth(0));
4669    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, 0, 0, pcCU->getDepth(0));
4670
4671    //  Motion compensation
4672    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_0 );
4673
4674  }
4675  else if ( eSliceType == B_SLICE &&
4676           pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 &&
4677           pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0  )
4678  {
4679    TComMv cMv;
4680    TComMv cZeroMv;
4681
4682    if (pcCU->getInterDir(0)!=2)
4683    {
4684      xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_0, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_0 )->getAMVPInfo()->iN > 0?  true:false) );
4685      pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4686      pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 ); //unnecessary
4687    }
4688
4689    if (pcCU->getInterDir(0)!=1)
4690    {
4691      xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_1, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_1 )->getAMVPInfo()->iN > 0?  true:false) );
4692      pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4693      pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4694    }
4695
4696    motionCompensation ( pcCU, rpcPredYuv );
4697
4698  }
4699  else
4700  {
4701    assert( 0 );
4702  }
4703
4704  return;
4705}
4706
4707/** encode residual and calculate rate-distortion for a CU block
4708 * \param pcCU
4709 * \param pcYuvOrg
4710 * \param pcYuvPred
4711 * \param rpcYuvResi
4712 * \param rpcYuvResiBest
4713 * \param rpcYuvRec
4714 * \param bSkipRes
4715 * \returns Void
4716 */
4717Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred, TComYuv*& rpcYuvResi, TComYuv*& rpcYuvResiBest, TComYuv*& rpcYuvRec, TComYuv*& rpcYuvResPrd, Bool bSkipRes )
4718{
4719  if ( pcCU->isIntra(0) )
4720  {
4721    return;
4722  }
4723
4724  PredMode  ePredMode    = pcCU->getPredictionMode( 0 );
4725  Bool      bHighPass    = pcCU->getSlice()->getDepth() ? true : false;
4726  UInt      uiBits       = 0, uiBitsBest = 0;
4727  Dist      uiDistortion = 0, uiDistortionBest = 0;
4728
4729  UInt      uiWidth      = pcCU->getWidth ( 0 );
4730  UInt      uiHeight     = pcCU->getHeight( 0 );
4731
4732  //  No residual coding : SKIP mode
4733  if ( ePredMode == MODE_SKIP && bSkipRes )
4734  {
4735    rpcYuvResi->clear();
4736
4737    pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4738
4739#if HHI_INTER_VIEW_RESIDUAL_PRED
4740    // add residual prediction
4741    if( pcCU->getResPredFlag( 0 ) )
4742    {
4743      rpcYuvRec->add( rpcYuvResPrd, uiWidth, uiHeight );
4744      rpcYuvRec->clip( uiWidth, uiHeight );
4745    }
4746#endif
4747
4748#if HHI_VSO   
4749    if ( m_pcRdCost->getUseVSO() )
4750    {
4751      uiDistortion = m_pcRdCost->getDistVS( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight     , false, 0 );
4752    }
4753    else
4754#endif
4755    {
4756      uiDistortion = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4757      + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4758      + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4759    }
4760   
4761
4762    if( m_bUseSBACRD )
4763      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4764
4765    m_pcEntropyCoder->resetBits();
4766#if HHI_MPI
4767    if( pcCU->getTextureModeDepth( 0 ) == -1 )
4768    {
4769#endif
4770    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4771#if HHI_MRG_SKIP
4772    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, 0, true );
4773#else
4774    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 ) //if ( ref. frame list0 has at least 1 entry )
4775    {
4776      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_0);
4777    }
4778    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 ) //if ( ref. frame list1 has at least 1 entry )
4779    {
4780      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_1);
4781    }
4782#endif
4783#if HHI_INTER_VIEW_RESIDUAL_PRED
4784    m_pcEntropyCoder->encodeResPredFlag( pcCU, 0, 0, true );
4785#endif
4786#if HHI_MPI
4787    }
4788#endif
4789
4790    uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4791    pcCU->getTotalBits()       = uiBits;
4792    pcCU->getTotalDistortion() = uiDistortion;
4793
4794#if HHI_VSO
4795    if ( m_pcRdCost->getUseLambdaScaleVSO() )
4796    {
4797      pcCU->getTotalCost() = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );
4798    }
4799    else
4800#endif
4801    {
4802      pcCU->getTotalCost() = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4803    }
4804
4805    if( m_bUseSBACRD )
4806      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4807
4808    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4809    pcCU->setTrIdxSubParts( 0, 0, pcCU->getDepth(0) );
4810
4811#if HHI_VSO
4812    // set Model
4813    if( m_pcRdCost->getUseRenModel() )
4814    {
4815      Pel*  piSrc       = rpcYuvRec->getLumaAddr();
4816      UInt  uiSrcStride = rpcYuvRec->getStride();
4817      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4818    }
4819#endif
4820
4821    return;
4822  }
4823
4824  //  Residual coding.
4825  UInt    uiQp, uiQpBest = 0, uiQpMin, uiQpMax;
4826  Double  dCost, dCostBest = MAX_DOUBLE;
4827
4828  UInt uiBestTrMode = 0;
4829
4830  UInt uiTrLevel = 0;
4831  if( (pcCU->getWidth(0) > pcCU->getSlice()->getSPS()->getMaxTrSize()) )
4832  {
4833    while( pcCU->getWidth(0) > (pcCU->getSlice()->getSPS()->getMaxTrSize()<<uiTrLevel) ) uiTrLevel++;
4834  }
4835  UInt uiMaxTrMode = pcCU->getSlice()->getSPS()->getMaxTrDepth() + uiTrLevel;
4836
4837  while((uiWidth>>uiMaxTrMode) < (g_uiMaxCUWidth>>g_uiMaxCUDepth)) uiMaxTrMode--;
4838
4839  uiQpMin      = bHighPass ? Min( MAX_QP, Max( MIN_QP, pcCU->getQP(0) - m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4840  uiQpMax      = bHighPass ? Min( MAX_QP, Max( MIN_QP, pcCU->getQP(0) + m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4841
4842  pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4843
4844#if HHI_INTER_VIEW_RESIDUAL_PRED
4845  // add residual prediction
4846  if( pcCU->getResPredFlag( 0 ) )
4847  {
4848    rpcYuvRec->add( rpcYuvResPrd, uiWidth, uiHeight );
4849  }
4850#endif
4851#if HHI_INTERVIEW_SKIP
4852  if( bSkipRes)
4853  {
4854    rpcYuvResi->clear() ;
4855  }
4856  else
4857  {
4858    rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4859  }
4860#else
4861  rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4862#endif
4863
4864  for ( uiQp = uiQpMin; uiQp <= uiQpMax; uiQp++ )
4865  {
4866    pcCU->setQPSubParts( uiQp, 0, pcCU->getDepth(0) );
4867    dCost = 0.;
4868    uiBits = 0;
4869    uiDistortion = 0;
4870    if( m_bUseSBACRD )
4871    {
4872      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4873    }
4874
4875    Dist uiZeroDistortion = 0;
4876#if HHI_VSO
4877    if ( m_pcRdCost->getUseVSO() )
4878    {
4879      m_cYuvRecTemp.create( pcYuvPred->getWidth(), pcYuvPred->getHeight()  );
4880    }
4881#endif
4882
4883    xEstimateResidualQT( pcCU, 0, 0, pcYuvOrg, rpcYuvRec, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4884
4885#if HHI_VSO
4886    if ( m_pcRdCost->getUseVSO() )
4887    {
4888      m_cYuvRecTemp.destroy();
4889    }
4890#endif
4891
4892
4893    double dZeroCost;
4894#if HHI_VSO
4895    if( m_pcRdCost->getUseLambdaScaleVSO() )
4896    {
4897      dZeroCost = m_pcRdCost->calcRdCostVSO( 0, uiZeroDistortion );
4898    }
4899    else
4900#endif
4901    {
4902      dZeroCost = m_pcRdCost->calcRdCost( 0, uiZeroDistortion );
4903    }
4904
4905    if ( dZeroCost < dCost )
4906    {
4907      dCost        = dZeroCost;
4908      uiBits       = 0;
4909      uiDistortion = uiZeroDistortion;
4910
4911      const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4912      ::memset( pcCU->getTransformIdx()      , 0, uiQPartNum * sizeof(UChar) );
4913      ::memset( pcCU->getCbf( TEXT_LUMA )    , 0, uiQPartNum * sizeof(UChar) );
4914      ::memset( pcCU->getCbf( TEXT_CHROMA_U ), 0, uiQPartNum * sizeof(UChar) );
4915      ::memset( pcCU->getCbf( TEXT_CHROMA_V ), 0, uiQPartNum * sizeof(UChar) );
4916      ::memset( pcCU->getCoeffY()            , 0, uiWidth * uiHeight * sizeof( TCoeff )      );
4917      ::memset( pcCU->getCoeffCb()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4918      ::memset( pcCU->getCoeffCr()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4919    }
4920    else
4921    {
4922      xSetResidualQTData( pcCU, 0, NULL, pcCU->getDepth(0), false );
4923    }
4924
4925    if( m_bUseSBACRD )
4926    {
4927      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4928    }
4929#if 0 // check
4930    {
4931      m_pcEntropyCoder->resetBits();
4932      m_pcEntropyCoder->encodeCoeff( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
4933      const UInt uiBitsForCoeff = m_pcEntropyCoder->getNumberOfWrittenBits();
4934      if( m_bUseSBACRD )
4935      {
4936        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4937      }
4938      if( uiBitsForCoeff != uiBits )
4939        assert( 0 );
4940    }
4941#endif
4942    uiBits = 0;
4943    {
4944      TComYuv *pDummy = NULL;
4945      xAddSymbolBitsInter( pcCU, 0, 0, uiBits, pDummy, NULL, pDummy );
4946    }
4947
4948    Double dExactCost;
4949#if HHI_VSO
4950    if( m_pcRdCost->getUseLambdaScaleVSO() )
4951    {
4952      dExactCost = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );;
4953    }
4954    else
4955#endif
4956    {
4957      dExactCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4958    }
4959
4960    dCost = dExactCost;
4961
4962    if ( dCost < dCostBest )
4963    {
4964      if ( !pcCU->getQtRootCbf( 0 ) )
4965      {
4966        rpcYuvResiBest->clear();
4967      }
4968      else
4969      {
4970        xSetResidualQTData( pcCU, 0, rpcYuvResiBest, pcCU->getDepth(0), true );
4971      }
4972
4973      if( uiQpMin != uiQpMax && uiQp != uiQpMax )
4974      {
4975        const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4976        ::memcpy( m_puhQTTempTrIdx, pcCU->getTransformIdx(),        uiQPartNum * sizeof(UChar) );
4977        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA ),     uiQPartNum * sizeof(UChar) );
4978        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPartNum * sizeof(UChar) );
4979        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPartNum * sizeof(UChar) );
4980        ::memcpy( m_pcQTTempCoeffY,  pcCU->getCoeffY(),  uiWidth * uiHeight * sizeof( TCoeff )      );
4981        ::memcpy( m_pcQTTempCoeffCb, pcCU->getCoeffCb(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4982        ::memcpy( m_pcQTTempCoeffCr, pcCU->getCoeffCr(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4983      }
4984      uiBitsBest       = uiBits;
4985      uiDistortionBest = uiDistortion;
4986      dCostBest        = dCost;
4987      uiQpBest         = uiQp;
4988
4989      if( m_bUseSBACRD )
4990      {
4991        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4992      }
4993    }
4994
4995#if HHI_VSO
4996    // reset Model
4997    if( m_pcRdCost->getUseRenModel() )
4998    {
4999      Pel*  piSrc       = pcYuvOrg->getLumaAddr();
5000      UInt  uiSrcStride = pcYuvOrg->getStride();
5001      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
5002    }
5003#endif
5004  }
5005
5006  assert ( dCostBest != MAX_DOUBLE );
5007
5008  if( uiQpMin != uiQpMax && uiQpBest != uiQpMax )
5009  {
5010    if( m_bUseSBACRD )
5011    {
5012      assert( 0 ); // check
5013      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
5014    }
5015    // copy best cbf and trIdx to pcCU
5016    const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
5017    ::memcpy( pcCU->getTransformIdx(),       m_puhQTTempTrIdx,  uiQPartNum * sizeof(UChar) );
5018    ::memcpy( pcCU->getCbf( TEXT_LUMA ),     m_puhQTTempCbf[0], uiQPartNum * sizeof(UChar) );
5019    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPartNum * sizeof(UChar) );
5020    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPartNum * sizeof(UChar) );
5021    ::memcpy( pcCU->getCoeffY(),  m_pcQTTempCoeffY,  uiWidth * uiHeight * sizeof( TCoeff )      );
5022    ::memcpy( pcCU->getCoeffCb(), m_pcQTTempCoeffCb, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
5023    ::memcpy( pcCU->getCoeffCr(), m_pcQTTempCoeffCr, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
5024  }
5025  rpcYuvRec->addClip ( rpcYuvRec, rpcYuvResiBest, 0, uiWidth );
5026
5027  // update with clipped distortion and cost (qp estimation loop uses unclipped values)
5028
5029#if HHI_VSO
5030  if ( m_pcRdCost->getUseVSO() )
5031  {
5032    uiDistortionBest = m_pcRdCost->getDistVS  ( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight, false, 0    );
5033  }
5034  else
5035#endif
5036  {
5037    uiDistortionBest = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
5038    + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
5039    + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
5040  }
5041
5042#if HHI_VSO
5043  if ( m_pcRdCost->getUseLambdaScaleVSO() )
5044  {
5045    dCostBest = m_pcRdCost->calcRdCostVSO( uiBitsBest, uiDistortionBest );
5046  }
5047  else
5048#endif
5049  {
5050    dCostBest = m_pcRdCost->calcRdCost( uiBitsBest, uiDistortionBest );
5051  }
5052
5053  pcCU->getTotalBits()       = uiBitsBest;
5054  pcCU->getTotalDistortion() = uiDistortionBest;
5055  pcCU->getTotalCost()       = dCostBest;
5056
5057  if ( pcCU->isSkipped(0) )
5058  {
5059    uiBestTrMode = 0;
5060    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
5061  }
5062
5063  pcCU->setQPSubParts( uiQpBest, 0, pcCU->getDepth(0) );
5064
5065  // set Model
5066#if HHI_VSO
5067  if( m_pcRdCost->getUseRenModel() )
5068  {
5069    Pel*  piSrc       = rpcYuvRec->getLumaAddr();
5070    UInt  uiSrcStride = rpcYuvRec->getStride();
5071    m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
5072  }
5073#endif
5074}
5075
5076Void 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 )
5077{
5078  const UInt uiTrMode = uiDepth - pcCU->getDepth( 0 );
5079
5080  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5081  const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
5082
5083#if HHI_RQT_FORCE_SPLIT_ACC2_PU
5084#if HHI_RQT_FORCE_SPLIT_NxN
5085  const Bool bNxNOK = pcCU->getPartitionSize( 0 ) == SIZE_NxN && uiTrMode > 0;
5086#else
5087  const Bool bNxNOK = pcCU->getPartitionSize( 0 ) == SIZE_NxN;
5088#endif
5089#if HHI_RQT_FORCE_SPLIT_RECT
5090  const Bool bSymmetricOK  = pcCU->getPartitionSize( 0 ) >= SIZE_2NxN  && pcCU->getPartitionSize( 0 ) < SIZE_NxN   && uiTrMode > 0;
5091#else
5092  const Bool bSymmetricOK  = pcCU->getPartitionSize( 0 ) >= SIZE_2NxN  && pcCU->getPartitionSize( 0 ) < SIZE_NxN;
5093#endif
5094  const Bool bNoForceSplit = pcCU->getPartitionSize( 0 ) == SIZE_2Nx2N || bNxNOK || bSymmetricOK;
5095  const Bool bCheckFull    = bNoForceSplit && ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
5096#else
5097  const Bool bCheckFull    = ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
5098#endif
5099
5100  const Bool bCheckSplit  = ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
5101
5102  assert( bCheckFull || bCheckSplit );
5103
5104  Bool  bCodeChroma   = true;
5105  UInt  uiTrModeC     = uiTrMode;
5106  UInt  uiLog2TrSizeC = uiLog2TrSize-1;
5107  if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
5108  {
5109    uiLog2TrSizeC++;
5110    uiTrModeC    --;
5111    UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
5112    bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
5113  }
5114
5115  const UInt uiSetCbf = 1 << uiTrMode;
5116  // code full block
5117  Double dSingleCost = MAX_DOUBLE;
5118  UInt uiSingleBits = 0;
5119  Dist uiSingleDist = 0;
5120  UInt uiAbsSumY = 0, uiAbsSumU = 0, uiAbsSumV = 0;
5121
5122  if( m_bUseSBACRD )
5123  {
5124    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5125  }
5126
5127  if( bCheckFull )
5128  {
5129    const UInt uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
5130    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5131    TCoeff *pcCoeffCurrY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5132    TCoeff *pcCoeffCurrU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5133    TCoeff *pcCoeffCurrV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5134
5135    pcCU->setTrIdxSubParts( uiDepth - pcCU->getDepth( 0 ), uiAbsPartIdx, uiDepth );
5136    if (m_pcEncCfg->getUseRDOQ())
5137    {
5138      m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, 1<< uiLog2TrSize, TEXT_LUMA );
5139    }
5140#if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
5141    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ) + pcCU->getQpOffsetForTextCU(uiAbsPartIdx, false), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA );
5142#else
5143    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA );
5144#endif
5145    m_pcTrQuant->transformNxN( pcCU, pcResi->getLumaAddr( uiAbsPartIdx ), pcResi->getStride (), pcCoeffCurrY, 1<< uiLog2TrSize,    1<< uiLog2TrSize,    uiAbsSumY, TEXT_LUMA,     uiAbsPartIdx );
5146
5147    pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5148
5149    if( bCodeChroma )
5150    {
5151      if (m_pcEncCfg->getUseRDOQ())
5152      {
5153        m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, 1<<uiLog2TrSizeC, TEXT_CHROMA );
5154      }
5155#if POZNAN_TEXTURE_TU_DELTA_QP_ACCORDING_TO_DEPTH
5156      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ) + pcCU->getQpOffsetForTextCU(uiAbsPartIdx, false), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
5157#else
5158      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
5159#endif
5160      m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr( uiAbsPartIdx ), pcResi->getCStride(), pcCoeffCurrU, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiAbsSumU, TEXT_CHROMA_U, uiAbsPartIdx );
5161      m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr( uiAbsPartIdx ), pcResi->getCStride(), pcCoeffCurrV, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiAbsSumV, TEXT_CHROMA_V, uiAbsPartIdx );
5162      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5163      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5164    }
5165
5166    m_pcEntropyCoder->resetBits();
5167
5168    if (pcCU->getSlice()->getSymbolMode())<