source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncSearch.cpp @ 42

Last change on this file since 42 was 42, checked in by tech, 12 years ago

Nokia (Flexible Coding Order)
Ericsson ( High Level Syntax )
changes

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