source: 3DVCSoftware/branches/0.2-HHI/source/Lib/TLibEncoder/TEncSearch.cpp @ 21

Last change on this file since 21 was 5, checked in by hhi, 13 years ago

Clean version with cfg-files

  • Property svn:eol-style set to native
File size: 216.3 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2011, ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35/** \file     TEncSearch.cpp
36 \brief    encoder search class
37 */
38
39#include "../TLibCommon/TypeDef.h"
40#include "../TLibCommon/TComMotionInfo.h"
41#include "TEncSearch.h"
42
43static TComMv s_acMvRefineH[9] =
44{
45  TComMv(  0,  0 ), // 0
46  TComMv(  0, -1 ), // 1
47  TComMv(  0,  1 ), // 2
48  TComMv( -1,  0 ), // 3
49  TComMv(  1,  0 ), // 4
50  TComMv( -1, -1 ), // 5
51  TComMv(  1, -1 ), // 6
52  TComMv( -1,  1 ), // 7
53  TComMv(  1,  1 )  // 8
54};
55
56static TComMv s_acMvRefineQ[9] =
57{
58  TComMv(  0,  0 ), // 0
59  TComMv(  0, -1 ), // 1
60  TComMv(  0,  1 ), // 2
61  TComMv( -1, -1 ), // 5
62  TComMv(  1, -1 ), // 6
63  TComMv( -1,  0 ), // 3
64  TComMv(  1,  0 ), // 4
65  TComMv( -1,  1 ), // 7
66  TComMv(  1,  1 )  // 8
67};
68
69static UInt s_auiDFilter[9] =
70{
71  0, 1, 0,
72  2, 3, 2,
73  0, 1, 0
74};
75
76TEncSearch::TEncSearch()
77{
78  m_ppcQTTempCoeffY  = NULL;
79  m_ppcQTTempCoeffCb = NULL;
80  m_ppcQTTempCoeffCr = NULL;
81  m_pcQTTempCoeffY   = NULL;
82  m_pcQTTempCoeffCb  = NULL;
83  m_pcQTTempCoeffCr  = NULL;
84  m_puhQTTempTrIdx   = NULL;
85  m_puhQTTempCbf[0] = m_puhQTTempCbf[1] = m_puhQTTempCbf[2] = NULL;
86  m_pcQTTempTComYuv  = NULL;
87  m_pcEncCfg = NULL;
88  m_pcEntropyCoder = NULL;
89  m_pTempPel = NULL;
90#ifdef WEIGHT_PRED
91  setWpScalingDistParam( NULL, -1, -1, REF_PIC_LIST_X );
92#endif
93}
94
95TEncSearch::~TEncSearch()
96{
97  if ( m_pTempPel )
98  {
99    delete [] m_pTempPel;
100    m_pTempPel = NULL;
101  }
102
103  if ( m_pcEncCfg )
104  {
105    const UInt uiNumLayersAllocated = m_pcEncCfg->getQuadtreeTULog2MaxSize()-m_pcEncCfg->getQuadtreeTULog2MinSize()+1;
106    for( UInt ui = 0; ui < uiNumLayersAllocated; ++ui )
107    {
108      delete[] m_ppcQTTempCoeffY[ui];
109      delete[] m_ppcQTTempCoeffCb[ui];
110      delete[] m_ppcQTTempCoeffCr[ui];
111      m_pcQTTempTComYuv[ui].destroy();
112    }
113  }
114  delete[] m_ppcQTTempCoeffY;
115  delete[] m_ppcQTTempCoeffCb;
116  delete[] m_ppcQTTempCoeffCr;
117  delete[] m_pcQTTempCoeffY;
118  delete[] m_pcQTTempCoeffCb;
119  delete[] m_pcQTTempCoeffCr;
120  delete[] m_puhQTTempTrIdx;
121  delete[] m_puhQTTempCbf[0];
122  delete[] m_puhQTTempCbf[1];
123  delete[] m_puhQTTempCbf[2];
124  delete[] m_pcQTTempTComYuv;
125}
126
127void TEncSearch::init(TEncCfg*      pcEncCfg,
128                      TComTrQuant*  pcTrQuant,
129                      Int           iSearchRange,
130                      Int           bipredSearchRange,
131                      Int           iFastSearch,
132                      Int           iMaxDeltaQP,
133                      TEncEntropy*  pcEntropyCoder,
134                      TComRdCost*   pcRdCost,
135                      TEncSbac*** pppcRDSbacCoder,
136                      TEncSbac*   pcRDGoOnSbacCoder
137                      )
138{
139  m_pcEncCfg             = pcEncCfg;
140  m_pcTrQuant            = pcTrQuant;
141  m_iSearchRange         = iSearchRange;
142  m_bipredSearchRange    = bipredSearchRange;
143  m_iFastSearch          = iFastSearch;
144  m_iMaxDeltaQP          = iMaxDeltaQP;
145  m_pcEntropyCoder       = pcEntropyCoder;
146  m_pcRdCost             = pcRdCost;
147
148  m_pppcRDSbacCoder     = pppcRDSbacCoder;
149  m_pcRDGoOnSbacCoder   = pcRDGoOnSbacCoder;
150
151  m_bUseSBACRD          = pppcRDSbacCoder ? true : false;
152
153  for (Int iDir = 0; iDir < 2; iDir++)
154  {
155    for (Int iRefIdx = 0; iRefIdx < 33; iRefIdx++)
156    {
157      m_aaiAdaptSR[iDir][iRefIdx] = iSearchRange;
158    }
159  }
160
161  m_puiDFilter = s_auiDFilter + 4;
162
163  // initialize motion cost
164  m_pcRdCost->initRateDistortionModel( m_iSearchRange << 2 );
165
166  for( Int iNum = 0; iNum < AMVP_MAX_NUM_CANDS+1; iNum++)
167  {
168    for( Int iIdx = 0; iIdx < AMVP_MAX_NUM_CANDS; iIdx++)
169    {
170      if (iIdx < iNum)
171        m_auiMVPIdxCost[iIdx][iNum] = xGetMvpIdxBits(iIdx, iNum);
172      else
173        m_auiMVPIdxCost[iIdx][iNum] = MAX_INT;
174    }
175  }
176
177  initTempBuff();
178
179  m_pTempPel = new Pel[g_uiMaxCUWidth*g_uiMaxCUHeight];
180
181  const UInt uiNumLayersToAllocate = pcEncCfg->getQuadtreeTULog2MaxSize()-pcEncCfg->getQuadtreeTULog2MinSize()+1;
182  m_ppcQTTempCoeffY  = new TCoeff*[uiNumLayersToAllocate];
183  m_ppcQTTempCoeffCb = new TCoeff*[uiNumLayersToAllocate];
184  m_ppcQTTempCoeffCr = new TCoeff*[uiNumLayersToAllocate];
185  m_pcQTTempCoeffY   = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight   ];
186  m_pcQTTempCoeffCb  = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
187  m_pcQTTempCoeffCr  = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
188
189  const UInt uiNumPartitions = 1<<(g_uiMaxCUDepth<<1);
190  m_puhQTTempTrIdx   = new UChar  [uiNumPartitions];
191  m_puhQTTempCbf[0]  = new UChar  [uiNumPartitions];
192  m_puhQTTempCbf[1]  = new UChar  [uiNumPartitions];
193  m_puhQTTempCbf[2]  = new UChar  [uiNumPartitions];
194  m_pcQTTempTComYuv  = new TComYuv[uiNumLayersToAllocate];
195  for( UInt ui = 0; ui < uiNumLayersToAllocate; ++ui )
196  {
197    m_ppcQTTempCoeffY[ui]  = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight   ];
198    m_ppcQTTempCoeffCb[ui] = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
199    m_ppcQTTempCoeffCr[ui] = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
200    m_pcQTTempTComYuv[ui].create( g_uiMaxCUWidth, g_uiMaxCUHeight );
201  }
202}
203
204#if FASTME_SMOOTHER_MV
205#define FIRSTSEARCHSTOP     1
206#else
207#define FIRSTSEARCHSTOP     0
208#endif
209
210#define TZ_SEARCH_CONFIGURATION                                                                                 \
211const Int  iRaster                  = 5;  /* TZ soll von aussen ?ergeben werden */                            \
212const Bool bTestOtherPredictedMV    = 0;                                                                      \
213const Bool bTestZeroVector          = 1;                                                                      \
214const Bool bTestZeroVectorStart     = 0;                                                                      \
215const Bool bTestZeroVectorStop      = 0;                                                                      \
216const Bool bFirstSearchDiamond      = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
217const Bool bFirstSearchStop         = FIRSTSEARCHSTOP;                                                        \
218const UInt uiFirstSearchRounds      = 3;  /* first search stop X rounds after best match (must be >=1) */     \
219const Bool bEnableRasterSearch      = 1;                                                                      \
220const Bool bAlwaysRasterSearch      = 0;  /* ===== 1: BETTER but factor 2 slower ===== */                     \
221const Bool bRasterRefinementEnable  = 0;  /* enable either raster refinement or star refinement */            \
222const Bool bRasterRefinementDiamond = 0;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
223const Bool bStarRefinementEnable    = 1;  /* enable either star refinement or raster refinement */            \
224const Bool bStarRefinementDiamond   = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
225const Bool bStarRefinementStop      = 0;                                                                      \
226const UInt uiStarRefinementRounds   = 2;  /* star refinement stop X rounds after best match (must be >=1) */  \
227
228
229__inline Void TEncSearch::xTZSearchHelp( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance )
230{
231  UInt  uiSad;
232
233  Pel*  piRefSrch;
234
235  piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;
236
237  //-- jclee for using the SAD function pointer
238  m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );
239
240  // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
241  if ( m_pcEncCfg->getUseFastEnc() )
242  {
243    if ( m_cDistParam.iRows > 8 )
244    {
245      m_cDistParam.iSubShift = 1;
246    }
247  }
248#ifdef WEIGHT_PRED
249  setDistParamComp(0);  // Y component
250#endif
251
252  // distortion
253  uiSad = m_cDistParam.DistFunc( &m_cDistParam );
254
255  // motion cost
256  uiSad += m_pcRdCost->getCost( iSearchX, iSearchY );
257
258  // regularization cost
259  if( m_pcRdCost->useMultiviewReg() )
260  {
261    uiSad += m_pcRdCost->getMultiviewRegCost( iSearchX, iSearchY );
262  }
263
264  if( uiSad < rcStruct.uiBestSad )
265  {
266    rcStruct.uiBestSad      = uiSad;
267    rcStruct.iBestX         = iSearchX;
268    rcStruct.iBestY         = iSearchY;
269    rcStruct.uiBestDistance = uiDistance;
270    rcStruct.uiBestRound    = 0;
271    rcStruct.ucPointNr      = ucPointNr;
272  }
273}
274
275__inline Void TEncSearch::xTZ2PointSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB )
276{
277  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
278  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
279  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
280  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
281
282  // 2 point search,                   //   1 2 3
283  // check only the 2 untested points  //   4 0 5
284  // around the start point            //   6 7 8
285  Int iStartX = rcStruct.iBestX;
286  Int iStartY = rcStruct.iBestY;
287  switch( rcStruct.ucPointNr )
288  {
289    case 1:
290    {
291      if ( (iStartX - 1) >= iSrchRngHorLeft )
292      {
293        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY, 0, 2 );
294      }
295      if ( (iStartY - 1) >= iSrchRngVerTop )
296      {
297        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
298      }
299    }
300      break;
301    case 2:
302    {
303      if ( (iStartY - 1) >= iSrchRngVerTop )
304      {
305        if ( (iStartX - 1) >= iSrchRngHorLeft )
306        {
307          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
308        }
309        if ( (iStartX + 1) <= iSrchRngHorRight )
310        {
311          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
312        }
313      }
314    }
315      break;
316    case 3:
317    {
318      if ( (iStartY - 1) >= iSrchRngVerTop )
319      {
320        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
321      }
322      if ( (iStartX + 1) <= iSrchRngHorRight )
323      {
324        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
325      }
326    }
327      break;
328    case 4:
329    {
330      if ( (iStartX - 1) >= iSrchRngHorLeft )
331      {
332        if ( (iStartY + 1) <= iSrchRngVerBottom )
333        {
334          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
335        }
336        if ( (iStartY - 1) >= iSrchRngVerTop )
337        {
338          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
339        }
340      }
341    }
342      break;
343    case 5:
344    {
345      if ( (iStartX + 1) <= iSrchRngHorRight )
346      {
347        if ( (iStartY - 1) >= iSrchRngVerTop )
348        {
349          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
350        }
351        if ( (iStartY + 1) <= iSrchRngVerBottom )
352        {
353          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
354        }
355      }
356    }
357      break;
358    case 6:
359    {
360      if ( (iStartX - 1) >= iSrchRngHorLeft )
361      {
362        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY , 0, 2 );
363      }
364      if ( (iStartY + 1) <= iSrchRngVerBottom )
365      {
366        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
367      }
368    }
369      break;
370    case 7:
371    {
372      if ( (iStartY + 1) <= iSrchRngVerBottom )
373      {
374        if ( (iStartX - 1) >= iSrchRngHorLeft )
375        {
376          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
377        }
378        if ( (iStartX + 1) <= iSrchRngHorRight )
379        {
380          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
381        }
382      }
383    }
384      break;
385    case 8:
386    {
387      if ( (iStartX + 1) <= iSrchRngHorRight )
388      {
389        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
390      }
391      if ( (iStartY + 1) <= iSrchRngVerBottom )
392      {
393        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
394      }
395    }
396      break;
397    default:
398    {
399      assert( false );
400    }
401      break;
402  } // switch( rcStruct.ucPointNr )
403}
404
405__inline Void TEncSearch::xTZ8PointSquareSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
406{
407  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
408  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
409  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
410  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
411
412  // 8 point search,                   //   1 2 3
413  // search around the start point     //   4 0 5
414  // with the required  distance       //   6 7 8
415  assert( iDist != 0 );
416  const Int iTop        = iStartY - iDist;
417  const Int iBottom     = iStartY + iDist;
418  const Int iLeft       = iStartX - iDist;
419  const Int iRight      = iStartX + iDist;
420  rcStruct.uiBestRound += 1;
421
422  if ( iTop >= iSrchRngVerTop ) // check top
423  {
424    if ( iLeft >= iSrchRngHorLeft ) // check top left
425    {
426      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iTop, 1, iDist );
427    }
428    // top middle
429    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
430
431    if ( iRight <= iSrchRngHorRight ) // check top right
432    {
433      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iTop, 3, iDist );
434    }
435  } // check top
436  if ( iLeft >= iSrchRngHorLeft ) // check middle left
437  {
438    xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
439  }
440  if ( iRight <= iSrchRngHorRight ) // check middle right
441  {
442    xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
443  }
444  if ( iBottom <= iSrchRngVerBottom ) // check bottom
445  {
446    if ( iLeft >= iSrchRngHorLeft ) // check bottom left
447    {
448      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iBottom, 6, iDist );
449    }
450    // check bottom middle
451    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
452
453    if ( iRight <= iSrchRngHorRight ) // check bottom right
454    {
455      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iBottom, 8, iDist );
456    }
457  } // check bottom
458}
459
460__inline Void TEncSearch::xTZ8PointDiamondSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
461{
462  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
463  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
464  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
465  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
466
467  // 8 point search,                   //   1 2 3
468  // search around the start point     //   4 0 5
469  // with the required  distance       //   6 7 8
470  assert ( iDist != 0 );
471  const Int iTop        = iStartY - iDist;
472  const Int iBottom     = iStartY + iDist;
473  const Int iLeft       = iStartX - iDist;
474  const Int iRight      = iStartX + iDist;
475  rcStruct.uiBestRound += 1;
476
477  if ( iDist == 1 ) // iDist == 1
478  {
479    if ( iTop >= iSrchRngVerTop ) // check top
480    {
481      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
482    }
483    if ( iLeft >= iSrchRngHorLeft ) // check middle left
484    {
485      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
486    }
487    if ( iRight <= iSrchRngHorRight ) // check middle right
488    {
489      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
490    }
491    if ( iBottom <= iSrchRngVerBottom ) // check bottom
492    {
493      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
494    }
495  }
496  else // if (iDist != 1)
497  {
498    if ( iDist <= 8 )
499    {
500      const Int iTop_2      = iStartY - (iDist>>1);
501      const Int iBottom_2   = iStartY + (iDist>>1);
502      const Int iLeft_2     = iStartX - (iDist>>1);
503      const Int iRight_2    = iStartX + (iDist>>1);
504
505      if (  iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
506          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
507      {
508        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iTop,      2, iDist    );
509        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iTop_2,    1, iDist>>1 );
510        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2,    3, iDist>>1 );
511        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,    iStartY,   4, iDist    );
512        xTZSearchHelp( pcPatternKey, rcStruct, iRight,   iStartY,   5, iDist    );
513        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iBottom_2, 6, iDist>>1 );
514        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, iDist>>1 );
515        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iBottom,   7, iDist    );
516      }
517      else // check border
518      {
519        if ( iTop >= iSrchRngVerTop ) // check top
520        {
521          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
522        }
523        if ( iTop_2 >= iSrchRngVerTop ) // check half top
524        {
525          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
526          {
527            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iTop_2, 1, (iDist>>1) );
528          }
529          if ( iRight_2 <= iSrchRngHorRight ) // check half right
530          {
531            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2, 3, (iDist>>1) );
532          }
533        } // check half top
534        if ( iLeft >= iSrchRngHorLeft ) // check left
535        {
536          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
537        }
538        if ( iRight <= iSrchRngHorRight ) // check right
539        {
540          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
541        }
542        if ( iBottom_2 <= iSrchRngVerBottom ) // check half bottom
543        {
544          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
545          {
546            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iBottom_2, 6, (iDist>>1) );
547          }
548          if ( iRight_2 <= iSrchRngHorRight ) // check half right
549          {
550            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, (iDist>>1) );
551          }
552        } // check half bottom
553        if ( iBottom <= iSrchRngVerBottom ) // check bottom
554        {
555          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
556        }
557      } // check border
558    }
559    else // iDist > 8
560    {
561      if ( iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
562          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
563      {
564        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop,    0, iDist );
565        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,   iStartY, 0, iDist );
566        xTZSearchHelp( pcPatternKey, rcStruct, iRight,  iStartY, 0, iDist );
567        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
568        for ( Int index = 1; index < 4; index++ )
569        {
570          Int iPosYT = iTop    + ((iDist>>2) * index);
571          Int iPosYB = iBottom - ((iDist>>2) * index);
572          Int iPosXL = iStartX - ((iDist>>2) * index);
573          Int iPosXR = iStartX + ((iDist>>2) * index);
574          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
575          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
576          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
577          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
578        }
579      }
580      else // check border
581      {
582        if ( iTop >= iSrchRngVerTop ) // check top
583        {
584          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 0, iDist );
585        }
586        if ( iLeft >= iSrchRngHorLeft ) // check left
587        {
588          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 0, iDist );
589        }
590        if ( iRight <= iSrchRngHorRight ) // check right
591        {
592          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 0, iDist );
593        }
594        if ( iBottom <= iSrchRngVerBottom ) // check bottom
595        {
596          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
597        }
598        for ( Int index = 1; index < 4; index++ )
599        {
600          Int iPosYT = iTop    + ((iDist>>2) * index);
601          Int iPosYB = iBottom - ((iDist>>2) * index);
602          Int iPosXL = iStartX - ((iDist>>2) * index);
603          Int iPosXR = iStartX + ((iDist>>2) * index);
604
605          if ( iPosYT >= iSrchRngVerTop ) // check top
606          {
607            if ( iPosXL >= iSrchRngHorLeft ) // check left
608            {
609              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
610            }
611            if ( iPosXR <= iSrchRngHorRight ) // check right
612            {
613              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
614            }
615          } // check top
616          if ( iPosYB <= iSrchRngVerBottom ) // check bottom
617          {
618            if ( iPosXL >= iSrchRngHorLeft ) // check left
619            {
620              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
621            }
622            if ( iPosXR <= iSrchRngHorRight ) // check right
623            {
624              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
625            }
626          } // check bottom
627        } // for ...
628      } // check border
629    } // iDist <= 8
630  } // iDist == 1
631}
632
633#ifdef ROUNDING_CONTROL_BIPRED
634UInt TEncSearch::xPatternRefinement_Bi    ( TComPattern* pcPatternKey, Pel* piRef, Int iRefStride, Int iIntStep, Int iFrac, TComMv& rcMvFrac, Pel* pcRef2, Bool bRound, Bool bInterview )
635{
636  UInt  uiDist;
637  UInt  uiDistBest  = MAX_UINT;
638  UInt  uiDirecBest = 0;
639
640  Pel*  piRefPos;
641
642  m_pcRdCost->setDistParam_Bi( pcPatternKey, piRef, iRefStride, iIntStep, m_cDistParam, m_pcEncCfg->getUseHADME() );
643
644  TComMv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
645
646  for (UInt i = 0; i < 9; i++)
647  {
648    TComMv cMvTest = pcMvRefine[i];
649    cMvTest += rcMvFrac;
650    piRefPos = piRef + (pcMvRefine[i].getHor() + iRefStride * pcMvRefine[i].getVer()) * iFrac;
651    m_cDistParam.pCur = piRefPos;
652    uiDist = m_cDistParam.DistFuncRnd( &m_cDistParam, pcRef2, bRound );
653    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
654
655    if ( uiDist < uiDistBest )
656    {
657      uiDistBest  = uiDist;
658      uiDirecBest = i;
659    }
660  }
661
662  rcMvFrac = pcMvRefine[uiDirecBest];
663
664  return uiDistBest;
665}
666#endif
667
668//<--
669
670UInt TEncSearch::xPatternRefinement( TComPattern* pcPatternKey, Pel* piRef, Int iRefStride, Int iIntStep, Int iFrac, TComMv& rcMvFrac )
671{
672  UInt  uiDist;
673  UInt  uiDistBest  = MAX_UINT;
674  UInt  uiDirecBest = 0;
675
676  Pel*  piRefPos;
677  m_pcRdCost->setDistParam( pcPatternKey, piRef, iRefStride, iIntStep, m_cDistParam, m_pcEncCfg->getUseHADME() );
678
679  TComMv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
680
681  for (UInt i = 0; i < 9; i++)
682  {
683    TComMv cMvTest = pcMvRefine[i];
684    cMvTest += rcMvFrac;
685    piRefPos = piRef + (pcMvRefine[i].getHor() + iRefStride * pcMvRefine[i].getVer()) * iFrac;
686    m_cDistParam.pCur = piRefPos;
687#ifdef WEIGHT_PRED
688    setDistParamComp(0);  // Y component
689#endif
690    uiDist = m_cDistParam.DistFunc( &m_cDistParam );
691    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
692
693    if ( uiDist < uiDistBest )
694    {
695      uiDistBest  = uiDist;
696      uiDirecBest = i;
697    }
698  }
699
700  rcMvFrac = pcMvRefine[uiDirecBest];
701
702  return uiDistBest;
703}
704
705Void
706TEncSearch::xEncSubdivCbfQT( TComDataCU*  pcCU,
707                            UInt         uiTrDepth,
708                            UInt         uiAbsPartIdx,
709                            Bool         bLuma,
710                            Bool         bChroma )
711{
712  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
713  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
714  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
715  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
716
717#if CAVLC_RQT_CBP
718  if(pcCU->getSlice()->getSymbolMode() == 0)
719  {
720    if(bLuma && bChroma)
721    {
722      m_pcEntropyCoder->m_pcEntropyCoderIf->codeCbfTrdiv( pcCU, uiAbsPartIdx, uiFullDepth);
723    }
724    else
725    {
726      UInt uiFlagPattern = m_pcEntropyCoder->m_pcEntropyCoderIf->xGetFlagPattern(pcCU, uiAbsPartIdx, uiFullDepth);
727      if(bLuma)
728      {
729        if(uiTrDepth==0 || pcCU->getCbf(uiAbsPartIdx, TEXT_LUMA, uiTrDepth-1))
730          m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, uiTrDepth);
731        if(uiFlagPattern & 0x01)
732          m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, uiFullDepth );
733      }
734      else if(bChroma)
735      {
736        if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
737        {
738          if(uiTrDepth==0 || pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth-1))
739            m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth);
740          if(uiTrDepth==0 || pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth-1))
741            m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth);
742        }
743        if(uiFlagPattern & 0x01)
744          m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, uiFullDepth );
745      }
746    }
747  }
748#endif
749
750#if CAVLC_RQT_CBP
751  if(pcCU->getSlice()->getSymbolMode())
752  {
753#endif
754  if( pcCU->getPredictionMode(0) == MODE_INTRA && pcCU->getPartitionSize(0) == SIZE_NxN && uiTrDepth == 0 )
755  {
756    assert( uiSubdiv );
757  }
758  else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
759  {
760    assert( uiSubdiv );
761  }
762  else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
763  {
764    assert( !uiSubdiv );
765  }
766  else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
767  {
768    assert( !uiSubdiv );
769  }
770  else
771  {
772    assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
773    if( bLuma )
774    {
775      m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, uiFullDepth );
776    }
777  }
778#if CAVLC_RQT_CBP
779  }
780#endif
781
782  if( uiSubdiv )
783  {
784    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
785    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
786    {
787      xEncSubdivCbfQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, bLuma, bChroma );
788    }
789    return;
790  }
791
792  if(pcCU->getSlice()->getSymbolMode())
793  {
794    //===== Cbfs =====
795    if( bLuma )
796    {
797      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
798    }
799    if( bChroma )
800    {
801      Bool bCodeChroma = true;
802      if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
803      {
804        assert( uiTrDepth > 0 );
805        UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
806        bCodeChroma  = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
807      }
808      if( bCodeChroma )
809      {
810        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
811        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
812      }
813    }
814  }
815}
816
817
818Void
819TEncSearch::xEncCoeffQT( TComDataCU*  pcCU,
820                        UInt         uiTrDepth,
821                        UInt         uiAbsPartIdx,
822                        TextType     eTextType,
823                        Bool         bRealCoeff )
824{
825  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
826  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
827  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
828  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
829  UInt  uiChroma        = ( eTextType != TEXT_LUMA ? 1 : 0 );
830
831  if( uiSubdiv )
832  {
833    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
834#if !CAVLC_RQT_CBP
835    if ( pcCU->getSlice()->getSymbolMode() || pcCU->getCbf( uiAbsPartIdx, eTextType, uiTrDepth ))
836    {
837      if(pcCU->getSlice()->getSymbolMode() == 0)
838      {
839        if( eTextType == TEXT_LUMA || uiLog2TrafoSize-1 > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
840          m_pcEntropyCoder->m_pcEntropyCoderIf->codeBlockCbf(pcCU, uiAbsPartIdx, eTextType, uiTrDepth + 1, uiQPartNum, true);
841      }
842#endif
843      for( UInt uiPart = 0; uiPart < 4; uiPart++ )
844      {
845        xEncCoeffQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, eTextType, bRealCoeff );
846      }
847#if !CAVLC_RQT_CBP
848    }
849#endif
850    return;
851  }
852
853  if( eTextType != TEXT_LUMA && uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
854  {
855    assert( uiTrDepth > 0 );
856    uiTrDepth--;
857    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
858    Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
859    if( !bFirstQ )
860    {
861      return;
862    }
863  }
864
865  //===== coefficients =====
866  UInt    uiWidth         = pcCU->getWidth  ( 0 ) >> ( uiTrDepth + uiChroma );
867  UInt    uiHeight        = pcCU->getHeight ( 0 ) >> ( uiTrDepth + uiChroma );
868  UInt    uiCoeffOffset   = ( pcCU->getPic()->getMinCUWidth() * pcCU->getPic()->getMinCUHeight() * uiAbsPartIdx ) >> ( uiChroma << 1 );
869  UInt    uiQTLayer       = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrafoSize;
870  TCoeff* pcCoeff         = 0;
871  switch( eTextType )
872  {
873    case TEXT_LUMA:     pcCoeff = ( bRealCoeff ? pcCU->getCoeffY () : m_ppcQTTempCoeffY [uiQTLayer] );  break;
874    case TEXT_CHROMA_U: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCb() : m_ppcQTTempCoeffCb[uiQTLayer] );  break;
875    case TEXT_CHROMA_V: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCr() : m_ppcQTTempCoeffCr[uiQTLayer] );  break;
876    default:            assert(0);
877  }
878  pcCoeff += uiCoeffOffset;
879
880  m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiWidth, uiHeight, uiFullDepth, eTextType, false );
881}
882
883
884Void
885TEncSearch::xEncIntraHeader( TComDataCU*  pcCU,
886                            UInt         uiTrDepth,
887                            UInt         uiAbsPartIdx,
888                            Bool         bLuma,
889                            Bool         bChroma )
890{
891  if( bLuma )
892  {
893    // CU header
894    if( uiAbsPartIdx == 0 )
895    {
896      if( !pcCU->getSlice()->isIntra() )
897      {
898        m_pcEntropyCoder->encodeSkipFlag( pcCU, 0, true );
899        m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
900      }
901
902      m_pcEntropyCoder  ->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
903    }
904    // luma prediction mode
905    if( pcCU->getPartitionSize(0) == SIZE_2Nx2N )
906    {
907      if( uiAbsPartIdx == 0 )
908      {
909        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, 0 );
910      }
911    }
912    else
913    {
914      UInt uiQNumParts = pcCU->getTotalNumPart() >> 2;
915      if( uiTrDepth == 0 )
916      {
917        assert( uiAbsPartIdx == 0 );
918        for( UInt uiPart = 0; uiPart < 4; uiPart++ )
919        {
920          m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPart * uiQNumParts );
921        }
922      }
923      else if( ( uiAbsPartIdx % uiQNumParts ) == 0 )
924      {
925        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiAbsPartIdx );
926      }
927    }
928  }
929  if( bChroma )
930  {
931    // chroma prediction mode
932    if( uiAbsPartIdx == 0 )
933    {
934      m_pcEntropyCoder->encodeIntraDirModeChroma( pcCU, 0, true );
935    }
936  }
937}
938
939
940UInt
941TEncSearch::xGetIntraBitsQT( TComDataCU*  pcCU,
942                            UInt         uiTrDepth,
943                            UInt         uiAbsPartIdx,
944                            Bool         bLuma,
945                            Bool         bChroma,
946                            Bool         bRealCoeff /* just for test */
947                            )
948{
949  m_pcEntropyCoder->resetBits();
950  xEncIntraHeader ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
951  xEncSubdivCbfQT ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
952 
953  if( bLuma )
954  {
955    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_LUMA,      bRealCoeff );
956  }
957  if( bChroma )
958  {
959    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_U,  bRealCoeff );
960    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_V,  bRealCoeff );
961  }
962  UInt   uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
963  return uiBits;
964}
965
966
967
968Void
969TEncSearch::xIntraCodingLumaBlk( TComDataCU* pcCU,
970                                UInt        uiTrDepth,
971                                UInt        uiAbsPartIdx,
972                                TComYuv*    pcOrgYuv,
973                                TComYuv*    pcPredYuv,
974                                TComYuv*    pcResiYuv,
975                                Dist&       ruiDist
976                                )
977{
978  UInt    uiLumaPredMode    = pcCU     ->getLumaIntraDir     ( uiAbsPartIdx );
979  UInt    uiFullDepth       = pcCU     ->getDepth   ( 0 )  + uiTrDepth;
980  UInt    uiWidth           = pcCU     ->getWidth   ( 0 ) >> uiTrDepth;
981  UInt    uiHeight          = pcCU     ->getHeight  ( 0 ) >> uiTrDepth;
982  UInt    uiStride          = pcOrgYuv ->getStride  ();
983  Pel*    piOrg             = pcOrgYuv ->getLumaAddr( uiAbsPartIdx );
984  Pel*    piPred            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
985  Pel*    piResi            = pcResiYuv->getLumaAddr( uiAbsPartIdx );
986  Pel*    piReco            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
987
988  UInt    uiLog2TrSize      = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
989  UInt    uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
990  UInt    uiNumCoeffPerInc  = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
991  TCoeff* pcCoeff           = m_ppcQTTempCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;
992  Pel*    piRecQt           = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
993  UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
994
995  UInt    uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
996  Pel*    piRecIPred        = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
997  UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getStride  ();
998
999  //===== init availability pattern =====
1000  Bool  bAboveAvail = false;
1001  Bool  bLeftAvail  = false;
1002  pcCU->getPattern()->initPattern   ( pcCU, uiTrDepth, uiAbsPartIdx );
1003  pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1004
1005#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1006  if( uiLumaPredMode > MAX_MODE_ID_INTRA_DIR )
1007  {
1008    predIntraLumaDMM( pcCU, uiAbsPartIdx, uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail, true );
1009  }
1010  else
1011#endif
1012  {
1013    //===== get prediction signal =====
1014    predIntraLumaAng( pcCU->getPattern(), uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1015  }
1016
1017  //===== get residual signal =====
1018  {
1019    // get residual
1020    Pel*  pOrg    = piOrg;
1021    Pel*  pPred   = piPred;
1022    Pel*  pResi   = piResi;
1023    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1024    {
1025      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1026      {
1027        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1028      }
1029      pOrg  += uiStride;
1030      pResi += uiStride;
1031      pPred += uiStride;
1032    }
1033  }
1034
1035  //===== transform and quantization =====
1036  //--- init rate estimation arrays for RDOQ ---
1037  if( m_pcEncCfg->getUseRDOQ() )
1038  {
1039    m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, TEXT_LUMA );
1040  }
1041  //--- transform and quantization ---
1042  UInt uiAbsSum = 0;
1043  pcCU       ->setTrIdxSubParts ( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1044  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      TComYuv cTempYuv; cTempYuv.create( uiWidth, uiHeight ); cTempYuv.clear();
1929      Pel* piTempY      = cTempYuv.getLumaAddr();
1930
1931      fillTexturePicTempBlock( pcCU, uiPartOffset, piTempY, uiWidth, uiHeight );
1932
1933      piTempY = cTempYuv.getLumaAddr();
1934
1935      UInt uiTexTabIdx  = 0;
1936      Int  iTexDeltaDC1 = 0;
1937      Int  iTexDeltaDC2 = 0;
1938      findWedgeTexMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTexTabIdx, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail, WedgeDist_SAD, piTempY ); 
1939      pcCU->setWedgePredTexTabIdxSubParts  ( uiTexTabIdx,  uiPartOffset, uiDepth + uiInitTrDepth );
1940      pcCU->setWedgePredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1941      pcCU->setWedgePredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1942
1943      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDTEX_IDX;
1944      uiRdModeList[ uiNewMaxMode++ ] = DMM_WEDGE_PREDTEX_D_IDX;
1945
1946      if ( uiWidth > 4 )
1947      {
1948        piTempY = cTempYuv.getLumaAddr();
1949
1950        iTexDeltaDC1 = 0;
1951        iTexDeltaDC2 = 0;
1952
1953        findContourPredTex( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail, piTempY );
1954        pcCU->setContourPredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1955        pcCU->setContourPredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1956
1957        uiRdModeList[ uiNewMaxMode++ ] = DMM_CONTOUR_PREDTEX_IDX;
1958        uiRdModeList[ uiNewMaxMode++ ] = DMM_CONTOUR_PREDTEX_D_IDX;
1959      }
1960
1961      cTempYuv.destroy();
1962#endif
1963    }
1964#endif
1965    //===== check modes (using r-d costs) =====
1966#if HHI_RQT_INTRA_SPEEDUP_MOD
1967    UInt   uiSecondBestMode  = MAX_UINT;
1968    Double dSecondBestPUCost = MAX_DOUBLE;
1969#endif
1970
1971    UInt    uiBestPUMode  = 0;
1972    Dist    uiBestPUDistY = 0;
1973    Dist    uiBestPUDistC = 0;
1974    Double  dBestPUCost   = MAX_DOUBLE;
1975    for( UInt uiMode = uiMinMode; uiMode < uiNewMaxMode; uiMode++ )
1976    {
1977      // set luma prediction mode
1978      UInt uiOrgMode = uiRdModeList[uiMode];
1979
1980#if (!REFERENCE_SAMPLE_PADDING)
1981#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1982      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail, uiWidth, uiHeight, pcCU, uiPartOffset ) )
1983        continue;
1984#else
1985      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
1986        continue;
1987#endif
1988#else
1989#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1990      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
1991        continue;
1992#endif
1993#endif
1994
1995      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
1996
1997      // set context models
1998      if( m_bUseSBACRD )
1999      {
2000        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2001      }
2002
2003      // determine residual for partition
2004      Dist   uiPUDistY = 0;
2005      Dist   uiPUDistC = 0;
2006      Double dPUCost   = 0.0;
2007
2008
2009      // reset Model
2010#if HHI_VSO
2011      if( m_pcRdCost->getUseRenModel() )
2012      {
2013        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2014      }
2015#endif
2016
2017#if HHI_RQT_INTRA_SPEEDUP
2018      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );
2019#else
2020      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
2021#endif
2022
2023      // check r-d cost
2024      if( dPUCost < dBestPUCost )
2025      {
2026#if HHI_RQT_INTRA_SPEEDUP_MOD
2027        uiSecondBestMode  = uiBestPUMode;
2028        dSecondBestPUCost = dBestPUCost;
2029#endif
2030        uiBestPUMode  = uiOrgMode;
2031        uiBestPUDistY = uiPUDistY;
2032        uiBestPUDistC = uiPUDistC;
2033        dBestPUCost   = dPUCost;
2034
2035        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2036
2037        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2038        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2039        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2040        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2041        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2042
2043      }
2044#if HHI_RQT_INTRA_SPEEDUP_MOD
2045      else if( dPUCost < dSecondBestPUCost )
2046      {
2047        uiSecondBestMode  = uiOrgMode;
2048        dSecondBestPUCost = dPUCost;
2049      }
2050#endif
2051    } // Mode loop
2052
2053#if HHI_RQT_INTRA_SPEEDUP
2054#if HHI_RQT_INTRA_SPEEDUP_MOD
2055    for( UInt ui =0; ui < 2; ++ui )
2056#endif
2057    {
2058#if HHI_RQT_INTRA_SPEEDUP_MOD
2059      UInt uiOrgMode   = ui ? uiSecondBestMode  : uiBestPUMode;
2060      if( uiOrgMode == MAX_UINT )
2061      {
2062        break;
2063      }
2064#else
2065      UInt uiOrgMode = uiBestPUMode;
2066#endif
2067
2068#if (!REFERENCE_SAMPLE_PADDING)
2069#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2070      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail, uiWidth, uiHeight, pcCU, uiPartOffset ) )
2071        continue;
2072#else
2073      if ( !predIntraLumaDirAvailable( uiOrgMode, uiWidthBit, bAboveAvail, bLeftAvail ) )
2074        continue;
2075#endif
2076#else
2077#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2078      if( m_pcEncCfg->isDepthCoder() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
2079        continue;
2080#endif
2081#endif
2082
2083      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2084
2085      // set context models
2086      if( m_bUseSBACRD )
2087      {
2088        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2089      }
2090
2091      // determine residual for partition
2092      Dist   uiPUDistY = 0;
2093      Dist   uiPUDistC = 0;
2094      Double dPUCost   = 0.0;
2095
2096#if HHI_VSO
2097      // reset Model
2098      if( m_pcRdCost->getUseRenModel() )
2099      {
2100        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2101      }
2102#endif
2103
2104      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, false, dPUCost );
2105
2106      // check r-d cost
2107      if( dPUCost < dBestPUCost )
2108      {
2109        uiBestPUMode  = uiOrgMode;
2110        uiBestPUDistY = uiPUDistY;
2111        uiBestPUDistC = uiPUDistC;
2112        dBestPUCost   = dPUCost;
2113
2114        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2115
2116        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2117        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2118        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2119        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2120        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2121
2122      }
2123    } // Mode loop
2124#endif
2125
2126    //--- update overall distortion ---
2127    uiOverallDistY += uiBestPUDistY;
2128    uiOverallDistC += uiBestPUDistC;
2129
2130    //--- update transform index and cbf ---
2131    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2132    ::memcpy( pcCU->getTransformIdx()       + uiPartOffset, m_puhQTTempTrIdx,  uiQPartNum * sizeof( UChar ) );
2133    ::memcpy( pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, m_puhQTTempCbf[0], uiQPartNum * sizeof( UChar ) );
2134    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, m_puhQTTempCbf[1], uiQPartNum * sizeof( UChar ) );
2135    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, m_puhQTTempCbf[2], uiQPartNum * sizeof( UChar ) );
2136
2137    //--- set reconstruction for next intra prediction blocks ---
2138    if( uiPU != uiNumPU - 1 )
2139    {
2140      Bool bSkipChroma  = false;
2141      Bool bChromaSame  = false;
2142      UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> ( pcCU->getDepth(0) + uiInitTrDepth ) ] + 2;
2143      if( !bLumaOnly && uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
2144      {
2145        assert( uiInitTrDepth  > 0 );
2146        bSkipChroma  = ( uiPU != 0 );
2147        bChromaSame  = true;
2148      }
2149
2150      UInt    uiCompWidth   = pcCU->getWidth ( 0 ) >> uiInitTrDepth;
2151      UInt    uiCompHeight  = pcCU->getHeight( 0 ) >> uiInitTrDepth;
2152      UInt    uiZOrder      = pcCU->getZorderIdxInCU() + uiPartOffset;
2153      Pel*    piDes         = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
2154      UInt    uiDesStride   = pcCU->getPic()->getPicYuvRec()->getStride();
2155      Pel*    piSrc         = pcRecoYuv->getLumaAddr( uiPartOffset );
2156      UInt    uiSrcStride   = pcRecoYuv->getStride();
2157      for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2158      {
2159        for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2160        {
2161          piDes[ uiX ] = piSrc[ uiX ];
2162        }
2163      }
2164
2165#if HHI_VSO
2166      // set model
2167      if( m_pcRdCost->getUseRenModel() )
2168      {
2169        piSrc = pcRecoYuv->getLumaAddr( uiPartOffset );
2170        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piSrc, uiSrcStride, uiCompWidth, uiCompHeight);
2171      }
2172#endif
2173
2174      if( !bLumaOnly && !bSkipChroma )
2175      {
2176        if( !bChromaSame )
2177        {
2178          uiCompWidth   >>= 1;
2179          uiCompHeight  >>= 1;
2180        }
2181        piDes         = pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder );
2182        uiDesStride   = pcCU->getPic()->getPicYuvRec()->getCStride();
2183        piSrc         = pcRecoYuv->getCbAddr( uiPartOffset );
2184        uiSrcStride   = pcRecoYuv->getCStride();
2185        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2186        {
2187          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2188          {
2189            piDes[ uiX ] = piSrc[ uiX ];
2190          }
2191        }
2192        piDes         = pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder );
2193        piSrc         = pcRecoYuv->getCrAddr( uiPartOffset );
2194        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2195        {
2196          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2197          {
2198            piDes[ uiX ] = piSrc[ uiX ];
2199          }
2200        }
2201      }
2202    }
2203
2204    //=== update PU data ====
2205    pcCU->setLumaIntraDirSubParts     ( uiBestPUMode, uiPartOffset, uiDepth + uiInitTrDepth );
2206    pcCU->copyToPic                   ( uiDepth, uiPU, uiInitTrDepth );
2207  } // PU loop
2208
2209
2210  if( uiNumPU > 1 )
2211  { // set Cbf for all blocks
2212    UInt uiCombCbfY = 0;
2213    UInt uiCombCbfU = 0;
2214    UInt uiCombCbfV = 0;
2215    UInt uiPartIdx  = 0;
2216    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += uiQNumParts )
2217    {
2218      uiCombCbfY |= pcCU->getCbf( uiPartIdx, TEXT_LUMA,     1 );
2219      uiCombCbfU |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_U, 1 );
2220      uiCombCbfV |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_V, 1 );
2221    }
2222    for( UInt uiOffs = 0; uiOffs < 4 * uiQNumParts; uiOffs++ )
2223    {
2224      pcCU->getCbf( TEXT_LUMA     )[ uiOffs ] |= uiCombCbfY;
2225      pcCU->getCbf( TEXT_CHROMA_U )[ uiOffs ] |= uiCombCbfU;
2226      pcCU->getCbf( TEXT_CHROMA_V )[ uiOffs ] |= uiCombCbfV;
2227    }
2228  }
2229
2230  //===== reset context models =====
2231  if(m_bUseSBACRD)
2232  {
2233    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2234  }
2235
2236  //===== set distortion (rate and r-d costs are determined later) =====
2237  ruiDistC                   = uiOverallDistC;
2238  pcCU->getTotalDistortion() = uiOverallDistY + uiOverallDistC;
2239}
2240
2241
2242
2243Void
2244TEncSearch::estIntraPredChromaQT( TComDataCU* pcCU,
2245                                 TComYuv*    pcOrgYuv,
2246                                 TComYuv*    pcPredYuv,
2247                                 TComYuv*    pcResiYuv,
2248                                 TComYuv*    pcRecoYuv,
2249                                 Dist        uiPreCalcDistC )
2250{
2251  UInt    uiDepth     = pcCU->getDepth(0);
2252  UInt    uiBestMode  = 0;
2253  Dist    uiBestDist  = 0;
2254  Double  dBestCost   = MAX_DOUBLE;
2255
2256  //----- init mode list -----
2257#if ADD_PLANAR_MODE
2258  UInt  uiModeList[6];
2259  uiModeList[0] = PLANAR_IDX;
2260  for( Int i = 0; i < 5; i++ )
2261  {
2262    uiModeList[i+1] = i;
2263  }
2264  UInt uiLumaMode = pcCU->getLumaIntraDir(0);
2265#else
2266  UInt  uiModeList[5];
2267  for( Int i = 0; i < 4; i++ )
2268  {
2269    uiModeList[i] = i;
2270  }
2271
2272  uiModeList[4]   = pcCU->getLumaIntraDir(0);
2273#endif
2274
2275  UInt  uiMinMode = 0;
2276#if CHROMA_CODEWORD
2277#if ADD_PLANAR_MODE
2278  UInt  uiMaxMode = 6;
2279
2280#if LM_CHROMA
2281  UInt  uiIgnore;
2282  if(pcCU->getSlice()->getSPS()->getUseLMChroma())
2283  {
2284    uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 3) ) ? uiMaxMode : uiLumaMode );
2285  }
2286  else
2287  {
2288    uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? uiMaxMode : uiLumaMode );
2289  }
2290#else
2291  UInt  uiIgnore = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? uiMaxMode : uiLumaMode );
2292#endif
2293
2294#else
2295  UInt  uiMaxMode = 5;
2296
2297#if LM_CHROMA
2298  UInt  uiIgnore;
2299  if(pcCU->getSlice()->getSPS()->getUseLMChroma())
2300  {
2301    uiIgnore = (uiModeList[4] >= 0 && uiModeList[4] < 3) ? uiModeList[4] : 6;
2302  }
2303  else
2304  {
2305    uiIgnore = (uiModeList[4] >= 0 && uiModeList[4] < 4) ? uiModeList[4] : 6;
2306  }
2307#else
2308  UInt  uiIgnore = (uiModeList[4] < 4) ? uiModeList[4] : 6;
2309#endif
2310
2311#endif
2312#else
2313#if ADD_PLANAR_MODE
2314  UInt  uiMaxMode = ( ( (uiLumaMode != PLANAR_IDX) && (uiLumaMode >= 4) ) ? 6 : 5 );
2315#else
2316  UInt  uiMaxMode = ( uiModeList[4] >= 4 ? 5 : 4 );
2317#endif
2318#endif
2319
2320  //----- check chroma modes -----
2321  for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )
2322  {
2323#if CHROMA_CODEWORD
2324#if ADD_PLANAR_MODE
2325    if ( uiModeList[uiMode] == uiIgnore )
2326#else
2327    if (uiMode == uiIgnore)
2328#endif
2329    {
2330      continue;
2331    }
2332#endif
2333#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2334#if ADD_PLANAR_MODE
2335    if ( uiModeList[uiMode] == 4 && pcCU->getLumaIntraDir(0) > MAX_MODE_ID_INTRA_DIR )
2336    {
2337      continue;
2338    }
2339#else
2340    if ( uiMode == 4 && pcCU->getLumaIntraDir(0) > MAX_MODE_ID_INTRA_DIR )
2341    {
2342      continue;
2343    }
2344#endif
2345#endif
2346    //----- restore context models -----
2347    if( m_bUseSBACRD )
2348    {
2349      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2350    }
2351
2352    //----- chroma coding -----
2353    Dist    uiDist = 0;
2354#if ADD_PLANAR_MODE
2355    pcCU->setChromIntraDirSubParts  ( uiModeList[uiMode], 0, uiDepth );
2356#else
2357    pcCU->setChromIntraDirSubParts  ( uiMode, 0, uiDepth );
2358#endif
2359    xRecurIntraChromaCodingQT       ( pcCU,   0, 0, pcOrgYuv, pcPredYuv, pcResiYuv, uiDist );
2360    UInt    uiBits = xGetIntraBitsQT( pcCU,   0, 0, false, true, false );
2361    Double  dCost  = m_pcRdCost->calcRdCost( uiBits, uiDist );
2362
2363    //----- compare -----
2364    if( dCost < dBestCost )
2365    {
2366      dBestCost   = dCost;
2367      uiBestDist  = uiDist;
2368#if ADD_PLANAR_MODE
2369      uiBestMode  = uiModeList[uiMode];
2370#else
2371      uiBestMode  = uiMode;
2372#endif
2373      UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2374      xSetIntraResultChromaQT( pcCU, 0, 0, pcRecoYuv );
2375      ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
2376      ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
2377    }
2378  }
2379
2380  //----- set data -----
2381  UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2382  ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPN * sizeof( UChar ) );
2383  ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPN * sizeof( UChar ) );
2384  pcCU->setChromIntraDirSubParts( uiBestMode, 0, uiDepth );
2385  pcCU->getTotalDistortion      () += uiBestDist - uiPreCalcDistC;
2386
2387  //----- restore context models -----
2388  if( m_bUseSBACRD )
2389  {
2390    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2391  }
2392}
2393
2394#if (!REFERENCE_SAMPLE_PADDING)
2395#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2396Bool TEncSearch::predIntraLumaDirAvailable( UInt uiMode, UInt uiWidthBit, Bool bAboveAvail, Bool bLeftAvail, UInt uiWidth, UInt uiHeight, TComDataCU* pcCU, UInt uiAbsPartIdx   )
2397#else
2398Bool TEncSearch::predIntraLumaDirAvailable( UInt uiMode, UInt uiWidthBit, Bool bAboveAvail, Bool bLeftAvail )
2399#endif
2400{
2401  Bool bDirAvailable;
2402#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2403  if( uiMode > MAX_MODE_ID_INTRA_DIR )
2404  {
2405    return predIntraLumaDMMAvailable( uiMode, bAboveAvail, bLeftAvail, uiWidth, uiHeight );
2406  }
2407  else
2408#endif
2409  {
2410    bDirAvailable = true;
2411    UInt uiNewMode = g_aucAngIntraModeOrder[uiMode];
2412    if ( uiNewMode > 0 && ( ( (!bAboveAvail) && uiNewMode < 18 ) || ( (!bLeftAvail) && uiNewMode > 17 ) ) )
2413    {
2414      bDirAvailable = false;
2415    }
2416  }
2417
2418  return bDirAvailable;
2419}
2420#endif
2421
2422#if HHI_DMM_WEDGE_INTRA
2423Void TEncSearch::findWedgeFullMinDist( TComDataCU*  pcCU,
2424                                      UInt         uiAbsPtIdx,
2425                                      Pel*         piOrig,
2426                                      Pel*         piPredic,
2427                                      UInt         uiStride,
2428                                      UInt         uiWidth,
2429                                      UInt         uiHeight,
2430                                      UInt&        ruiTabIdx,
2431                                      Int&         riDeltaDC1,
2432                                      Int&         riDeltaDC2,
2433                                      Bool         bAbove,
2434                                      Bool         bLeft,
2435                                      WedgeDist    eWedgeDist
2436                                      )
2437{
2438  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2439
2440  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2441  xSearchWedgeFullMinDist( pcCU, uiAbsPtIdx, pacWedgeList, piOrig, uiStride, uiWidth, uiHeight, ruiTabIdx );
2442
2443  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2444  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2445}
2446
2447Void TEncSearch::xSearchWedgeFullMinDist( TComDataCU* pcCU, UInt uiAbsPtIdx, WedgeList* pacWedgeList, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx )
2448{
2449  ruiTabIdx = 0;
2450
2451  // local pred buffer
2452  TComYuv cPredYuv;
2453  cPredYuv.create( uiWidth, uiHeight );
2454  cPredYuv.clear();
2455
2456  UInt uiPredStride = cPredYuv.getStride();
2457  Pel* piPred       = cPredYuv.getLumaAddr();
2458
2459  Int  iDC1 = 0;
2460  Int  iDC2 = 0;
2461  // regular wedge search
2462  Dist uiBestDist   = RDO_DIST_MAX;
2463  UInt uiBestTabIdx = 0;
2464
2465  for( UInt uiIdx = 0; uiIdx < pacWedgeList->size(); uiIdx++ )
2466  {
2467    calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piRef,  uiRefStride,  iDC1, iDC2 );
2468    assignWedgeDCs2Pred( &(pacWedgeList->at(uiIdx)), piPred, uiPredStride, iDC1, iDC2 );
2469
2470    Dist uiActDist = RDO_DIST_MAX;
2471#if HHI_VSO
2472    if( m_pcRdCost->getUseVSO() )
2473    {
2474      uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false, 0 );
2475    }
2476    else
2477    {
2478      uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2479    }
2480#else
2481    uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2482#endif
2483
2484    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2485    {
2486      uiBestDist   = uiActDist;
2487      uiBestTabIdx = uiIdx;
2488    }
2489  }
2490  ruiTabIdx = uiBestTabIdx;
2491
2492  cPredYuv.destroy();
2493  return;
2494}
2495
2496Void TEncSearch::findWedgePredDirMinDist( TComDataCU*  pcCU,
2497                                         UInt         uiAbsPtIdx,
2498                                         Pel*         piOrig,
2499                                         Pel*         piPredic,
2500                                         UInt         uiStride,
2501                                         UInt         uiWidth,
2502                                         UInt         uiHeight,
2503                                         UInt&        ruiTabIdx,
2504                                         Int&         riWedgeDeltaEnd,
2505                                         Int&         riDeltaDC1,
2506                                         Int&         riDeltaDC2,
2507                                         Bool         bAbove,
2508                                         Bool         bLeft,
2509                                         WedgeDist    eWedgeDist )
2510{
2511  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2512  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2513
2514  ruiTabIdx       = 0;
2515  riWedgeDeltaEnd = 0;
2516
2517  xSearchWedgePredDirMinDist( pcCU, uiAbsPtIdx, pacWedgeList, piOrig, uiStride, uiWidth, uiHeight, ruiTabIdx, riWedgeDeltaEnd );
2518
2519  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2520  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2521}
2522
2523Void TEncSearch::xSearchWedgePredDirMinDist( TComDataCU* pcCU, UInt uiAbsPtIdx, WedgeList* pacWedgeList, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx, Int& riWedgeDeltaEnd )
2524{
2525  ruiTabIdx       = 0;
2526  riWedgeDeltaEnd = 0;
2527
2528  // local pred buffer
2529  TComYuv cPredYuv;
2530  cPredYuv.create( uiWidth, uiHeight );
2531  cPredYuv.clear();
2532
2533  UInt uiPredStride = cPredYuv.getStride();
2534  Pel* piPred       = cPredYuv.getLumaAddr();
2535
2536  Int  iDC1 = 0;
2537  Int  iDC2 = 0;
2538
2539  // regular wedge search
2540  Dist uiBestDist    = RDO_DIST_MAX;
2541  UInt uiBestTabIdx  = 0;
2542  Int  iBestDeltaEnd = 0;
2543
2544  UInt uiIdx = 0;
2545  for( Int iTestDeltaEnd = -DMM_WEDGE_PREDDIR_DELTAEND_MAX; iTestDeltaEnd <= DMM_WEDGE_PREDDIR_DELTAEND_MAX; iTestDeltaEnd++ )
2546  {
2547    uiIdx = getBestContinueWedge( pcCU, uiAbsPtIdx, uiWidth, uiHeight, iTestDeltaEnd );
2548    calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piRef,  uiRefStride,  iDC1, iDC2 );
2549    assignWedgeDCs2Pred( &(pacWedgeList->at(uiIdx)), piPred, uiPredStride, iDC1, iDC2 );
2550
2551    Dist uiActDist = RDO_DIST_MAX;
2552#if HHI_VSO
2553    if( m_pcRdCost->getUseVSO() )
2554    {
2555      uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false, 0 );
2556    }
2557    else
2558    {
2559      uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2560    }
2561#else
2562    uiActDist = m_pcRdCost->getDistPart( piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, DF_SAD );
2563#endif
2564
2565    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2566    {
2567      uiBestDist    = uiActDist;
2568      uiBestTabIdx  = uiIdx;
2569      iBestDeltaEnd = iTestDeltaEnd;
2570    }
2571    else if( uiIdx == uiBestTabIdx && abs(iTestDeltaEnd) < abs(iBestDeltaEnd) )
2572    {
2573      iBestDeltaEnd = iTestDeltaEnd;
2574    }
2575  }
2576
2577  ruiTabIdx       = uiBestTabIdx;
2578  riWedgeDeltaEnd = iBestDeltaEnd;
2579
2580  cPredYuv.destroy();
2581  return;
2582}
2583#endif
2584
2585#if HHI_DMM_PRED_TEX
2586Void TEncSearch::findWedgeTexMinDist( TComDataCU*  pcCU, 
2587                                      UInt         uiAbsPtIdx, 
2588                                      Pel*         piOrig, 
2589                                      Pel*         piPredic, 
2590                                      UInt         uiStride, 
2591                                      UInt         uiWidth, 
2592                                      UInt         uiHeight, 
2593                                      UInt&        ruiTabIdx, 
2594                                      Int&         riDeltaDC1, 
2595                                      Int&         riDeltaDC2, 
2596                                      Bool         bAbove, 
2597                                      Bool         bLeft, 
2598                                      WedgeDist    eWedgeDist,
2599                                      Pel*         piTextureRef
2600                                    )
2601  {
2602  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
2603  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
2604
2605  ruiTabIdx = getBestWedgeFromText( pcCU, uiAbsPtIdx, uiWidth, uiHeight, eWedgeDist, piTextureRef );
2606
2607  TComWedgelet* pcBestWedgelet = &(pacWedgeList->at(ruiTabIdx));
2608  xGetWedgeDeltaDCsMinDist( pcBestWedgelet, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2609}
2610
2611Void TEncSearch::findContourPredTex( TComDataCU*  pcCU,
2612                                     UInt         uiAbsPtIdx,
2613                                     Pel*         piOrig,
2614                                     Pel*         piPredic,
2615                                     UInt         uiStride,
2616                                     UInt         uiWidth,
2617                                     UInt         uiHeight,
2618                                     Int&         riDeltaDC1,
2619                                     Int&         riDeltaDC2,
2620                                     Bool         bAbove,
2621                                     Bool         bLeft,
2622                                     Pel*         piTextureRef )
2623{
2624  // get contour pattern
2625  TComWedgelet* pcContourWedge = new TComWedgelet( uiWidth, uiHeight );
2626  getBestContourFromText( pcCU, uiAbsPtIdx, uiWidth, uiHeight, pcContourWedge, piTextureRef );
2627
2628  xGetWedgeDeltaDCsMinDist( pcContourWedge, pcCU, uiAbsPtIdx, piOrig, piPredic, uiStride, uiWidth, uiHeight, riDeltaDC1, riDeltaDC2, bAbove, bLeft );
2629
2630  pcContourWedge->destroy();
2631  delete pcContourWedge;
2632}
2633#endif
2634#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
2635Void TEncSearch::xGetWedgeDeltaDCsMinDist( TComWedgelet* pcWedgelet,
2636                                           TComDataCU*   pcCU,
2637                                           UInt          uiAbsPtIdx,
2638                                           Pel*          piOrig,
2639                                           Pel*          piPredic,
2640                                           UInt          uiStride,
2641                                           UInt          uiWidth,
2642                                           UInt          uiHeight,
2643                                           Int&          riDeltaDC1,
2644                                           Int&          riDeltaDC2,
2645                                           Bool          bAbove,
2646                                           Bool          bLeft )
2647{
2648  Int iDC1 = 0;
2649  Int iDC2 = 0;
2650  calcWedgeDCs       ( pcWedgelet, piOrig,   uiStride, iDC1, iDC2 );
2651  assignWedgeDCs2Pred( pcWedgelet, piPredic, uiStride, iDC1, iDC2 );
2652
2653  Int iPredDC1 = 0;
2654  Int iPredDC2 = 0;
2655  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt );
2656  Int iMaskStride = ( uiWidth<<1 ) + 1;
2657  piMask += iMaskStride+1;
2658  getWedgePredDCs( pcWedgelet, piMask, iMaskStride, iPredDC1, iPredDC2, bAbove, bLeft );
2659
2660  riDeltaDC1 = iDC1 - iPredDC1;
2661  riDeltaDC2 = iDC2 - iPredDC2;
2662
2663#if HHI_VSO
2664  if( m_pcRdCost->getUseVSO() )
2665  {
2666    Int iFullDeltaDC1 = riDeltaDC1;
2667    Int iFullDeltaDC2 = riDeltaDC2;
2668
2669    xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC1 );
2670    xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC2 );
2671
2672    Dist uiBestDist     = RDO_DIST_MAX;
2673    UInt  uiBestQStepDC1 = 0;
2674    UInt  uiBestQStepDC2 = 0;
2675
2676    UInt uiDeltaDC1Max = abs(iFullDeltaDC1);
2677    UInt uiDeltaDC2Max = abs(iFullDeltaDC2);
2678
2679    //VSO Level delta DC check range extension
2680    uiDeltaDC1Max += (uiDeltaDC1Max>>1);
2681    uiDeltaDC2Max += (uiDeltaDC2Max>>1);
2682
2683    for( UInt uiQStepDC1 = 1; uiQStepDC1 <= uiDeltaDC1Max; uiQStepDC1++  )
2684    {
2685      Int iLevelDeltaDC1 = (Int)(uiQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
2686      xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC1 );
2687
2688      Int iTestDC1 = Clip( iPredDC1 + iLevelDeltaDC1 );
2689      for( UInt uiQStepDC2 = 1; uiQStepDC2 <= uiDeltaDC2Max; uiQStepDC2++  )
2690      {
2691        Int iLevelDeltaDC2 = (Int)(uiQStepDC2) * (Int)(( iFullDeltaDC2 < 0 ) ? -1 : 1);
2692        xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC2 );
2693
2694        Int iTestDC2 = Clip( iPredDC2 + iLevelDeltaDC2 );
2695
2696        assignWedgeDCs2Pred( pcWedgelet, piPredic, uiStride, iTestDC1, iTestDC2 );
2697
2698        Dist uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPredic, uiStride,  piOrig, uiStride, uiWidth, uiHeight, false, 0 );
2699        if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
2700        {
2701          uiBestDist     = uiActDist;
2702          uiBestQStepDC1 = uiQStepDC1;
2703          uiBestQStepDC2 = uiQStepDC2;
2704        }
2705      }
2706    }
2707
2708    iFullDeltaDC1 = (Int)(uiBestQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
2709    iFullDeltaDC2 = (Int)(uiBestQStepDC2) * (Int)(( iFullDeltaDC2 < 0 ) ? -1 : 1);
2710    xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC1 );
2711    xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC2 );
2712    riDeltaDC1 = iFullDeltaDC1;
2713    riDeltaDC2 = iFullDeltaDC2;
2714  }
2715#endif
2716
2717  xDeltaDCQuantScaleDown( pcCU, riDeltaDC1 );
2718  xDeltaDCQuantScaleDown( pcCU, riDeltaDC2 );
2719}
2720
2721Bool TEncSearch::predIntraLumaDMMAvailable( UInt uiMode, UInt uiWidth, UInt uiHeight )
2722{
2723  if( uiMode <= MAX_MODE_ID_INTRA_DIR ) return true;
2724
2725  Bool bDMMAvailable = m_pcEncCfg->getUseDMM();
2726
2727#if HHI_DMM_WEDGE_INTRA
2728  if( uiMode == DMM_WEDGE_FULL_IDX        ||
2729      uiMode == DMM_WEDGE_FULL_D_IDX      ||
2730      uiMode == DMM_WEDGE_PREDDIR_IDX     ||
2731      uiMode == DMM_WEDGE_PREDDIR_D_IDX )
2732  {
2733    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 ) )
2734    {
2735      bDMMAvailable = false;
2736    }
2737  }
2738#endif
2739#if HHI_DMM_PRED_TEX
2740  if( uiMode == DMM_WEDGE_PREDTEX_IDX     ||
2741      uiMode == DMM_WEDGE_PREDTEX_D_IDX   ||
2742      uiMode == DMM_CONTOUR_PREDTEX_IDX   ||
2743      uiMode == DMM_CONTOUR_PREDTEX_D_IDX )
2744  {
2745    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 ) )
2746    {
2747      bDMMAvailable = false;
2748    }
2749  }
2750
2751#endif
2752
2753  return bDMMAvailable;
2754}
2755
2756Void TEncSearch::xDeltaDCQuantScaleDown( TComDataCU*  pcCU, Int& riDeltaDC )
2757{
2758  Int  iSign  = riDeltaDC < 0 ? -1 : 1;
2759  UInt uiAbs  = abs( riDeltaDC );
2760
2761  Int riB = 0;
2762  Int iQp = pcCU->getQP(0);
2763  Int iMax = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) );
2764  Double dStepSize = Clip3( 1, iMax, pow( 2.0, iQp/10.0 + g_dDeltaDCsQuantOffset ) );
2765
2766  riB = roftoi( uiAbs / dStepSize );
2767
2768  riDeltaDC = riB * iSign;
2769  return;
2770}
2771#endif
2772
2773
2774Void TEncSearch::xGetInterPredictionError( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, UInt& ruiErr, Bool bHadamard )
2775{
2776  TComYuv cYuvPred;
2777  cYuvPred.create( pcYuvOrg->getWidth(), pcYuvOrg->getHeight() );
2778
2779#ifdef WEIGHT_PRED
2780  UInt uiAbsPartIdx = 0;
2781  Int iWidth = 0;
2782  Int iHeight = 0;
2783  Int iRefIdx[2];
2784  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2785
2786  iRefIdx[0] = pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiAbsPartIdx );
2787  iRefIdx[1] = pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiAbsPartIdx );
2788  if ( iRefIdx[0]>=0 && iRefIdx[1]<1 )
2789    setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_0);
2790  else
2791    setWpScalingDistParam( pcCU, iRefIdx[0], iRefIdx[1], REF_PIC_LIST_1);
2792
2793  motionCompensation( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2794#else
2795  motionCompensation( pcCU, &cYuvPred, REF_PIC_LIST_X, iPartIdx );
2796
2797  UInt uiAbsPartIdx = 0;
2798  Int iWidth = 0;
2799  Int iHeight = 0;
2800  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2801#endif
2802
2803  DistParam cDistParam;
2804#ifdef WEIGHT_PRED
2805  cDistParam.applyWeight = false;
2806#endif
2807  m_pcRdCost->setDistParam( cDistParam,
2808                            pcYuvOrg->getLumaAddr( uiAbsPartIdx ), pcYuvOrg->getStride(),
2809                            cYuvPred .getLumaAddr( uiAbsPartIdx ), cYuvPred .getStride(),
2810                            iWidth, iHeight, m_pcEncCfg->getUseHADME() );
2811  ruiErr = cDistParam.DistFunc( &cDistParam );
2812
2813  cYuvPred.destroy();
2814}
2815
2816/** estimation of best merge coding
2817 * \param pcCU
2818 * \param pcYuvOrg
2819 * \param iPUIdx
2820 * \param uiInterDir
2821 * \param pacMvField
2822 * \param uiMergeIndex
2823 * \param ruiCost
2824 * \param ruiBits
2825 * \param puhNeighCands
2826 * \param bValid
2827 * \returns Void
2828 */
2829Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost, UInt& ruiBits, UChar* puhNeighCands,Bool& bValid )
2830{
2831  TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
2832  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
2833  UInt uiNeighbourCandIdx[MRG_MAX_NUM_CANDS]; //MVs with same idx => same cand
2834
2835  for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ++ui )
2836  {
2837    uhInterDirNeighbours[ui] = 0;
2838    uiNeighbourCandIdx[ui] = 0;
2839  }
2840
2841  UInt uiAbsPartIdx = 0;
2842  Int iWidth = 0;
2843  Int iHeight = 0;
2844
2845  pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
2846  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
2847  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, uiNeighbourCandIdx );
2848
2849  UInt uiNumCand = 0;
2850  for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; ++uiMergeCand )
2851  {
2852    if( uiNeighbourCandIdx[uiMergeCand] == ( uiMergeCand + 1 ) )
2853    {
2854      uiNumCand++;
2855    }
2856  }
2857
2858  UInt uiBestSAD = MAX_UINT;
2859  UInt uiBestBitCost = MAX_UINT;
2860  UInt uiBestBits = MAX_UINT;
2861
2862  ruiCost = MAX_UINT;
2863  ruiBits = MAX_UINT;
2864
2865  bValid = false;
2866
2867  for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; ++uiMergeCand )
2868  {
2869    if( uiNeighbourCandIdx[uiMergeCand] == ( uiMergeCand + 1 ) )
2870    {
2871      bValid = true;
2872      UInt uiCostCand = MAX_UINT;
2873      UInt uiBitsCand = 0;
2874
2875      PartSize ePartSize = pcCU->getPartitionSize( 0 );
2876
2877      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[0 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2878      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[1 + 2*uiMergeCand].getRefIdx(), ePartSize, uiAbsPartIdx, iPUIdx, 0 );
2879
2880      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2881
2882      if( uiNumCand == 1 )
2883      {
2884        uiBitsCand = 1;
2885      }
2886      else
2887      {
2888        if( uiMergeCand == 0 || uiNumCand == 2 )
2889        {
2890          uiBitsCand = 2;
2891        }
2892        else if( uiMergeCand == 1 || uiNumCand == 3 )
2893        {
2894          uiBitsCand = 3;
2895        }
2896        else if( uiMergeCand == 2 || uiNumCand == 4 )
2897        {
2898          uiBitsCand = 4;
2899        }
2900        else
2901        {
2902          uiBitsCand = 5;
2903        }
2904      }
2905
2906      if ( uiCostCand < ruiCost )
2907      {
2908        ruiCost = uiCostCand;
2909        ruiBits = uiBitsCand;
2910        pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
2911        pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
2912        uiInterDir = uhInterDirNeighbours[uiMergeCand];
2913        uiMergeIndex = uiMergeCand;
2914        for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
2915        {
2916          UChar uhNeighCand = uiNeighbourCandIdx[ui];
2917          puhNeighCands[ui] = uhNeighCand;
2918        }
2919
2920        uiBestSAD = uiCostCand;
2921        uiBestBitCost = m_pcRdCost->getCost( uiBitsCand );
2922        uiBestBits = uiBitsCand;
2923      }
2924    }
2925  }
2926}
2927
2928/** search of the best candidate for inter prediction
2929 * \param pcCU
2930 * \param pcOrgYuv
2931 * \param rpcPredYuv
2932 * \param rpcResiYuv
2933 * \param rpcRecoYuv
2934 * \param bUseRes
2935 * \returns Void
2936 */
2937Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes )
2938{
2939  m_acYuvPred[0].clear();
2940  m_acYuvPred[1].clear();
2941  m_cYuvPredTemp.clear();
2942  rpcPredYuv->clear();
2943
2944  if ( !bUseRes )
2945  {
2946    rpcResiYuv->clear();
2947  }
2948
2949  rpcRecoYuv->clear();
2950
2951  TComMv        cMvSrchRngLT;
2952  TComMv        cMvSrchRngRB;
2953
2954  TComMv        cMvZero;
2955  TComMv        TempMv; //kolya
2956
2957  TComMv        cMv[2];
2958  TComMv        cMvBi[2];
2959  TComMv        cMvTemp[2][33];
2960
2961  Int           iNumPart    = pcCU->getNumPartInter();
2962  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
2963
2964  TComMv        cMvPred[2][33];
2965
2966  TComMv        cMvPredBi[2][33];
2967  Int           aaiMvpIdxBi[2][33];
2968
2969  Int           aaiMvpIdx[2][33];
2970  Int           aaiMvpNum[2][33];
2971
2972  AMVPInfo aacAMVPInfo[2][33];
2973
2974#ifdef WEIGHT_PRED
2975  Int           iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
2976#else
2977  Int           iRefIdx[2];
2978#endif
2979  Int           iRefIdxBi[2];
2980
2981  UInt          uiPartAddr;
2982  Int           iRoiWidth, iRoiHeight;
2983
2984  UInt          uiMbBits[3] = {1, 1, 0};
2985
2986  UInt          uiLastMode = 0;
2987  Int           iRefStart, iRefEnd;
2988
2989  PartSize      ePartSize = pcCU->getPartitionSize( 0 );
2990
2991#if ZERO_MVD_EST
2992  Int           aiZeroMvdMvpIdx[2] = {-1, -1};
2993  Int           aiZeroMvdRefIdx[2] = {0, 0};
2994  Int           iZeroMvdDir = -1;
2995#endif
2996
2997  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
2998  {
2999    UInt          uiCost[2] = { MAX_UINT, MAX_UINT };
3000    UInt          uiCostBi  =   MAX_UINT;
3001    UInt          uiCostTemp;
3002
3003    UInt          uiBits[3];
3004    UInt          uiBitsTemp;
3005#if ZERO_MVD_EST
3006    UInt          uiZeroMvdCost = MAX_UINT;
3007    UInt          uiZeroMvdCostTemp;
3008    UInt          uiZeroMvdBitsTemp;
3009    UInt          uiZeroMvdDistTemp = MAX_UINT;
3010    UInt          auiZeroMvdBits[3];
3011#endif
3012
3013#if DCM_COMB_LIST
3014    UInt          uiCostTempL0[MAX_NUM_REF];
3015    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) uiCostTempL0[iNumRef] = MAX_UINT;
3016#endif
3017
3018    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
3019
3020    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3021
3022#if PART_MRG
3023    Bool bTestNormalMC = true;
3024    if (pcCU->getWidth( 0 ) > 8 && iNumPart == 2 && iPartIdx == 0)
3025      bTestNormalMC = false;
3026    if (bTestNormalMC)
3027    {
3028#endif
3029
3030    //  Uni-directional prediction
3031    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
3032    {
3033      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3034
3035      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
3036      {
3037#ifdef WEIGHT_PRED
3038        if ( eRefPicList == REF_PIC_LIST_0 ) setWpScalingDistParam( pcCU, iRefIdxTemp, -1 , eRefPicList);
3039        if ( eRefPicList == REF_PIC_LIST_1 ) setWpScalingDistParam( pcCU, -1, iRefIdxTemp , eRefPicList);
3040#endif
3041        uiBitsTemp = uiMbBits[iRefList];
3042        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3043        {
3044          uiBitsTemp += iRefIdxTemp+1;
3045          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3046        }
3047#if ZERO_MVD_EST
3048        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &uiZeroMvdDistTemp);
3049#else
3050        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp]);
3051#endif
3052        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
3053        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
3054
3055        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][aaiMvpNum[iRefList][iRefIdxTemp]];
3056#if ZERO_MVD_EST
3057#if DCM_COMB_LIST
3058        if ((iRefList != 1 || !pcCU->getSlice()->getNoBackPredFlag()) &&
3059            (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) <= 0 || pcCU->getSlice()->getRefIdxOfLC(eRefPicList, iRefIdxTemp)>=0))
3060#endif
3061        {
3062          uiZeroMvdBitsTemp = uiBitsTemp;
3063          uiZeroMvdBitsTemp += 2; //zero mvd bits
3064
3065          m_pcRdCost->getMotionCost( 1, 0 );
3066          uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost(uiZeroMvdBitsTemp);
3067
3068          if (uiZeroMvdCostTemp < uiZeroMvdCost)
3069          {
3070            uiZeroMvdCost = uiZeroMvdCostTemp;
3071            iZeroMvdDir = iRefList + 1;
3072            aiZeroMvdRefIdx[iRefList] = iRefIdxTemp;
3073            aiZeroMvdMvpIdx[iRefList] = aaiMvpIdx[iRefList][iRefIdxTemp];
3074            auiZeroMvdBits[iRefList] = uiZeroMvdBitsTemp;
3075          }
3076        }
3077#endif
3078
3079#if GPB_SIMPLE_UNI
3080#if DCM_COMB_LIST
3081        if ( pcCU->getSlice()->getSPS()->getUseLDC() || pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0)
3082#else
3083        if ( pcCU->getSlice()->getSPS()->getUseLDC() )
3084#endif
3085        {
3086#if DCM_COMB_LIST
3087          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 ) ) )
3088#else
3089          if ( iRefList && ( iRefIdxTemp != iRefIdx[0] || pcCU->getSlice()->getNoBackPredFlag() ) )
3090#endif
3091            {
3092#if DCM_COMB_LIST
3093              if (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
3094              {
3095                uiCostTemp = uiCostTempL0[pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
3096              }
3097              else
3098              {
3099                uiCostTemp = MAX_UINT;
3100              }
3101#else
3102              uiCostTemp = MAX_UINT;
3103#endif
3104#if DCM_COMB_LIST
3105              if ( pcCU->getSlice()->getNoBackPredFlag() || pcCU->getSlice()->getSPS()->getUseLDC() )
3106#else
3107              if ( pcCU->getSlice()->getNoBackPredFlag() )
3108#endif
3109              {
3110                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3111              }
3112#if DCM_COMB_LIST
3113              else
3114              {
3115                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
3116              }
3117#endif
3118            }
3119            else
3120            {
3121              xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3122            }
3123        }
3124        else
3125        {
3126          if (iRefList && pcCU->getSlice()->getNoBackPredFlag())
3127          {
3128            uiCostTemp = MAX_UINT;
3129            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3130          }
3131          else
3132          {
3133            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3134          }
3135        }
3136#else
3137        xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3138#endif
3139        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
3140        if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3141        {
3142          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3143        }
3144
3145#if DCM_COMB_LIST
3146        if(pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
3147        {
3148          if(iRefList==REF_PIC_LIST_0)
3149          {
3150            uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3151            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_0, iRefIdxTemp)<0)
3152            {
3153              uiCostTemp = MAX_UINT;
3154            }
3155          }
3156          else
3157          {
3158            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_1, iRefIdxTemp)<0)
3159            {
3160              uiCostTemp = MAX_UINT;
3161            }
3162          }
3163        }
3164#endif
3165
3166        if ( ( iRefList == 0 && uiCostTemp < uiCost[iRefList] ) ||
3167            ( iRefList == 1 &&  pcCU->getSlice()->getNoBackPredFlag() && iRefIdxTemp == iRefIdx[0] ) ||
3168#if DCM_COMB_LIST
3169            ( iRefList == 1 && (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0) && (iRefIdxTemp==0 || iRefIdxTemp == iRefIdx[0]) && !pcCU->getSlice()->getNoBackPredFlag() && (iRefIdxTemp == pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)) ) ||
3170#endif
3171            ( iRefList == 1 && !pcCU->getSlice()->getNoBackPredFlag() && uiCostTemp < uiCost[iRefList] ) )
3172          {
3173            uiCost[iRefList] = uiCostTemp;
3174            uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3175
3176            // set motion
3177            cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3178            iRefIdx[iRefList] = iRefIdxTemp;
3179            pcCU->getCUMvField(eRefPicList)->setAllMvField( cMv[iRefList], iRefIdx[iRefList], ePartSize, uiPartAddr, iPartIdx, 0 );
3180
3181            // storing list 1 prediction signal for iterative bi-directional prediction
3182            if ( eRefPicList == REF_PIC_LIST_1 )
3183            {
3184              TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3185              motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3186            }
3187#if DCM_COMB_LIST
3188            if ( (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) && eRefPicList == REF_PIC_LIST_0 )
3189#else
3190            if ( pcCU->getSlice()->getNoBackPredFlag() && eRefPicList == REF_PIC_LIST_0 )
3191#endif
3192            {
3193              TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3194              motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3195            }
3196          }
3197      }
3198    }
3199    //  Bi-directional prediction
3200    if ( pcCU->getSlice()->isInterB() )
3201    {
3202
3203      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
3204      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
3205
3206      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
3207      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
3208
3209      UInt uiMotBits[2] = { uiBits[0] - uiMbBits[0], uiBits[1] - uiMbBits[1] };
3210      uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3211
3212      // 4-times iteration (default)
3213      Int iNumIter = 4;
3214
3215      // fast encoder setting: only one iteration
3216      if ( m_pcEncCfg->getUseFastEnc() )
3217      {
3218        iNumIter = 1;
3219      }
3220
3221      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3222      {
3223
3224        Int         iRefList    = iIter % 2;
3225#if DCM_COMB_LIST
3226        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3227#else
3228        if ( m_pcEncCfg->getUseFastEnc() && pcCU->getSlice()->getNoBackPredFlag() )
3229#endif
3230        {
3231          iRefList = 1;
3232        }
3233        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3234
3235        Bool bChanged = false;
3236
3237#if GPB_SIMPLE
3238        if ( pcCU->getSlice()->getSPS()->getUseLDC() && iRefList )
3239        {
3240          iRefStart = iRefIdxBi[1-iRefList];
3241          iRefEnd   = iRefIdxBi[1-iRefList];
3242        }
3243        else
3244        {
3245          iRefStart = 0;
3246          iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3247        }
3248#else
3249        iRefStart = 0;
3250        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3251#endif
3252
3253#if DCM_COMB_LIST
3254        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3255#else
3256        if ( m_pcEncCfg->getUseFastEnc() && pcCU->getSlice()->getNoBackPredFlag() )
3257#endif
3258        {
3259          iRefStart = 0;
3260          iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3261        }
3262
3263        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3264        {
3265#ifdef WEIGHT_PRED
3266          if ( eRefPicList == REF_PIC_LIST_0 ) setWpScalingDistParam( pcCU, iRefIdxTemp, -1 , eRefPicList);
3267          if ( eRefPicList == REF_PIC_LIST_1 ) setWpScalingDistParam( pcCU, -1, iRefIdxTemp , eRefPicList);
3268#endif
3269          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3270          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3271          {
3272            uiBitsTemp += iRefIdxTemp+1;
3273            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3274          }
3275
3276          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][aaiMvpNum[iRefList][iRefIdxTemp]];
3277          // call ME
3278          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3279          if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3280          {
3281            xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3282            xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3283          }
3284
3285          if ( uiCostTemp < uiCostBi )
3286          {
3287            bChanged = true;
3288
3289            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3290            iRefIdxBi[iRefList] = iRefIdxTemp;
3291
3292            uiCostBi            = uiCostTemp;
3293            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3294            uiBits[2]           = uiBitsTemp;
3295
3296            //  Set motion
3297            pcCU->getCUMvField( eRefPicList )->setAllMvField( cMvBi[iRefList], iRefIdxBi[iRefList], ePartSize, uiPartAddr, iPartIdx, 0 );
3298
3299            TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3300            motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3301          }
3302        } // for loop-iRefIdxTemp
3303
3304        if ( !bChanged )
3305        {
3306          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3307          {
3308            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3309            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3310            xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3311            xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3312          }
3313          break;
3314        }
3315      } // for loop-iter
3316    } // if (B_SLICE)
3317#if ZERO_MVD_EST
3318    if ( pcCU->getSlice()->isInterB() )
3319    {
3320      m_pcRdCost->getMotionCost( 1, 0 );
3321
3322      for ( Int iL0RefIdxTemp = 0; iL0RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1; iL0RefIdxTemp++ )
3323      for ( Int iL1RefIdxTemp = 0; iL1RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1; iL1RefIdxTemp++ )
3324      {
3325        UInt uiRefIdxBitsTemp = 0;
3326        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 1 )
3327        {
3328          uiRefIdxBitsTemp += iL0RefIdxTemp+1;
3329          if ( iL0RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1 ) uiRefIdxBitsTemp--;
3330        }
3331        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3332        {
3333          uiRefIdxBitsTemp += iL1RefIdxTemp+1;
3334          if ( iL1RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiRefIdxBitsTemp--;
3335        }
3336
3337        Int iL0MVPIdx = 0;
3338        Int iL1MVPIdx = 0;
3339
3340        for (iL0MVPIdx = 0; iL0MVPIdx < aaiMvpNum[0][iL0RefIdxTemp]; iL0MVPIdx++)
3341        {
3342          for (iL1MVPIdx = 0; iL1MVPIdx < aaiMvpNum[1][iL1RefIdxTemp]; iL1MVPIdx++)
3343          {
3344            uiZeroMvdBitsTemp = uiRefIdxBitsTemp;
3345            uiZeroMvdBitsTemp += uiMbBits[2];
3346            uiZeroMvdBitsTemp += m_auiMVPIdxCost[iL0MVPIdx][aaiMvpNum[0][iL0RefIdxTemp]] + m_auiMVPIdxCost[iL1MVPIdx][aaiMvpNum[1][iL1RefIdxTemp]];
3347            uiZeroMvdBitsTemp += 4; //zero mvd for both directions
3348            pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( aacAMVPInfo[0][iL0RefIdxTemp].m_acMvCand[iL0MVPIdx], iL0RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3349            pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( aacAMVPInfo[1][iL1RefIdxTemp].m_acMvCand[iL1MVPIdx], iL1RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3350
3351            xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiZeroMvdDistTemp, m_pcEncCfg->getUseHADME() );
3352            uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost( uiZeroMvdBitsTemp );
3353            if (uiZeroMvdCostTemp < uiZeroMvdCost)
3354            {
3355              uiZeroMvdCost = uiZeroMvdCostTemp;
3356              iZeroMvdDir = 3;
3357              aiZeroMvdMvpIdx[0] = iL0MVPIdx;
3358              aiZeroMvdMvpIdx[1] = iL1MVPIdx;
3359              aiZeroMvdRefIdx[0] = iL0RefIdxTemp;
3360              aiZeroMvdRefIdx[1] = iL1RefIdxTemp;
3361              auiZeroMvdBits[2] = uiZeroMvdBitsTemp;
3362            }
3363          }
3364        }
3365      }
3366    }
3367#endif
3368#if PART_MRG
3369    } //end if bTestNormalMC
3370#endif
3371    //  Clear Motion Field
3372    {
3373      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvZero, NOT_VALID, ePartSize, uiPartAddr, iPartIdx, 0 );
3374      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvZero, NOT_VALID, ePartSize, uiPartAddr, iPartIdx, 0 );
3375    }
3376    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3377    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3378
3379    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3380    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3381    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3382    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3383
3384    UInt uiMEBits = 0;
3385    // Set Motion Field_
3386#if DCM_COMB_LIST
3387    if ( pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 ) )
3388#else
3389    if ( pcCU->getSlice()->getNoBackPredFlag() )
3390#endif
3391    {
3392      uiCost[1] = MAX_UINT;
3393    }
3394#if PART_MRG
3395    if (bTestNormalMC)
3396    {
3397#endif
3398#if ZERO_MVD_EST
3399    if (uiZeroMvdCost <= uiCostBi && uiZeroMvdCost <= uiCost[0] && uiZeroMvdCost <= uiCost[1])
3400    {
3401      if (iZeroMvdDir == 3)
3402      {
3403        uiLastMode = 2;
3404
3405        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3406        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3407
3408        pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3409
3410        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3411        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3412        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3413        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3414        uiMEBits = auiZeroMvdBits[2];
3415      }
3416      else if (iZeroMvdDir == 1)
3417      {
3418        uiLastMode = 0;
3419
3420        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3421
3422        pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3423
3424        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3425        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3426        uiMEBits = auiZeroMvdBits[0];
3427      }
3428      else if (iZeroMvdDir == 2)
3429      {
3430        uiLastMode = 1;
3431
3432        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3433
3434        pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3435
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[1];
3439      }
3440      else
3441      {
3442        assert(0);
3443      }
3444    }
3445    else
3446#endif
3447    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3448    {
3449      uiLastMode = 2;
3450      {
3451        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvBi[0], iRefIdxBi[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3452        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvBi[1], iRefIdxBi[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3453      }
3454      {
3455        TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3456        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3457#if DCM_SIMPLIFIED_MVP==0
3458        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[0][iRefIdxBi[0]]))
3459        {
3460          aaiMvpIdxBi[0][iRefIdxBi[0]] = pcCU->searchMVPIdx(cMvPredBi[0][iRefIdxBi[0]], &aacAMVPInfo[0][iRefIdxBi[0]]);
3461          aaiMvpNum[0][iRefIdxBi[0]] = aacAMVPInfo[0][iRefIdxBi[0]].iN;
3462        }
3463#endif
3464      }
3465      {
3466        TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3467        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3468#if DCM_SIMPLIFIED_MVP==0
3469        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[1][iRefIdxBi[1]]))
3470        {
3471          aaiMvpIdxBi[1][iRefIdxBi[1]] = pcCU->searchMVPIdx(cMvPredBi[1][iRefIdxBi[1]], &aacAMVPInfo[1][iRefIdxBi[1]]);
3472          aaiMvpNum[1][iRefIdxBi[1]] = aacAMVPInfo[1][iRefIdxBi[1]].iN;
3473        }
3474#endif
3475      }
3476
3477      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3478
3479      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3480      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3481      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3482      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3483
3484      uiMEBits = uiBits[2];
3485    }
3486    else if ( uiCost[0] <= uiCost[1] )
3487    {
3488      uiLastMode = 0;
3489      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMv[0],   iRefIdx[0],   ePartSize, uiPartAddr, iPartIdx, 0 );
3490
3491      {
3492        TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3493        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3494#if DCM_SIMPLIFIED_MVP==0
3495        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[0][iRefIdx[0]]))
3496        {
3497          aaiMvpIdx[0][iRefIdx[0]] = pcCU->searchMVPIdx(cMvPred[0][iRefIdx[0]], &aacAMVPInfo[0][iRefIdx[0]]);
3498          aaiMvpNum[0][iRefIdx[0]] = aacAMVPInfo[0][iRefIdx[0]].iN;
3499        }
3500#endif
3501      }
3502      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3503
3504      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3505      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3506
3507      uiMEBits = uiBits[0];
3508    }
3509    else
3510    {
3511      uiLastMode = 1;
3512      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMv[1],   iRefIdx[1],   ePartSize, uiPartAddr, iPartIdx, 0 );
3513
3514      {
3515        TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3516        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, iPartIdx, 0 );
3517#if DCM_SIMPLIFIED_MVP==0
3518        if (pcCU->clearMVPCand(TempMv, &aacAMVPInfo[1][iRefIdx[1]]))
3519        {
3520          aaiMvpIdx[1][iRefIdx[1]] = pcCU->searchMVPIdx(cMvPred[1][iRefIdx[1]], &aacAMVPInfo[1][iRefIdx[1]]);
3521          aaiMvpNum[1][iRefIdx[1]] = aacAMVPInfo[1][iRefIdx[1]].iN;
3522        }
3523#endif
3524      }
3525      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3526
3527      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3528      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3529
3530      uiMEBits = uiBits[1];
3531    }
3532#if PART_MRG
3533    } // end if bTestNormalMC
3534#endif
3535
3536    if ( pcCU->getSlice()->getSPS()->getUseMRG() && pcCU->getPartitionSize( uiPartAddr ) == SIZE_2Nx2N )
3537    {
3538      UChar       uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
3539      UInt        uiNeighbourCandIdx  [MRG_MAX_NUM_CANDS];
3540      TComMvField cMvFieldNeighbours  [MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
3541      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3542      {
3543        uhInterDirNeighbours[ui] = 0;
3544        uiNeighbourCandIdx  [ui] = 0;
3545      }
3546      pcCU->getInterMergeCandidates( uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ), cMvFieldNeighbours, uhInterDirNeighbours, uiNeighbourCandIdx );
3547      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3548      {
3549        pcCU->setNeighbourCandIdxSubParts( ui, uiNeighbourCandIdx[ui], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3550      }
3551    }
3552
3553    if ( pcCU->getSlice()->getSPS()->getUseMRG() && pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3554    {
3555      UInt uiMRGInterDir = 0;
3556      TComMvField cMRGMvField[2];
3557      UInt uiMRGIndex = 0;
3558
3559      UInt uiMEInterDir = 0;
3560      TComMvField cMEMvField[2];
3561
3562      m_pcRdCost->getMotionCost( 1, 0 );
3563#if PART_MRG
3564      // calculate ME cost
3565      UInt uiMEError = MAX_UINT;
3566      UInt uiMECost = MAX_UINT;
3567
3568      if (bTestNormalMC)
3569      {
3570        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3571        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3572      }
3573#else
3574      // calculate ME cost
3575      UInt uiMEError = MAX_UINT;
3576      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3577      UInt uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3578#endif
3579      // save ME result.
3580      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3581      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3582      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3583
3584      // find Merge result
3585      UInt uiMRGError = MAX_UINT;
3586      UInt uiMRGBits = MAX_UINT;
3587      Bool bMergeValid = false;
3588      UChar ucNeighCand[MRG_MAX_NUM_CANDS];
3589      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3590      {
3591        ucNeighCand[ui] = 0;
3592      }
3593      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGError, uiMRGBits, ucNeighCand, bMergeValid );
3594      UInt uiMRGCost = uiMRGError + m_pcRdCost->getCost( uiMRGBits );
3595
3596      for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ )
3597      {
3598        pcCU->setNeighbourCandIdxSubParts( ui, ucNeighCand[ui], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3599      }
3600      if ( bMergeValid && uiMRGCost < uiMECost )
3601      {
3602        // set Merge result
3603        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3604        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3605        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3606        {
3607          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0].getMv(), cMRGMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3608          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1].getMv(), cMRGMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3609        }
3610
3611        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3612        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, iPartIdx, 0 );
3613        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3614        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3615        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3616        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3617      }
3618      else
3619      {
3620        // set ME result
3621        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3622        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3623        {
3624          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0].getMv(), cMEMvField[0].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3625          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1].getMv(), cMEMvField[1].getRefIdx(), ePartSize, uiPartAddr, iPartIdx, 0 );
3626        }
3627      }
3628#if PART_MRG
3629      if (!bTestNormalMC && !bMergeValid)
3630      {
3631        assert(pcCU->getWidth( 0 ) > 8 && iNumPart == 2 && iPartIdx == 0);
3632        return;
3633      }
3634#endif
3635    }
3636
3637    //  MC
3638    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
3639
3640  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3641
3642#ifdef WEIGHT_PRED
3643  setWpScalingDistParam( pcCU, -1, -1, REF_PIC_LIST_X );
3644#endif
3645  return;
3646}
3647
3648// AMVP
3649#if ZERO_MVD_EST
3650Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDist )
3651#else
3652Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled )
3653#endif
3654{
3655  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3656
3657  TComMv  cBestMv;
3658  Int     iBestIdx = 0;
3659  TComMv  cZeroMv;
3660  TComMv  cMvPred;
3661  UInt    uiBestCost = MAX_INT;
3662  UInt    uiPartAddr = 0;
3663  Int     iRoiWidth, iRoiHeight;
3664  Int     i;
3665
3666  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3667  // Fill the MV Candidates
3668  if (!bFilled)
3669  {
3670    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
3671  }
3672
3673  // initialize Mvp index & Mvp
3674  iBestIdx = 0;
3675  cBestMv  = pcAMVPInfo->m_acMvCand[0];
3676#if !ZERO_MVD_EST
3677  if( pcCU->getAMVPMode(uiPartAddr) == AM_NONE || (pcAMVPInfo->iN <= 1 && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL) )
3678  {
3679    rcMvPred = cBestMv;
3680
3681    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3682    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3683    return;
3684  }
3685#endif
3686  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL && bFilled)
3687  {
3688    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
3689    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
3690    return;
3691  }
3692
3693  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL)
3694  {
3695    m_cYuvPredTemp.clear();
3696#if ZERO_MVD_EST
3697    UInt uiDist;
3698#endif
3699    //-- Check Minimum Cost.
3700    for ( i = 0 ; i < pcAMVPInfo->iN; i++)
3701    {
3702      UInt uiTmpCost;
3703#if ZERO_MVD_EST
3704      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, pcAMVPInfo->iN, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3705#else
3706      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, pcAMVPInfo->iN, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3707#endif
3708      if ( uiBestCost > uiTmpCost )
3709      {
3710        uiBestCost = uiTmpCost;
3711        cBestMv   = pcAMVPInfo->m_acMvCand[i];
3712        iBestIdx  = i;
3713        #if ZERO_MVD_EST
3714        (*puiDist) = uiDist;
3715        #endif
3716      }
3717    }
3718
3719    m_cYuvPredTemp.clear();
3720  }
3721
3722  // Setting Best MVP
3723  rcMvPred = cBestMv;
3724  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3725  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3726  return;
3727}
3728
3729UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
3730{
3731  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
3732
3733  if (iNum == 1)
3734    return 0;
3735
3736  UInt uiLength = 1;
3737  Int iTemp = iIdx;
3738  if ( iTemp == 0 )
3739  {
3740    return uiLength;
3741  }
3742
3743  Bool bCodeLast = ( iNum-1 > iTemp );
3744
3745  uiLength += (iTemp-1);
3746
3747  if( bCodeLast )
3748  {
3749    uiLength++;
3750  }
3751
3752  return uiLength;
3753}
3754
3755Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
3756{
3757  if ( eCUMode == SIZE_2Nx2N )
3758  {
3759    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3760    uiBlkBit[1] = 3;
3761    uiBlkBit[2] = 5;
3762  }
3763  else if ( eCUMode == SIZE_2NxN )
3764  {
3765    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} } };
3766    if ( bPSlice )
3767    {
3768      uiBlkBit[0] = 3;
3769      uiBlkBit[1] = 0;
3770      uiBlkBit[2] = 0;
3771    }
3772    else
3773    {
3774      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3775    }
3776  }
3777  else if ( eCUMode == SIZE_Nx2N )
3778  {
3779    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} } };
3780    if ( bPSlice )
3781    {
3782      uiBlkBit[0] = 3;
3783      uiBlkBit[1] = 0;
3784      uiBlkBit[2] = 0;
3785    }
3786    else
3787    {
3788      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3789    }
3790  }
3791  else if ( eCUMode == SIZE_NxN )
3792  {
3793    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3794    uiBlkBit[1] = 3;
3795    uiBlkBit[2] = 5;
3796  }
3797  else
3798  {
3799    printf("Wrong!\n");
3800    assert( 0 );
3801  }
3802}
3803
3804Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
3805{
3806  pDst->iN = pSrc->iN;
3807  for (Int i = 0; i < pSrc->iN; i++)
3808  {
3809    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
3810  }
3811}
3812
3813Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, UInt& ruiCost )
3814{
3815  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3816
3817  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
3818
3819  if (pcAMVPInfo->iN < 2) return;
3820
3821  m_pcRdCost->getMotionCost( 1, 0 );
3822  m_pcRdCost->setCostScale ( 0    );
3823
3824  Int iBestMVPIdx = riMVPIdx;
3825
3826  m_pcRdCost->setPredictor( rcMvPred );
3827  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3828  Int iBestMvBits = iOrgMvBits;
3829
3830  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
3831  {
3832    if (iMVPIdx == riMVPIdx) continue;
3833
3834    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
3835
3836    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3837
3838    if (iMvBits < iBestMvBits)
3839    {
3840      iBestMvBits = iMvBits;
3841      iBestMVPIdx = iMVPIdx;
3842    }
3843  }
3844
3845  if (iBestMVPIdx != riMVPIdx)  //if changed
3846  {
3847    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
3848
3849    iOrgMvBits  += m_auiMVPIdxCost[riMVPIdx][pcAMVPInfo->iN];
3850    iBestMvBits += m_auiMVPIdxCost[iBestMVPIdx][pcAMVPInfo->iN];
3851
3852    riMVPIdx = iBestMVPIdx;
3853    UInt uiOrgBits = ruiBits;
3854    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
3855    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
3856  }
3857}
3858
3859UInt TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
3860                                  UInt        uiPartIdx,
3861                                  UInt      uiPartAddr,
3862                                  TComYuv*    pcOrgYuv,
3863                                  TComYuv*    pcTemplateCand,
3864                                  TComMv      cMvCand,
3865                                  Int         iMVPIdx,
3866                                  Int     iMVPNum,
3867                                  RefPicList  eRefPicList,
3868                                  Int         iRefIdx,
3869                                  Int         iSizeX,
3870                                  Int         iSizeY
3871                               #if ZERO_MVD_EST
3872                                , UInt&       ruiDist
3873                               #endif
3874                                  )
3875{
3876  UInt uiCost  = MAX_INT;
3877
3878  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
3879
3880  // prediction pattern
3881  xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand );
3882
3883#ifdef WEIGHT_PRED
3884  if ( pcCU->getSlice()->getPPS()->getUseWP() )
3885  {
3886    PartSize  ePartSize = pcCU->getPartitionSize( 0 );
3887    pcCU->getCUMvField(eRefPicList)->setAllMvField( cMvCand, iRefIdx, ePartSize, uiPartAddr, uiPartIdx, 0 );
3888#if 0
3889    TComMvField mvField;
3890    mvField.setMvField( cMvCand, iRefIdx);
3891    pcCU->getCUMvField(eRefPicList)->setAllMvField( mvField, ePartSize, uiPartAddr, 0 );
3892#endif
3893    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, uiPartIdx );
3894  }
3895#endif
3896
3897  // calc distortion
3898#if ZERO_MVD_EST
3899  m_pcRdCost->getMotionCost( 1, 0 );
3900  DistParam cDistParam;
3901  m_pcRdCost->setDistParam( cDistParam,
3902                            pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(),
3903                            pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(),
3904                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME() );
3905  // MW: check VSO here
3906  ruiDist = cDistParam.DistFunc( &cDistParam );
3907  uiCost = ruiDist + m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] );
3908#else
3909#if HHI_VSO
3910  if ( false /*m_pcRdCost->getUseVSO()*/ ) // GT: currently disabled
3911  {
3912    uiCost = m_pcRdCost->getDistVS  ( pcCU, uiPartAddr,  pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, true, 0);
3913    uiCost = (UInt) m_pcRdCost->calcRdCostVSO( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
3914  }
3915  else
3916#endif
3917  {
3918    uiCost = m_pcRdCost->getDistPart( pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, DF_SAD );
3919    uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
3920  }
3921#endif
3922  return uiCost;
3923}
3924
3925Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, UInt& ruiCost, Bool bBi  )
3926{
3927  UInt          uiPartAddr;
3928  Int           iRoiWidth;
3929  Int           iRoiHeight;
3930
3931  TComMv        cMvHalf, cMvQter;
3932  TComMv        cMvSrchRngLT;
3933  TComMv        cMvSrchRngRB;
3934
3935  TComYuv*      pcYuv = pcYuvOrg;
3936#ifdef ROUNDING_CONTROL_BIPRED
3937  Pel           pRefBufY[16384];  // 128x128
3938#endif
3939  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
3940
3941  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
3942  TComPattern*  pcPatternKey  = pcCU->getPattern        ();
3943
3944  Double        fWeight       = 1.0;
3945
3946  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3947
3948  if ( bBi )
3949  {
3950    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
3951    pcYuv                = &m_cYuvPredTemp;
3952
3953    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
3954
3955#ifdef ROUNDING_CONTROL_BIPRED
3956    Int y;
3957    //Int x;
3958    Pel *pRefY = pcYuvOther->getLumaAddr(uiPartAddr);
3959    Int iRefStride = pcYuvOther->getStride();
3960
3961    // copy the MC block into pRefBufY
3962    for( y = 0; y < iRoiHeight; y++)
3963    {
3964      memcpy(pRefBufY+y*iRoiWidth,pRefY,sizeof(Pel)*iRoiWidth);
3965      pRefY += iRefStride;
3966    }
3967#else
3968    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight );
3969#endif
3970
3971    fWeight = 0.5;
3972  }
3973
3974  //  Search key pattern initialization
3975  pcPatternKey->initPattern( pcYuv->getLumaAddr( uiPartAddr ),
3976                            pcYuv->getCbAddr  ( uiPartAddr ),
3977                            pcYuv->getCrAddr  ( uiPartAddr ),
3978                            iRoiWidth,
3979                            iRoiHeight,
3980                            pcYuv->getStride(),
3981                            0, 0, 0, 0 );
3982
3983  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr );
3984  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride();
3985
3986  TComMv      cMvPred = *pcMvPred;
3987
3988  if ( bBi )  xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3989  else        xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3990
3991  m_pcRdCost->getMotionCost ( 1, 0 );
3992
3993  m_pcRdCost->setPredictor  ( *pcMvPred );
3994#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3995  if( pcCU->getSlice()->getSPS()->isDepth() )
3996    m_pcRdCost->setCostScale  ( 0 );
3997  else
3998#endif
3999  m_pcRdCost->setCostScale  ( 2 );
4000
4001#if HHI_INTER_VIEW_MOTION_PRED
4002  { // init inter-view regularization
4003    TComMv  cOrgDepthMapMv;
4004    Bool    bMultiviewReg = pcCU->getIViewOrgDepthMvPred( iPartIdx, eRefPicList, iRefIdxPred, cOrgDepthMapMv );
4005#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4006    if( bMultiviewReg && pcCU->getSlice()->getSPS()->isDepth() )
4007    {
4008      cOrgDepthMapMv += TComMv( 2, 2 );
4009      cOrgDepthMapMv >>= 2;
4010    }
4011#endif
4012    m_pcRdCost->setMultiviewReg( bMultiviewReg ? &cOrgDepthMapMv : 0 );
4013    if( bMultiviewReg && !bBi )
4014    {
4015      xSetSearchRange( pcCU, cOrgDepthMapMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4016    }
4017  }
4018#endif
4019
4020  //  Do integer search
4021#ifdef ROUNDING_CONTROL_BIPRED
4022  if( bBi )
4023  {
4024    xPatternSearch_Bi      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost, pRefBufY, pcCU->getSlice()->isRounding() );
4025  }
4026  else
4027  {
4028    if ( !m_iFastSearch)
4029    {
4030      xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4031    }
4032    else
4033    {
4034      rcMv = *pcMvPred;
4035      xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4036    }
4037  }
4038#else
4039  if ( !m_iFastSearch || bBi )
4040  {
4041    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4042  }
4043  else
4044  {
4045    rcMv = ( m_pcRdCost->useMultiviewReg() ? m_pcRdCost->getMultiviewOrgMvPred() : *pcMvPred );
4046    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4047  }
4048#endif
4049
4050
4051  m_pcRdCost->getMotionCost( 1, 0 );
4052#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4053  if( ! pcCU->getSlice()->getSPS()->isDepth() )
4054  {
4055#endif
4056  m_pcRdCost->setCostScale ( 1 );
4057
4058#ifdef ROUNDING_CONTROL_BIPRED
4059  if( bBi )
4060  {
4061    Bool bRound =  pcCU->getSlice()->isRounding() ;
4062    xPatternSearchFracDIF_Bi( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost, pRefBufY, bRound );
4063  }
4064  else
4065#endif
4066  {
4067    xPatternSearchFracDIF( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
4068  }
4069
4070
4071
4072  m_pcRdCost->setCostScale( 0 );
4073  rcMv <<= 2;
4074  rcMv += (cMvHalf <<= 1);
4075  rcMv +=  cMvQter;
4076#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4077  }
4078#endif
4079
4080  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
4081#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4082  if( pcCU->getSlice()->getSPS()->isDepth() )
4083    ruiCost += m_pcRdCost->getCost( uiMvBits );
4084#endif
4085
4086  ruiBits   += uiMvBits;
4087  ruiCost       = (UInt)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
4088}
4089
4090
4091Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
4092{
4093  Int  iMvShift = 2;
4094#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4095  if( pcCU->getSlice()->getSPS()->isDepth() )
4096    iMvShift = 0;
4097#endif
4098  pcCU->clipMv( cMvPred );
4099
4100  rcMvSrchRngLT.setHor( cMvPred.getHor() - (iSrchRng << iMvShift) );
4101  rcMvSrchRngLT.setVer( cMvPred.getVer() - (iSrchRng << iMvShift) );
4102
4103  rcMvSrchRngRB.setHor( cMvPred.getHor() + (iSrchRng << iMvShift) );
4104  rcMvSrchRngRB.setVer( cMvPred.getVer() + (iSrchRng << iMvShift) );
4105
4106  pcCU->clipMv        ( rcMvSrchRngLT );
4107  pcCU->clipMv        ( rcMvSrchRngRB );
4108
4109  rcMvSrchRngLT >>= iMvShift;
4110  rcMvSrchRngRB >>= iMvShift;
4111}
4112
4113#ifdef ROUNDING_CONTROL_BIPRED
4114Void TEncSearch::xPatternSearch_Bi( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD, Pel* pcRefY2, Bool bRound )
4115{
4116  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4117  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4118  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4119  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4120
4121  UInt  uiSad;
4122  Dist  uiSadBest         = RDO_DIST_MAX;
4123  Int   iBestX = 0;
4124  Int   iBestY = 0;
4125
4126  Pel*  piRefSrch;
4127
4128  //-- jclee for using the SAD function pointer
4129  m_pcRdCost->setDistParam_Bi( pcPatternKey, piRefY, iRefStride,  m_cDistParam);
4130
4131  // fast encoder decision: use subsampled SAD for integer ME
4132  if ( m_pcEncCfg->getUseFastEnc() )
4133  {
4134    if ( m_cDistParam.iRows > 8 )
4135    {
4136      m_cDistParam.iSubShift = 1;
4137    }
4138  }
4139
4140  piRefY += (iSrchRngVerTop * iRefStride);
4141  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4142  {
4143    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4144    {
4145      //  find min. distortion position
4146      piRefSrch = piRefY + x;
4147      m_cDistParam.pCur = piRefSrch;
4148      uiSad = m_cDistParam.DistFuncRnd( &m_cDistParam, pcRefY2, bRound );
4149
4150      // motion cost
4151      uiSad += m_pcRdCost->getCost( x, y );
4152
4153      // regularization cost
4154      if( m_pcRdCost->useMultiviewReg() )
4155      {
4156        uiSad += m_pcRdCost->getMultiviewRegCost( x, y );
4157      }
4158
4159      if ( uiSad < uiSadBest )
4160      {
4161        uiSadBest = uiSad;
4162        iBestX    = x;
4163        iBestY    = y;
4164      }
4165    }
4166    piRefY += iRefStride;
4167  }
4168
4169  rcMv.set( iBestX, iBestY );
4170  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4171  return;
4172}
4173#endif
4174
4175Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4176{
4177  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4178  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4179  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4180  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4181
4182  UInt  uiSad;
4183  UInt  uiSadBest         = MAX_UINT;
4184  Int   iBestX = 0;
4185  Int   iBestY = 0;
4186
4187  Pel*  piRefSrch;
4188
4189  //-- jclee for using the SAD function pointer
4190  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
4191
4192  // fast encoder decision: use subsampled SAD for integer ME
4193  if ( m_pcEncCfg->getUseFastEnc() )
4194  {
4195    if ( m_cDistParam.iRows > 8 )
4196    {
4197      m_cDistParam.iSubShift = 1;
4198    }
4199  }
4200
4201  piRefY += (iSrchRngVerTop * iRefStride);
4202  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4203  {
4204    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4205    {
4206      //  find min. distortion position
4207      piRefSrch = piRefY + x;
4208      m_cDistParam.pCur = piRefSrch;
4209#ifdef WEIGHT_PRED
4210      setDistParamComp(0);
4211#endif
4212      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
4213
4214      // motion cost
4215      uiSad += m_pcRdCost->getCost( x, y );
4216
4217      // regularization cost
4218      if( m_pcRdCost->useMultiviewReg() )
4219      {
4220        uiSad += m_pcRdCost->getMultiviewRegCost( x, y );
4221      }
4222
4223      if ( uiSad < uiSadBest )
4224      {
4225        uiSadBest = uiSad;
4226        iBestX    = x;
4227        iBestY    = y;
4228      }
4229    }
4230    piRefY += iRefStride;
4231  }
4232
4233  rcMv.set( iBestX, iBestY );
4234
4235  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4236  return;
4237}
4238
4239Void TEncSearch::xPatternSearchFast( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4240{
4241  pcCU->getMvPredLeft       ( m_acMvPredictors[0] );
4242  pcCU->getMvPredAbove      ( m_acMvPredictors[1] );
4243  pcCU->getMvPredAboveRight ( m_acMvPredictors[2] );
4244
4245  switch ( m_iFastSearch )
4246  {
4247    case 1:
4248      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD );
4249      break;
4250
4251    default:
4252      break;
4253  }
4254}
4255
4256Void TEncSearch::xTZSearch( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4257{
4258  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4259  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4260  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4261  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4262
4263  TZ_SEARCH_CONFIGURATION
4264
4265  UInt uiSearchRange = m_iSearchRange;
4266  pcCU->clipMv( rcMv );
4267#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4268  if( ! pcCU->getSlice()->getSPS()->isDepth() )
4269#endif
4270  rcMv >>= 2;
4271  // init TZSearchStruct
4272  IntTZSearchStruct cStruct;
4273  cStruct.iYStride    = iRefStride;
4274  cStruct.piRefY      = piRefY;
4275  cStruct.uiBestSad   = MAX_UINT;
4276
4277  // set rcMv (Median predictor) as start point and as best point
4278  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4279
4280  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4281  if ( bTestOtherPredictedMV )
4282  {
4283    for ( UInt index = 0; index < 3; index++ )
4284    {
4285      TComMv cMv = m_acMvPredictors[index];
4286      pcCU->clipMv( cMv );
4287#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4288      if( ! pcCU->getSlice()->getSPS()->isDepth() )
4289#endif
4290      cMv >>= 2;
4291      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4292    }
4293  }
4294
4295  // test whether zero Mv is better start point than Median predictor
4296  if ( bTestZeroVector )
4297  {
4298    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4299  }
4300
4301  // start search
4302  Int  iDist = 0;
4303  Int  iStartX = cStruct.iBestX;
4304  Int  iStartY = cStruct.iBestY;
4305
4306  // first search
4307  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4308  {
4309    if ( bFirstSearchDiamond == 1 )
4310    {
4311      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4312    }
4313    else
4314    {
4315      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4316    }
4317
4318    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4319    {
4320      break;
4321    }
4322  }
4323
4324  // test whether zero Mv is a better start point than Median predictor
4325  if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4326  {
4327    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4328    if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4329    {
4330      // test its neighborhood
4331      for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4332      {
4333        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
4334        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4335        {
4336          break;
4337        }
4338      }
4339    }
4340  }
4341
4342  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4343  if ( cStruct.uiBestDistance == 1 )
4344  {
4345    cStruct.uiBestDistance = 0;
4346    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4347  }
4348
4349  // raster search if distance is too big
4350  if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4351  {
4352    cStruct.uiBestDistance = iRaster;
4353    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4354    {
4355      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4356      {
4357        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4358      }
4359    }
4360  }
4361
4362  // raster refinement
4363  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4364  {
4365    while ( cStruct.uiBestDistance > 0 )
4366    {
4367      iStartX = cStruct.iBestX;
4368      iStartY = cStruct.iBestY;
4369      if ( cStruct.uiBestDistance > 1 )
4370      {
4371        iDist = cStruct.uiBestDistance >>= 1;
4372        if ( bRasterRefinementDiamond == 1 )
4373        {
4374          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4375        }
4376        else
4377        {
4378          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4379        }
4380      }
4381
4382      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4383      if ( cStruct.uiBestDistance == 1 )
4384      {
4385        cStruct.uiBestDistance = 0;
4386        if ( cStruct.ucPointNr != 0 )
4387        {
4388          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4389        }
4390      }
4391    }
4392  }
4393
4394  // start refinement
4395  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4396  {
4397    while ( cStruct.uiBestDistance > 0 )
4398    {
4399      iStartX = cStruct.iBestX;
4400      iStartY = cStruct.iBestY;
4401      cStruct.uiBestDistance = 0;
4402      cStruct.ucPointNr = 0;
4403      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4404      {
4405        if ( bStarRefinementDiamond == 1 )
4406        {
4407          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4408        }
4409        else
4410        {
4411          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4412        }
4413        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4414        {
4415          break;
4416        }
4417      }
4418
4419      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4420      if ( cStruct.uiBestDistance == 1 )
4421      {
4422        cStruct.uiBestDistance = 0;
4423        if ( cStruct.ucPointNr != 0 )
4424        {
4425          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4426        }
4427      }
4428    }
4429  }
4430
4431  // write out best match
4432  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4433  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4434}
4435
4436
4437#ifdef ROUNDING_CONTROL_BIPRED
4438Void TEncSearch::xPatternSearchFracDIF_Bi( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvInt, TComMv& rcMvHalf, TComMv& rcMvQter, UInt& ruiCost, Pel* piRefY2, Bool bRound )
4439{
4440  //  Reference pattern initialization (integer scale)
4441  TComPattern cPatternRoi;
4442  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4443  cPatternRoi.initPattern( piRefY +  iOffset,
4444                          NULL,
4445                          NULL,
4446                          pcPatternKey->getROIYWidth(),
4447                          pcPatternKey->getROIYHeight(),
4448                          iRefStride,
4449                          0, 0, 0, 0 );
4450  Pel*  piRef;
4451  iRefStride  = m_cYuvExt.getStride();
4452
4453  //  Half-pel refinement
4454  xExtDIFUpSamplingH ( &cPatternRoi, &m_cYuvExt );
4455  piRef = m_cYuvExt.getLumaAddr() + ((iRefStride + 4) << 2);
4456
4457  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4458  ruiCost = xPatternRefinement_Bi( pcPatternKey, piRef, iRefStride, 4, 2, rcMvHalf, piRefY2, bRound );
4459
4460  m_pcRdCost->setCostScale( 0 );
4461
4462  //  Quater-pel refinement
4463  Pel*  piSrcPel = cPatternRoi.getROIY() + (rcMvHalf.getHor() >> 1) + cPatternRoi.getPatternLStride() * (rcMvHalf.getVer() >> 1);
4464  Int*  piSrc    = m_piYuvExt  + ((m_iYuvExtStride + 4) << 2) + (rcMvHalf.getHor() << 1) + m_iYuvExtStride * (rcMvHalf.getVer() << 1);
4465  piRef += (rcMvHalf.getHor() << 1) + iRefStride * (rcMvHalf.getVer() << 1);
4466  xExtDIFUpSamplingQ ( pcPatternKey, piRef, iRefStride, piSrcPel, cPatternRoi.getPatternLStride(), piSrc, m_iYuvExtStride, m_puiDFilter[rcMvHalf.getHor()+rcMvHalf.getVer()*3] );
4467
4468  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4469  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4470  ruiCost = xPatternRefinement_Bi( pcPatternKey, piRef, iRefStride, 4, 1, rcMvQter, piRefY2, bRound );
4471}
4472
4473#endif
4474
4475Void TEncSearch::xPatternSearchFracDIF( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvInt, TComMv& rcMvHalf, TComMv& rcMvQter, UInt& ruiCost )
4476{
4477  //  Reference pattern initialization (integer scale)
4478  TComPattern cPatternRoi;
4479  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4480  cPatternRoi.initPattern( piRefY +  iOffset,
4481                          NULL,
4482                          NULL,
4483                          pcPatternKey->getROIYWidth(),
4484                          pcPatternKey->getROIYHeight(),
4485                          iRefStride,
4486                          0, 0, 0, 0 );
4487  Pel*  piRef;
4488  iRefStride  = m_cYuvExt.getStride();
4489
4490  //  Half-pel refinement
4491  xExtDIFUpSamplingH ( &cPatternRoi, &m_cYuvExt );
4492  piRef = m_cYuvExt.getLumaAddr() + ((iRefStride + 4) << 2);
4493
4494  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4495  ruiCost = xPatternRefinement( pcPatternKey, piRef, iRefStride, 4, 2, rcMvHalf   );
4496
4497  m_pcRdCost->setCostScale( 0 );
4498
4499  //  Quater-pel refinement
4500  Pel*  piSrcPel = cPatternRoi.getROIY() + (rcMvHalf.getHor() >> 1) + cPatternRoi.getPatternLStride() * (rcMvHalf.getVer() >> 1);
4501  Int*  piSrc    = m_piYuvExt  + ((m_iYuvExtStride + 4) << 2) + (rcMvHalf.getHor() << 1) + m_iYuvExtStride * (rcMvHalf.getVer() << 1);
4502  piRef += (rcMvHalf.getHor() << 1) + iRefStride * (rcMvHalf.getVer() << 1);
4503  xExtDIFUpSamplingQ ( pcPatternKey, piRef, iRefStride, piSrcPel, cPatternRoi.getPatternLStride(), piSrc, m_iYuvExtStride, m_puiDFilter[rcMvHalf.getHor()+rcMvHalf.getVer()*3] );
4504
4505  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4506  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4507  ruiCost = xPatternRefinement( pcPatternKey, piRef, iRefStride, 4, 1, rcMvQter );
4508}
4509
4510Void TEncSearch::predInterSkipSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv )
4511{
4512  SliceType eSliceType = pcCU->getSlice()->getSliceType();
4513  if ( eSliceType == I_SLICE )
4514    return;
4515
4516  if ( eSliceType == P_SLICE && pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 )
4517  {
4518    pcCU->setInterDirSubParts( 1, 0, 0, pcCU->getDepth( 0 ) );
4519
4520    TComMv cMv;
4521    TComMv cZeroMv;
4522    xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_0, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_0 )->getAMVPInfo()->iN > 0?  true:false) );
4523    pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4524    pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4525    pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cZeroMv, NOT_VALID, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4526    pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4527
4528    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, 0, 0, pcCU->getDepth(0));
4529    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, 0, 0, pcCU->getDepth(0));
4530
4531    //  Motion compensation
4532    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_0 );
4533
4534  }
4535  else if ( eSliceType == B_SLICE &&
4536           pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 &&
4537           pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0  )
4538  {
4539    TComMv cMv;
4540    TComMv cZeroMv;
4541
4542    if (pcCU->getInterDir(0)!=2)
4543    {
4544      xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_0, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_0 )->getAMVPInfo()->iN > 0?  true:false) );
4545      pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4546      pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 ); //unnecessary
4547    }
4548
4549    if (pcCU->getInterDir(0)!=1)
4550    {
4551      xEstimateMvPredAMVP( pcCU, pcOrgYuv, 0, REF_PIC_LIST_1, 0, cMv, (pcCU->getCUMvField( REF_PIC_LIST_1 )->getAMVPInfo()->iN > 0?  true:false) );
4552      pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMv, 0, SIZE_2Nx2N, 0, 0, 0 );
4553      pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvd    ( cZeroMv, SIZE_2Nx2N, 0, 0, 0 );  //unnecessary
4554    }
4555
4556    motionCompensation ( pcCU, rpcPredYuv );
4557
4558  }
4559  else
4560  {
4561    assert( 0 );
4562  }
4563
4564  return;
4565}
4566
4567/** encode residual and calculate rate-distortion for a CU block
4568 * \param pcCU
4569 * \param pcYuvOrg
4570 * \param pcYuvPred
4571 * \param rpcYuvResi
4572 * \param rpcYuvResiBest
4573 * \param rpcYuvRec
4574 * \param bSkipRes
4575 * \returns Void
4576 */
4577Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred, TComYuv*& rpcYuvResi, TComYuv*& rpcYuvResiBest, TComYuv*& rpcYuvRec, TComYuv*& rpcYuvResPrd, Bool bSkipRes )
4578{
4579  if ( pcCU->isIntra(0) )
4580  {
4581    return;
4582  }
4583
4584  PredMode  ePredMode    = pcCU->getPredictionMode( 0 );
4585  Bool      bHighPass    = pcCU->getSlice()->getDepth() ? true : false;
4586  UInt      uiBits       = 0, uiBitsBest = 0;
4587  Dist      uiDistortion = 0, uiDistortionBest = 0;
4588
4589  UInt      uiWidth      = pcCU->getWidth ( 0 );
4590  UInt      uiHeight     = pcCU->getHeight( 0 );
4591
4592  //  No residual coding : SKIP mode
4593  if ( ePredMode == MODE_SKIP && bSkipRes )
4594  {
4595    rpcYuvResi->clear();
4596
4597    pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4598
4599#if HHI_INTER_VIEW_RESIDUAL_PRED
4600    // add residual prediction
4601    if( pcCU->getResPredFlag( 0 ) )
4602    {
4603      rpcYuvRec->add( rpcYuvResPrd, uiWidth, uiHeight );
4604      rpcYuvRec->clip( uiWidth, uiHeight );
4605    }
4606#endif
4607
4608#if HHI_VSO   
4609    if ( m_pcRdCost->getUseVSO() )
4610    {
4611      uiDistortion = m_pcRdCost->getDistVS( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight     , false, 0 );
4612    }
4613    else
4614#endif
4615    {
4616      uiDistortion = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4617      + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4618      + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4619    }
4620   
4621
4622    if( m_bUseSBACRD )
4623      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4624
4625    m_pcEntropyCoder->resetBits();
4626#if HHI_MPI
4627    if( pcCU->getTextureModeDepth( 0 ) == -1 )
4628    {
4629#endif
4630    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4631#if HHI_MRG_SKIP
4632    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, 0, true );
4633#else
4634    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 ) //if ( ref. frame list0 has at least 1 entry )
4635    {
4636      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_0);
4637    }
4638    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 ) //if ( ref. frame list1 has at least 1 entry )
4639    {
4640      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_1);
4641    }
4642#endif
4643#if HHI_INTER_VIEW_RESIDUAL_PRED
4644    m_pcEntropyCoder->encodeResPredFlag( pcCU, 0, 0, true );
4645#endif
4646#if HHI_MPI
4647    }
4648#endif
4649
4650    uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4651    pcCU->getTotalBits()       = uiBits;
4652    pcCU->getTotalDistortion() = uiDistortion;
4653
4654#if HHI_VSO
4655    if ( m_pcRdCost->getUseLambdaScaleVSO() )
4656    {
4657      pcCU->getTotalCost() = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );
4658    }
4659    else
4660#endif
4661    {
4662      pcCU->getTotalCost() = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4663    }
4664
4665    if( m_bUseSBACRD )
4666      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4667
4668    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4669    pcCU->setTrIdxSubParts( 0, 0, pcCU->getDepth(0) );
4670
4671#if HHI_VSO
4672    // set Model
4673    if( m_pcRdCost->getUseRenModel() )
4674    {
4675      Pel*  piSrc       = rpcYuvRec->getLumaAddr();
4676      UInt  uiSrcStride = rpcYuvRec->getStride();
4677      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4678    }
4679#endif
4680
4681    return;
4682  }
4683
4684  //  Residual coding.
4685  UInt    uiQp, uiQpBest = 0, uiQpMin, uiQpMax;
4686  Double  dCost, dCostBest = MAX_DOUBLE;
4687
4688  UInt uiBestTrMode = 0;
4689
4690  UInt uiTrLevel = 0;
4691  if( (pcCU->getWidth(0) > pcCU->getSlice()->getSPS()->getMaxTrSize()) )
4692  {
4693    while( pcCU->getWidth(0) > (pcCU->getSlice()->getSPS()->getMaxTrSize()<<uiTrLevel) ) uiTrLevel++;
4694  }
4695  UInt uiMaxTrMode = pcCU->getSlice()->getSPS()->getMaxTrDepth() + uiTrLevel;
4696
4697  while((uiWidth>>uiMaxTrMode) < (g_uiMaxCUWidth>>g_uiMaxCUDepth)) uiMaxTrMode--;
4698
4699  uiQpMin      = bHighPass ? Min( MAX_QP, Max( MIN_QP, pcCU->getQP(0) - m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4700  uiQpMax      = bHighPass ? Min( MAX_QP, Max( MIN_QP, pcCU->getQP(0) + m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4701
4702  pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4703
4704#if HHI_INTER_VIEW_RESIDUAL_PRED
4705  // add residual prediction
4706  if( pcCU->getResPredFlag( 0 ) )
4707  {
4708    rpcYuvRec->add( rpcYuvResPrd, uiWidth, uiHeight );
4709  }
4710#endif
4711#if HHI_INTERVIEW_SKIP
4712  if( bSkipRes)
4713  {
4714    rpcYuvResi->clear() ;
4715  }
4716  else
4717  {
4718    rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4719  }
4720#else
4721  rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4722#endif
4723
4724  for ( uiQp = uiQpMin; uiQp <= uiQpMax; uiQp++ )
4725  {
4726    pcCU->setQPSubParts( uiQp, 0, pcCU->getDepth(0) );
4727    dCost = 0.;
4728    uiBits = 0;
4729    uiDistortion = 0;
4730    if( m_bUseSBACRD )
4731    {
4732      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4733    }
4734
4735    Dist uiZeroDistortion = 0;
4736#if HHI_VSO
4737    if ( m_pcRdCost->getUseVSO() )
4738    {
4739      m_cYuvRecTemp.create( pcYuvPred->getWidth(), pcYuvPred->getHeight()  );
4740    }
4741#endif
4742
4743    xEstimateResidualQT( pcCU, 0, 0, pcYuvOrg, rpcYuvRec, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4744
4745#if HHI_VSO
4746    if ( m_pcRdCost->getUseVSO() )
4747    {
4748      m_cYuvRecTemp.destroy();
4749    }
4750#endif
4751
4752
4753    double dZeroCost;
4754#if HHI_VSO
4755    if( m_pcRdCost->getUseLambdaScaleVSO() )
4756    {
4757      dZeroCost = m_pcRdCost->calcRdCostVSO( 0, uiZeroDistortion );
4758    }
4759    else
4760#endif
4761    {
4762      dZeroCost = m_pcRdCost->calcRdCost( 0, uiZeroDistortion );
4763    }
4764
4765    if ( dZeroCost < dCost )
4766    {
4767      dCost        = dZeroCost;
4768      uiBits       = 0;
4769      uiDistortion = uiZeroDistortion;
4770
4771      const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4772      ::memset( pcCU->getTransformIdx()      , 0, uiQPartNum * sizeof(UChar) );
4773      ::memset( pcCU->getCbf( TEXT_LUMA )    , 0, uiQPartNum * sizeof(UChar) );
4774      ::memset( pcCU->getCbf( TEXT_CHROMA_U ), 0, uiQPartNum * sizeof(UChar) );
4775      ::memset( pcCU->getCbf( TEXT_CHROMA_V ), 0, uiQPartNum * sizeof(UChar) );
4776      ::memset( pcCU->getCoeffY()            , 0, uiWidth * uiHeight * sizeof( TCoeff )      );
4777      ::memset( pcCU->getCoeffCb()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4778      ::memset( pcCU->getCoeffCr()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4779    }
4780    else
4781    {
4782      xSetResidualQTData( pcCU, 0, NULL, pcCU->getDepth(0), false );
4783    }
4784
4785    if( m_bUseSBACRD )
4786    {
4787      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4788    }
4789#if 0 // check
4790    {
4791      m_pcEntropyCoder->resetBits();
4792      m_pcEntropyCoder->encodeCoeff( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
4793      const UInt uiBitsForCoeff = m_pcEntropyCoder->getNumberOfWrittenBits();
4794      if( m_bUseSBACRD )
4795      {
4796        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4797      }
4798      if( uiBitsForCoeff != uiBits )
4799        assert( 0 );
4800    }
4801#endif
4802    uiBits = 0;
4803    {
4804      TComYuv *pDummy = NULL;
4805      xAddSymbolBitsInter( pcCU, 0, 0, uiBits, pDummy, NULL, pDummy );
4806    }
4807
4808    Double dExactCost;
4809#if HHI_VSO
4810    if( m_pcRdCost->getUseLambdaScaleVSO() )
4811    {
4812      dExactCost = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );;
4813    }
4814    else
4815#endif
4816    {
4817      dExactCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4818    }
4819
4820    dCost = dExactCost;
4821
4822    if ( dCost < dCostBest )
4823    {
4824      if ( !pcCU->getQtRootCbf( 0 ) )
4825      {
4826        rpcYuvResiBest->clear();
4827      }
4828      else
4829      {
4830        xSetResidualQTData( pcCU, 0, rpcYuvResiBest, pcCU->getDepth(0), true );
4831      }
4832
4833      if( uiQpMin != uiQpMax && uiQp != uiQpMax )
4834      {
4835        const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4836        ::memcpy( m_puhQTTempTrIdx, pcCU->getTransformIdx(),        uiQPartNum * sizeof(UChar) );
4837        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA ),     uiQPartNum * sizeof(UChar) );
4838        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPartNum * sizeof(UChar) );
4839        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPartNum * sizeof(UChar) );
4840        ::memcpy( m_pcQTTempCoeffY,  pcCU->getCoeffY(),  uiWidth * uiHeight * sizeof( TCoeff )      );
4841        ::memcpy( m_pcQTTempCoeffCb, pcCU->getCoeffCb(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4842        ::memcpy( m_pcQTTempCoeffCr, pcCU->getCoeffCr(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4843      }
4844      uiBitsBest       = uiBits;
4845      uiDistortionBest = uiDistortion;
4846      dCostBest        = dCost;
4847      uiQpBest         = uiQp;
4848
4849      if( m_bUseSBACRD )
4850      {
4851        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4852      }
4853    }
4854
4855#if HHI_VSO
4856    // reset Model
4857    if( m_pcRdCost->getUseRenModel() )
4858    {
4859      Pel*  piSrc       = pcYuvOrg->getLumaAddr();
4860      UInt  uiSrcStride = pcYuvOrg->getStride();
4861      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4862    }
4863#endif
4864  }
4865
4866  assert ( dCostBest != MAX_DOUBLE );
4867
4868  if( uiQpMin != uiQpMax && uiQpBest != uiQpMax )
4869  {
4870    if( m_bUseSBACRD )
4871    {
4872      assert( 0 ); // check
4873      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4874    }
4875    // copy best cbf and trIdx to pcCU
4876    const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4877    ::memcpy( pcCU->getTransformIdx(),       m_puhQTTempTrIdx,  uiQPartNum * sizeof(UChar) );
4878    ::memcpy( pcCU->getCbf( TEXT_LUMA ),     m_puhQTTempCbf[0], uiQPartNum * sizeof(UChar) );
4879    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPartNum * sizeof(UChar) );
4880    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPartNum * sizeof(UChar) );
4881    ::memcpy( pcCU->getCoeffY(),  m_pcQTTempCoeffY,  uiWidth * uiHeight * sizeof( TCoeff )      );
4882    ::memcpy( pcCU->getCoeffCb(), m_pcQTTempCoeffCb, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4883    ::memcpy( pcCU->getCoeffCr(), m_pcQTTempCoeffCr, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4884  }
4885  rpcYuvRec->addClip ( rpcYuvRec, rpcYuvResiBest, 0, uiWidth );
4886
4887  // update with clipped distortion and cost (qp estimation loop uses unclipped values)
4888
4889#if HHI_VSO
4890  if ( m_pcRdCost->getUseVSO() )
4891  {
4892    uiDistortionBest = m_pcRdCost->getDistVS  ( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight, false, 0    );
4893  }
4894  else
4895#endif
4896  {
4897    uiDistortionBest = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4898    + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4899    + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4900  }
4901
4902#if HHI_VSO
4903  if ( m_pcRdCost->getUseLambdaScaleVSO() )
4904  {
4905    dCostBest = m_pcRdCost->calcRdCostVSO( uiBitsBest, uiDistortionBest );
4906  }
4907  else
4908#endif
4909  {
4910    dCostBest = m_pcRdCost->calcRdCost( uiBitsBest, uiDistortionBest );
4911  }
4912
4913  pcCU->getTotalBits()       = uiBitsBest;
4914  pcCU->getTotalDistortion() = uiDistortionBest;
4915  pcCU->getTotalCost()       = dCostBest;
4916
4917  if ( pcCU->isSkipped(0) )
4918  {
4919    uiBestTrMode = 0;
4920    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4921  }
4922
4923  pcCU->setQPSubParts( uiQpBest, 0, pcCU->getDepth(0) );
4924
4925  // set Model
4926#if HHI_VSO
4927  if( m_pcRdCost->getUseRenModel() )
4928  {
4929    Pel*  piSrc       = rpcYuvRec->getLumaAddr();
4930    UInt  uiSrcStride = rpcYuvRec->getStride();
4931    m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4932  }
4933#endif
4934}
4935
4936Void 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 )
4937{
4938  const UInt uiTrMode = uiDepth - pcCU->getDepth( 0 );
4939
4940  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
4941  const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
4942
4943#if HHI_RQT_FORCE_SPLIT_ACC2_PU
4944#if HHI_RQT_FORCE_SPLIT_NxN
4945  const Bool bNxNOK = pcCU->getPartitionSize( 0 ) == SIZE_NxN && uiTrMode > 0;
4946#else
4947  const Bool bNxNOK = pcCU->getPartitionSize( 0 ) == SIZE_NxN;
4948#endif
4949#if HHI_RQT_FORCE_SPLIT_RECT
4950  const Bool bSymmetricOK  = pcCU->getPartitionSize( 0 ) >= SIZE_2NxN  && pcCU->getPartitionSize( 0 ) < SIZE_NxN   && uiTrMode > 0;
4951#else
4952  const Bool bSymmetricOK  = pcCU->getPartitionSize( 0 ) >= SIZE_2NxN  && pcCU->getPartitionSize( 0 ) < SIZE_NxN;
4953#endif
4954  const Bool bNoForceSplit = pcCU->getPartitionSize( 0 ) == SIZE_2Nx2N || bNxNOK || bSymmetricOK;
4955  const Bool bCheckFull    = bNoForceSplit && ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
4956#else
4957  const Bool bCheckFull    = ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
4958#endif
4959
4960  const Bool bCheckSplit  = ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
4961
4962  assert( bCheckFull || bCheckSplit );
4963
4964  Bool  bCodeChroma   = true;
4965  UInt  uiTrModeC     = uiTrMode;
4966  UInt  uiLog2TrSizeC = uiLog2TrSize-1;
4967  if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
4968  {
4969    uiLog2TrSizeC++;
4970    uiTrModeC    --;
4971    UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
4972    bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
4973  }
4974
4975  const UInt uiSetCbf = 1 << uiTrMode;
4976  // code full block
4977  Double dSingleCost = MAX_DOUBLE;
4978  UInt uiSingleBits = 0;
4979  Dist uiSingleDist = 0;
4980  UInt uiAbsSumY = 0, uiAbsSumU = 0, uiAbsSumV = 0;
4981
4982  if( m_bUseSBACRD )
4983  {
4984    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4985  }
4986
4987  if( bCheckFull )
4988  {
4989    const UInt uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
4990    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
4991    TCoeff *pcCoeffCurrY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
4992    TCoeff *pcCoeffCurrU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4993    TCoeff *pcCoeffCurrV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4994
4995    pcCU->setTrIdxSubParts( uiDepth - pcCU->getDepth( 0 ), uiAbsPartIdx, uiDepth );
4996    if (m_pcEncCfg->getUseRDOQ())
4997    {
4998      m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, 1<< uiLog2TrSize, TEXT_LUMA );
4999    }
5000    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA );
5001    m_pcTrQuant->transformNxN( pcCU, pcResi->getLumaAddr( uiAbsPartIdx ), pcResi->getStride (), pcCoeffCurrY, 1<< uiLog2TrSize,    1<< uiLog2TrSize,    uiAbsSumY, TEXT_LUMA,     uiAbsPartIdx );
5002
5003    pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5004
5005    if( bCodeChroma )
5006    {
5007      if (m_pcEncCfg->getUseRDOQ())
5008      {
5009        m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, 1<<uiLog2TrSizeC, TEXT_CHROMA );
5010      }
5011      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
5012      m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr( uiAbsPartIdx ), pcResi->getCStride(), pcCoeffCurrU, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiAbsSumU, TEXT_CHROMA_U, uiAbsPartIdx );
5013      m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr( uiAbsPartIdx ), pcResi->getCStride(), pcCoeffCurrV, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiAbsSumV, TEXT_CHROMA_V, uiAbsPartIdx );
5014      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5015      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5016    }
5017
5018    m_pcEntropyCoder->resetBits();
5019
5020    if (pcCU->getSlice()->getSymbolMode())
5021      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
5022
5023    m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx, 1<< uiLog2TrSize,    1<< uiLog2TrSize,    uiDepth, TEXT_LUMA,     false );
5024    const UInt uiSingleBitsY = m_pcEntropyCoder->getNumberOfWrittenBits();
5025
5026    UInt uiSingleBitsU = 0;
5027    UInt uiSingleBitsV = 0;
5028    if( bCodeChroma )
5029    {
5030      if (pcCU->getSlice()->getSymbolMode())
5031        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode );
5032      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_U, false );
5033      uiSingleBitsU = m_pcEntropyCoder->getNumberOfWrittenBits() - uiSingleBitsY;
5034
5035      if (pcCU->getSlice()->getSymbolMode())
5036        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode );
5037      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_V, false );
5038      uiSingleBitsV = m_pcEntropyCoder->getNumberOfWrittenBits() - ( uiSingleBitsY + uiSingleBitsU );
5039    }
5040
5041    const UInt uiNumSamplesLuma = 1 << (uiLog2TrSize<<1);
5042    const UInt uiNumSamplesChro = 1 << (uiLog2TrSizeC<<1);
5043
5044    Dist uiDistY;
5045
5046//GT VSO
5047
5048    // GT Fix: Not necessary for VSO, however used for chroma later, irrelevant except from valgrind error message
5049    ::memset( m_pTempPel, 0, sizeof( Pel ) * uiNumSamplesLuma ); // not necessary needed for inside of recursion (only at the beginning)
5050
5051#if HHI_VSO
5052    if ( m_pcRdCost->getUseVSO() )
5053    {
5054      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
5055    }
5056    else
5057#endif
5058    {
5059#if IBDI_DISTORTION
5060      uiDistY = m_pcRdCost->getDistPart( pcPred->getLumaAddr( uiAbsPartIdx ), pcPred->getStride(), pcOrg->getLumaAddr( uiAbsPartIdx ), pcOrg->getStride(), 1<< uiLog2TrSize, 1<< uiLog2TrSize);
5061#else
5062      uiDistY = m_pcRdCost->getDistPart( m_pTempPel, 1<< uiLog2TrSize, pcResi->getLumaAddr( uiAbsPartIdx ), pcResi->getStride(), 1<< uiLog2TrSize, 1<< uiLog2TrSize ); // initialized with zero residual distortion
5063#endif
5064    }
5065
5066
5067    if ( puiZeroDist )
5068    {
5069      *puiZeroDist += uiDistY;
5070    }
5071    if( uiAbsSumY )
5072    {
5073      Pel *pcResiCurrY = m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( uiAbsPartIdx );
5074      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA );
5075#if INTRA_DST_TYPE_7 // Inside Inter Encoder Search. So use conventional DCT.
5076    m_pcTrQuant->invtransformNxN( TEXT_LUMA,REG_DCT, pcResiCurrY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),  pcCoeffCurrY, 1<< uiLog2TrSize,    1<< uiLog2TrSize );//this is for inter mode only
5077#else
5078    m_pcTrQuant->invtransformNxN( pcResiCurrY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),  pcCoeffCurrY, 1<< uiLog2TrSize,    1<< uiLog2TrSize );
5079#endif
5080
5081      Dist uiNonzeroDistY;
5082
5083#if HHI_VSO     
5084      if ( m_pcRdCost->getUseVSO() )
5085      {
5086        m_cYuvRecTemp.addClipPartLuma( &m_pcQTTempTComYuv[uiQTTempAccessLayer], pcPred, uiAbsPartIdx, 1<< uiLog2TrSize  );
5087        uiNonzeroDistY = m_pcRdCost->getDistVS( pcCU, uiAbsPartIdx, m_cYuvRecTemp.getLumaAddr(uiAbsPartIdx), m_cYuvRecTemp.getStride(),
5088                                                pcOrg->getLumaAddr( uiAbsPartIdx ), pcOrg->getStride(), 1<< uiLog2TrSize,   1<< uiLog2TrSize, false, 0 );
5089      }
5090      else
5091#endif
5092      {
5093        uiNonzeroDistY = m_pcRdCost->getDistPart( m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( uiAbsPartIdx ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),
5094                                                  pcResi->getLumaAddr( uiAbsPartIdx ), pcResi->getStride(), 1<< uiLog2TrSize,    1<< uiLog2TrSize );
5095      }
5096
5097      Double dSingleCostY;
5098      Double dNullCostY;
5099
5100#if HHI_VSO     
5101      if ( m_pcRdCost->getUseLambdaScaleVSO())
5102      {
5103        dSingleCostY = m_pcRdCost->calcRdCostVSO( uiSingleBitsY, uiNonzeroDistY );
5104        dNullCostY   = m_pcRdCost->calcRdCostVSO( 0, uiDistY );
5105      }
5106      else
5107#endif
5108      {
5109        dSingleCostY = m_pcRdCost->calcRdCost( uiSingleBitsY, uiNonzeroDistY );
5110        dNullCostY   = m_pcRdCost->calcRdCost( 0, uiDistY );
5111      }
5112
5113
5114      if( dNullCostY < dSingleCostY )
5115      {
5116        uiAbsSumY = 0;
5117        ::memset( pcCoeffCurrY, 0, sizeof( TCoeff ) * uiNumSamplesLuma );
5118      }
5119      else
5120      {
5121        uiDistY = uiNonzeroDistY;
5122      }
5123    }
5124
5125    if( !uiAbsSumY )
5126    {
5127      Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( uiAbsPartIdx );
5128      const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride();
5129      for( UInt uiY = 0; uiY < 1<< uiLog2TrSize; ++uiY )
5130      {
5131        ::memset( pcPtr, 0, sizeof(Pel) << uiLog2TrSize );
5132        pcPtr += uiStride;
5133      }
5134    }
5135
5136    Dist uiDistU = 0;
5137    Dist uiDistV = 0;
5138    if( bCodeChroma )
5139    {
5140#if IBDI_DISTORTION
5141      uiDistU = m_pcRdCost->getDistPart( pcPred->getCbAddr( uiAbsPartIdx ), pcPred->getCStride(), pcOrg->getCbAddr( uiAbsPartIdx ), pcOrg->getCStride(), 1<< uiLog2TrSizeC, 1<< uiLog2TrSizeC);
5142#else
5143      uiDistU = m_pcRdCost->getDistPart( m_pTempPel, 1<<uiLog2TrSizeC, pcResi->getCbAddr( uiAbsPartIdx ), pcResi->getCStride(), 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC ); // initialized with zero residual destortion
5144#endif
5145      if ( puiZeroDist )
5146      {
5147        *puiZeroDist += uiDistU;
5148      }
5149      if( uiAbsSumU )
5150      {
5151        Pel *pcResiCurrU = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( uiAbsPartIdx );
5152        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
5153#if INTRA_DST_TYPE_7  // Inside Inter Encoder Search. So use conventional DCT.
5154        m_pcTrQuant->invtransformNxN( TEXT_CHROMA,REG_DCT, pcResiCurrU, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrU, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC);
5155#else
5156        m_pcTrQuant->invtransformNxN( pcResiCurrU, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrU, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC );
5157#endif
5158        const UInt uiNonzeroDistU = m_pcRdCost->getDistPart( m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( uiAbsPartIdx ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(),
5159                                                            pcResi->getCbAddr( uiAbsPartIdx ), pcResi->getCStride(), 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC );
5160        const Double dSingleCostU = m_pcRdCost->calcRdCost( uiSingleBitsU, uiNonzeroDistU );
5161        const Double dNullCostU   = m_pcRdCost->calcRdCost( 0, uiDistU );
5162        if( dNullCostU < dSingleCostU )
5163        {
5164          uiAbsSumU = 0;
5165          ::memset( pcCoeffCurrU, 0, sizeof( TCoeff ) * uiNumSamplesChro );
5166        }
5167        else
5168        {
5169          uiDistU = uiNonzeroDistU;
5170        }
5171      }
5172      if( !uiAbsSumU )
5173      {
5174        Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( uiAbsPartIdx );
5175        const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride();
5176        for( UInt uiY = 0; uiY < 1<<uiLog2TrSizeC; ++uiY )
5177        {
5178          ::memset( pcPtr, 0, sizeof(Pel) << uiLog2TrSizeC );
5179          pcPtr += uiStride;
5180        }
5181      }
5182
5183#if IBDI_DISTORTION
5184      uiDistV = m_pcRdCost->getDistPart( pcPred->getCrAddr( uiAbsPartIdx ), pcPred->getCStride(), pcOrg->getCrAddr( uiAbsPartIdx ), pcOrg->getCStride(), 1<< uiLog2TrSizeC, 1<< uiLog2TrSizeC);
5185#else
5186      uiDistV = m_pcRdCost->getDistPart( m_pTempPel, 1<<uiLog2TrSizeC, pcResi->getCrAddr( uiAbsPartIdx ), pcResi->getCStride(), 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC ); // initialized with zero residual destortion
5187#endif
5188      if ( puiZeroDist )
5189      {
5190        *puiZeroDist += uiDistV;
5191      }
5192      if( uiAbsSumV )
5193      {
5194        Pel *pcResiCurrV = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr  ( uiAbsPartIdx );
5195        if( !uiAbsSumU )
5196        {
5197          m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA );
5198        }
5199#if INTRA_DST_TYPE_7   // Inside Inter Encoder Search. So use conventional DCT.
5200        m_pcTrQuant->invtransformNxN( TEXT_CHROMA,REG_DCT, pcResiCurrV, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrV, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC );
5201#else
5202        m_pcTrQuant->invtransformNxN( pcResiCurrV, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrV, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC );
5203#endif
5204        const UInt uiNonzeroDistV = m_pcRdCost->getDistPart( m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( uiAbsPartIdx ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(),
5205                                                            pcResi->getCrAddr( uiAbsPartIdx ), pcResi->getCStride(), 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC );
5206        const Double dSingleCostV = m_pcRdCost->calcRdCost( uiSingleBitsV, uiNonzeroDistV );
5207        const Double dNullCostV   = m_pcRdCost->calcRdCost( 0, uiDistV );
5208        if( dNullCostV < dSingleCostV )
5209        {
5210          uiAbsSumV = 0;
5211          ::memset( pcCoeffCurrV, 0, sizeof( TCoeff ) * uiNumSamplesChro );
5212        }
5213        else
5214        {
5215          uiDistV = uiNonzeroDistV;
5216        }
5217      }
5218      if( !uiAbsSumV )
5219      {
5220        Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( uiAbsPartIdx );
5221        const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride();
5222        for( UInt uiY = 0; uiY < 1<<uiLog2TrSizeC; ++uiY )
5223        {
5224          ::memset( pcPtr, 0, sizeof(Pel) << uiLog2TrSizeC );
5225          pcPtr += uiStride;
5226        }
5227      }
5228    }
5229    pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5230    if( bCodeChroma )
5231    {
5232      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5233      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5234    }
5235
5236    if( m_bUseSBACRD )
5237    {
5238      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5239    }
5240
5241    m_pcEntropyCoder->resetBits();
5242
5243#if CAVLC_RQT_CBP
5244    if (pcCU->getSlice()->getSymbolMode())
5245    {
5246#endif
5247    if( uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5248    {
5249      m_pcEntropyCoder->encodeTransformSubdivFlag( 0, uiDepth );
5250    }
5251#if CAVLC_RQT_CBP
5252    }
5253#endif
5254
5255    if (pcCU->getSlice()->getSymbolMode())
5256    {
5257      if( bCodeChroma )
5258      {
5259        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode );
5260        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode );
5261      }
5262
5263      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
5264    }
5265
5266    m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx, 1<< uiLog2TrSize,    1<< uiLog2TrSize,    uiDepth, TEXT_LUMA,     false );
5267
5268    if( bCodeChroma )
5269    {
5270      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_U, false );
5271      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_V, false );
5272    }
5273
5274    uiSingleBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5275
5276    uiSingleDist = uiDistY + uiDistU + uiDistV;
5277#if HHI_VSO
5278    if ( m_pcRdCost->getUseLambdaScaleVSO())
5279    {
5280      dSingleCost = m_pcRdCost->calcRdCostVSO( uiSingleBits, uiSingleDist );
5281    }
5282    else
5283#endif
5284    {
5285      dSingleCost = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDist );
5286    }
5287  }
5288
5289  // code sub-blocks
5290  if( bCheckSplit )
5291  {
5292    if( m_bUseSBACRD && bCheckFull )
5293    {
5294      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5295      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5296    }
5297    Dist uiSubdivDist = 0;
5298    UInt uiSubdivBits = 0;
5299    Double dSubdivCost = 0.0;
5300
5301    const UInt uiQPartNumSubdiv = pcCU->getPic()->getNumPartInCU() >> ((uiDepth + 1 ) << 1);
5302    for( UInt ui = 0; ui < 4; ++ui )
5303    {
5304      xEstimateResidualQT( pcCU, ui, uiAbsPartIdx + ui * uiQPartNumSubdiv, pcOrg, pcPred, pcResi, uiDepth + 1, dSubdivCost, uiSubdivBits, uiSubdivDist, bCheckFull ? NULL : puiZeroDist );
5305    }
5306
5307    UInt uiYCbf = 0;
5308    UInt uiUCbf = 0;
5309    UInt uiVCbf = 0;
5310    for( UInt ui = 0; ui < 4; ++ui )
5311    {
5312      uiYCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, TEXT_LUMA,     uiTrMode + 1 );
5313      uiUCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, TEXT_CHROMA_U, uiTrMode + 1 );
5314      uiVCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, TEXT_CHROMA_V, uiTrMode + 1 );
5315    }
5316    for( UInt ui = 0; ui < 4 * uiQPartNumSubdiv; ++ui )
5317    {
5318      pcCU->getCbf( TEXT_LUMA     )[uiAbsPartIdx + ui] |= uiYCbf << uiTrMode;
5319      pcCU->getCbf( TEXT_CHROMA_U )[uiAbsPartIdx + ui] |= uiUCbf << uiTrMode;
5320      pcCU->getCbf( TEXT_CHROMA_V )[uiAbsPartIdx + ui] |= uiVCbf << uiTrMode;
5321    }
5322
5323    if( m_bUseSBACRD )
5324    {
5325      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5326    }
5327    m_pcEntropyCoder->resetBits();
5328
5329    {
5330      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, true,  TEXT_LUMA );
5331      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, false, TEXT_LUMA );
5332      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, false, TEXT_CHROMA_U );
5333      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, false, TEXT_CHROMA_V );
5334    }
5335
5336    uiSubdivBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5337
5338#if HHI_VSO
5339    if ( m_pcRdCost->getUseLambdaScaleVSO())
5340    {
5341      dSubdivCost  = m_pcRdCost->calcRdCostVSO( uiSubdivBits, uiSubdivDist );
5342    }
5343    else
5344#endif
5345    {
5346      dSubdivCost  = m_pcRdCost->calcRdCost( uiSubdivBits, uiSubdivDist );
5347    }
5348
5349    if( uiYCbf || uiUCbf || uiVCbf || !bCheckFull )
5350    {
5351      if( dSubdivCost < dSingleCost )
5352      {
5353        rdCost += dSubdivCost;
5354        ruiBits += uiSubdivBits;
5355        ruiDist += uiSubdivDist;
5356        return;
5357      }
5358    }
5359    assert( bCheckFull );
5360    if( m_bUseSBACRD )
5361    {
5362      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5363    }
5364  }
5365
5366#if HHI_VSO
5367  if ( m_pcRdCost->getUseRenModel() )
5368  {
5369    UInt  uiWidth     = 1<< uiLog2TrSize;
5370    UInt  uiHeight    = 1<< uiLog2TrSize;
5371
5372    Pel*  piSrc;
5373    UInt  uiSrcStride;
5374
5375    if ( uiAbsSumY )
5376    {
5377      UInt  uiQTLayer   = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5378      m_cYuvRecTemp.addClipPartLuma( &m_pcQTTempTComYuv[uiQTLayer], pcPred, uiAbsPartIdx, 1<< uiLog2TrSize  );
5379      piSrc       = m_cYuvRecTemp.getLumaAddr( uiAbsPartIdx );
5380      uiSrcStride = m_cYuvRecTemp.getStride  ();
5381    }
5382    else
5383    {
5384      piSrc       = pcPred->getLumaAddr( uiAbsPartIdx );
5385      uiSrcStride = pcPred->getStride  ();
5386    }
5387
5388    m_pcRdCost->setRenModelData( pcCU, uiAbsPartIdx, piSrc, (Int) uiSrcStride, (Int) uiWidth, (Int) uiHeight );
5389  }
5390#endif
5391
5392  rdCost += dSingleCost;
5393  ruiBits += uiSingleBits;
5394  ruiDist += uiSingleDist;
5395
5396  pcCU->setTrIdxSubParts( uiTrMode, uiAbsPartIdx, uiDepth );
5397
5398  pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5399  if( bCodeChroma )
5400  {
5401    pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5402    pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5403  }
5404}
5405
5406Void TEncSearch::xEncodeResidualQT( TComDataCU* pcCU, UInt uiAbsPartIdx, const UInt uiDepth, Bool bSubdivAndCbf, TextType eType )
5407{
5408  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5409  const UInt uiCurrTrMode = uiDepth - pcCU->getDepth( 0 );
5410  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5411
5412  const Bool bSubdiv = uiCurrTrMode != uiTrMode;
5413
5414  const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
5415
5416#if CAVLC_RQT_CBP
5417  if(pcCU->getSlice()->getSymbolMode() == 0 )
5418  {
5419    if( bSubdivAndCbf && uiCurrTrMode != 0)
5420      m_pcEntropyCoder->m_pcEntropyCoderIf->codeCbfTrdiv( pcCU, uiAbsPartIdx, uiDepth );
5421  }
5422#endif
5423
5424#if CAVLC_RQT_CBP
5425  if(pcCU->getSlice()->getSymbolMode())
5426  {
5427#endif
5428  if( bSubdivAndCbf && uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() && uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5429  {
5430    m_pcEntropyCoder->encodeTransformSubdivFlag( bSubdiv, uiDepth );
5431  }
5432#if CAVLC_RQT_CBP
5433  }
5434#endif
5435
5436  if (pcCU->getSlice()->getSymbolMode())
5437  {
5438    assert( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA );
5439    if( bSubdivAndCbf && uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
5440    {
5441      const Bool bFirstCbfOfCU = uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() || uiCurrTrMode == 0;
5442      if( bFirstCbfOfCU || uiLog2TrSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
5443      {
5444        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode - 1 ) )
5445        {
5446          m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode );
5447        }
5448        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode - 1 ) )
5449        {
5450          m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode );
5451        }
5452      }
5453      else if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
5454      {
5455        assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode - 1 ) );
5456        assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode - 1 ) );
5457      }
5458    }
5459  }
5460
5461  if( !bSubdiv )
5462  {
5463    const UInt uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
5464    assert( 16 == uiNumCoeffPerAbsPartIdxIncrement ); // check
5465    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5466    TCoeff *pcCoeffCurrY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5467    TCoeff *pcCoeffCurrU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5468    TCoeff *pcCoeffCurrV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5469
5470    Bool  bCodeChroma   = true;
5471    UInt  uiTrModeC     = uiTrMode;
5472    UInt  uiLog2TrSizeC = uiLog2TrSize-1;
5473    if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
5474    {
5475      uiLog2TrSizeC++;
5476      uiTrModeC    --;
5477      UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
5478      bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
5479    }
5480
5481    if( bSubdivAndCbf )
5482    {
5483      if (pcCU->getSlice()->getSymbolMode())
5484      {
5485        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
5486      }
5487    }
5488    else
5489    {
5490      if( eType == TEXT_LUMA     && pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA,     uiTrMode ) )
5491      {
5492        m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx, 1<< uiLog2TrSize,    1<< uiLog2TrSize,    uiDepth, TEXT_LUMA,     false );
5493      }
5494      if( bCodeChroma )
5495      {
5496        if( eType == TEXT_CHROMA_U && pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode ) )
5497        {
5498          m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_U, false );
5499        }
5500        if( eType == TEXT_CHROMA_V && pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode ) )
5501        {
5502          m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC, uiDepth, TEXT_CHROMA_V, false );
5503        }
5504      }
5505    }
5506  }
5507  else
5508  {
5509    if( bSubdivAndCbf || pcCU->getCbf( uiAbsPartIdx, eType, uiCurrTrMode ) )
5510    {
5511      const UInt uiQPartNumSubdiv = pcCU->getPic()->getNumPartInCU() >> ((uiDepth + 1 ) << 1);
5512#if !CAVLC_RQT_CBP
5513      if(pcCU->getSlice()->getSymbolMode() == 0)
5514      {
5515        if( !bSubdivAndCbf && (eType == TEXT_LUMA || uiLog2TrSize-1 > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize()) )
5516          m_pcEntropyCoder->m_pcEntropyCoderIf->codeBlockCbf(pcCU, uiAbsPartIdx, eType, uiCurrTrMode + 1, uiQPartNumSubdiv, true);
5517      }
5518#endif
5519      for( UInt ui = 0; ui < 4; ++ui )
5520      {
5521        xEncodeResidualQT( pcCU, uiAbsPartIdx + ui * uiQPartNumSubdiv, uiDepth + 1, bSubdivAndCbf, eType );
5522      }
5523    }
5524  }
5525}
5526
5527Void TEncSearch::xSetResidualQTData( TComDataCU* pcCU, UInt uiAbsPartIdx, TComYuv* pcResi, UInt uiDepth, Bool bSpatial )
5528{
5529  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5530  const UInt uiCurrTrMode = uiDepth - pcCU->getDepth( 0 );
5531  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5532
5533  if( uiCurrTrMode == uiTrMode )
5534  {
5535    const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
5536    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5537
5538    Bool  bCodeChroma   = true;
5539    UInt  uiTrModeC     = uiTrMode;
5540    UInt  uiLog2TrSizeC = uiLog2TrSize-1;
5541    if( uiLog2TrSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
5542    {
5543      uiLog2TrSizeC++;
5544      uiTrModeC    --;
5545      UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
5546      bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
5547    }
5548
5549    if( bSpatial )
5550    {
5551      m_pcQTTempTComYuv[uiQTTempAccessLayer].copyPartToPartLuma    ( pcResi, uiAbsPartIdx, 1<<uiLog2TrSize , 1<<uiLog2TrSize  );
5552      if( bCodeChroma )
5553      {
5554        m_pcQTTempTComYuv[uiQTTempAccessLayer].copyPartToPartChroma( pcResi, uiAbsPartIdx, 1<<uiLog2TrSizeC, 1<<uiLog2TrSizeC );
5555      }
5556    }
5557    else
5558    {
5559      UInt    uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
5560      UInt    uiNumCoeffY = ( 1 << ( uiLog2TrSize << 1 ) );
5561      TCoeff* pcCoeffSrcY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5562      TCoeff* pcCoeffDstY = pcCU->getCoeffY() + uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5563      ::memcpy( pcCoeffDstY, pcCoeffSrcY, sizeof( TCoeff ) * uiNumCoeffY );
5564      if( bCodeChroma )
5565      {
5566        UInt    uiNumCoeffC = ( 1 << ( uiLog2TrSizeC << 1 ) );
5567        TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5568        TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5569        TCoeff* pcCoeffDstU = pcCU->getCoeffCb() + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5570        TCoeff* pcCoeffDstV = pcCU->getCoeffCr() + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5571        ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
5572        ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
5573      }
5574    }
5575  }
5576  else
5577  {
5578    const UInt uiQPartNumSubdiv = pcCU->getPic()->getNumPartInCU() >> ((uiDepth + 1 ) << 1);
5579    for( UInt ui = 0; ui < 4; ++ui )
5580    {
5581      xSetResidualQTData( pcCU, uiAbsPartIdx + ui * uiQPartNumSubdiv, pcResi, uiDepth + 1, bSpatial );
5582    }
5583  }
5584}
5585
5586UInt TEncSearch::xModeBitsIntra( TComDataCU* pcCU, UInt uiMode, UInt uiPU, UInt uiPartOffset, UInt uiDepth, UInt uiInitTrDepth )
5587{
5588  if( m_bUseSBACRD )
5589  {
5590    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
5591  }
5592  pcCU->setLumaIntraDirSubParts ( uiMode, uiPartOffset, uiDepth + uiInitTrDepth );
5593
5594  m_pcEntropyCoder->resetBits();
5595  m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPartOffset);
5596
5597  return m_pcEntropyCoder->getNumberOfWrittenBits();
5598}
5599
5600UInt TEncSearch::xUpdateCandList( UInt uiMode, Double uiCost, UInt uiFastCandNum, UInt * CandModeList, Double * CandCostList )
5601{
5602  UInt i;
5603  UInt shift=0;
5604
5605  while ( shift<uiFastCandNum && uiCost<CandCostList[ uiFastCandNum-1-shift ] ) shift++;
5606
5607  if( shift!=0 )
5608  {
5609    for(i=1; i<shift; i++)
5610    {
5611      CandModeList[ uiFastCandNum-i ] = CandModeList[ uiFastCandNum-1-i ];
5612      CandCostList[ uiFastCandNum-i ] = CandCostList[ uiFastCandNum-1-i ];
5613    }
5614    CandModeList[ uiFastCandNum-shift ] = uiMode;
5615    CandCostList[ uiFastCandNum-shift ] = uiCost;
5616    return 1;
5617  }
5618
5619  return 0;
5620}
5621
5622/** add inter-prediction syntax elements for a CU block
5623 * \param pcCU
5624 * \param uiQp
5625 * \param uiTrMode
5626 * \param ruiBits
5627 * \param rpcYuvRec
5628 * \param pcYuvPred
5629 * \param rpcYuvResi
5630 * \returns Void
5631 */
5632Void  TEncSearch::xAddSymbolBitsInter( TComDataCU* pcCU, UInt uiQp, UInt uiTrMode, UInt& ruiBits, TComYuv*& rpcYuvRec, TComYuv*pcYuvPred, TComYuv*& rpcYuvResi )
5633{
5634  if ( pcCU->isSkipped( 0 ) )
5635  {
5636#if HHI_MPI
5637    if( pcCU->getTextureModeDepth( 0 ) != -1 )
5638    {
5639      return;
5640    }
5641#endif
5642    m_pcEntropyCoder->resetBits();
5643    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
5644    ruiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5645
5646    m_pcEntropyCoder->resetBits();
5647#if HHI_MRG_SKIP
5648    m_pcEntropyCoder->encodeMergeIndex(pcCU, 0, 0, true);
5649#else
5650    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 ) //if ( ref. frame list0 has at least 1 entry )
5651    {
5652      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_0);
5653    }
5654    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 ) //if ( ref. frame list1 has at least 1 entry )
5655    {
5656      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_1);
5657    }
5658#endif
5659#if HHI_INTER_VIEW_RESIDUAL_PRED
5660    m_pcEntropyCoder->encodeResPredFlag( pcCU, 0, 0, true );
5661#endif
5662    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5663  }
5664  else
5665  {
5666    m_pcEntropyCoder->resetBits();
5667#if HHI_MPI
5668    if( pcCU->getTextureModeDepth( 0 ) == -1 )
5669    {
5670#endif
5671      m_pcEntropyCoder->encodeSkipFlag ( pcCU, 0, true );
5672#if HHI_MRG_SKIP
5673      if (pcCU->getPredictionMode(0) == MODE_SKIP)
5674      {
5675        pcCU->setPredModeSubParts( MODE_INTER, 0, pcCU->getDepth(0) );
5676      }
5677#endif
5678      m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
5679      m_pcEntropyCoder->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
5680      m_pcEntropyCoder->encodePredInfo( pcCU, 0, true );
5681
5682#if HHI_INTER_VIEW_RESIDUAL_PRED
5683      m_pcEntropyCoder->encodeResPredFlag( pcCU, 0, 0, true );
5684#endif
5685#if HHI_MPI
5686    }
5687#endif
5688    m_pcEntropyCoder->encodeCoeff   ( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
5689
5690    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5691  }
5692}
5693
5694
5695Void TEncSearch::xExtDIFUpSamplingH ( TComPattern* pcPattern, TComYuv* pcYuvExt  )
5696{
5697  Int   x, y;
5698
5699  Int   iWidth      = pcPattern->getROIYWidth();
5700  Int   iHeight     = pcPattern->getROIYHeight();
5701
5702  Int   iPatStride  = pcPattern->getPatternLStride();
5703  Int   iExtStride  = pcYuvExt ->getStride();
5704
5705  Int*  piSrcY;
5706  Int*  piDstY;
5707  Pel*  piDstYPel;
5708  Pel*  piSrcYPel;
5709
5710  //  Copy integer-pel
5711  piSrcYPel = pcPattern->getROIY() - 4 - iPatStride;
5712  piDstY    = m_piYuvExt;//pcYuvExt->getLumaAddr();
5713  piDstYPel = pcYuvExt->getLumaAddr();
5714  for ( y = 0; y < iHeight + 2; y++ )
5715  {
5716    for ( x = 0; x < iWidth + 8; x++ )
5717    {
5718      piDstYPel[x << 2] = piSrcYPel[x];
5719    }
5720    piSrcYPel +=  iPatStride;
5721    piDstY    += (m_iYuvExtStride << 2);
5722    piDstYPel += (iExtStride      << 2);
5723  }
5724
5725  //  Half-pel NORM. : vertical
5726  piSrcYPel = pcPattern->getROIY()    - iPatStride - 4;
5727  piDstY    = m_piYuvExt              + (m_iYuvExtStride<<1);
5728  piDstYPel = pcYuvExt->getLumaAddr() + (iExtStride<<1);
5729  xCTI_FilterHalfVer     (piSrcYPel, iPatStride,     1, iWidth + 8, iHeight + 1, m_iYuvExtStride<<2, 4, piDstY, iExtStride<<2, piDstYPel);
5730
5731  //  Half-pel interpolation : horizontal
5732  piSrcYPel = pcPattern->getROIY()   -  iPatStride - 1;
5733  piDstYPel = pcYuvExt->getLumaAddr() + 14;
5734  xCTI_FilterHalfHor (piSrcYPel, iPatStride,     1,  iWidth + 1, iHeight + 1,  iExtStride<<2, 4, piDstYPel);
5735
5736  //  Half-pel interpolation : center
5737  piSrcY    = m_piYuvExt              + (m_iYuvExtStride<<1) + (3 << 2);
5738  piDstYPel = pcYuvExt->getLumaAddr() + (iExtStride<<1)      + 14;
5739  xCTI_FilterHalfHor       (piSrcY, m_iYuvExtStride<<2, 4, iWidth + 1, iHeight + 1,iExtStride<<2, 4, piDstYPel);
5740
5741}
5742
5743Void TEncSearch::xExtDIFUpSamplingQ   ( TComPattern* pcPatternKey, Pel* piDst, Int iDstStride, Pel* piSrcPel, Int iSrcPelStride, Int* piSrc, Int iSrcStride, UInt uiFilter )
5744{
5745  Int   x, y;
5746
5747  Int   iWidth      = pcPatternKey->getROIYWidth();
5748  Int   iHeight     = pcPatternKey->getROIYHeight();
5749
5750  Int*  piSrcY;
5751  Int*  piDstY;
5752  Pel*  piDstYPel;
5753  Pel*  piSrcYPel;
5754
5755  Int iSrcStride4 = (iSrcStride<<2);
5756  Int iDstStride4 = (iDstStride<<2);
5757
5758  switch (uiFilter)
5759  {
5760    case 0:
5761    {
5762      //  Quater-pel interpolation : vertical
5763      piSrcYPel = piSrcPel - 3;
5764      piDstY    = piSrc - 14 - iSrcStride;
5765      xCTI_FilterQuarter0Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 7, iHeight, iSrcStride4, 4, piDstY);
5766
5767      piSrcYPel = piSrcPel - 3;
5768      piDstY    = piSrc - 14 + iSrcStride;
5769      xCTI_FilterQuarter1Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 7, iHeight, iSrcStride4, 4, piDstY);
5770      // Above three pixels
5771      piSrcY    = piSrc-2 - iSrcStride;
5772      piDstYPel = piDst-1 - iDstStride;
5773      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5774
5775      piSrcY    = piSrc-2 - iSrcStride;
5776      piDstYPel = piDst   - iDstStride;;
5777      xCTI_FilterHalfHor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5778
5779      piSrcY    = piSrc-2 - iSrcStride;
5780      piDstYPel = piDst+1 - iDstStride;
5781      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5782
5783      // Middle two pixels
5784      piSrcY    = piSrc-2;
5785      piDstYPel = piDst-1;
5786      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5787
5788      piSrcY    = piSrc-2;
5789      piDstYPel = piDst+1;
5790      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5791
5792      // Below three pixels
5793      piSrcY    = piSrc-2 + iSrcStride;
5794      piDstYPel = piDst-1 + iDstStride;
5795      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5796
5797      piSrcY    = piSrc-2 + iSrcStride;
5798      piDstYPel = piDst   + iDstStride;;
5799      xCTI_FilterHalfHor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5800
5801      piSrcY    = piSrc-2 + iSrcStride;
5802      piDstYPel = piDst+1 + iDstStride;
5803      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5804      break;
5805    }
5806    case 1:
5807    {
5808      //  Quater-pel interpolation : vertical
5809      piSrcYPel = piSrcPel - 4;
5810      piDstY    = piSrc-16 - iSrcStride;
5811      xCTI_FilterQuarter0Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 8, iHeight, iSrcStride4, 4, piDstY);
5812
5813      piSrcYPel = piSrcPel - 4;
5814      piDstY    = piSrc-16 + iSrcStride;
5815      xCTI_FilterQuarter1Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 8, iHeight, iSrcStride4, 4, piDstY);
5816      // Left three pixels
5817      piSrcY    = piSrc-4 - iSrcStride;
5818      piDstYPel = piDst-1 - iDstStride;
5819      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5820
5821      piSrcY    = piSrc-4;
5822      piDstYPel = piDst-1;
5823      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5824
5825      piSrcY    = piSrc-4 + iSrcStride;
5826      piDstYPel = piDst-1 + iDstStride;
5827      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5828
5829      // Middle two pixels
5830      piSrcY    = piSrc - iSrcStride;
5831      piDstYPel = piDst - iDstStride;
5832      Int iSrcStride2 = (iSrcStride<<1);
5833      Int iDstStride2 = (iDstStride<<1);
5834
5835      for (y=0; y < iHeight*2; y++)
5836      {
5837        for (x=0; x < iWidth; x++)
5838        {
5839          piDstYPel[x*4] = Clip( (piSrcY[x*4] +  32) >>  6 );
5840        }
5841        piSrcY+=iSrcStride2;
5842        piDstYPel+=iDstStride2;
5843      }
5844
5845      // Right three pixels
5846      piSrcY    = piSrc   - iSrcStride;
5847      piDstYPel = piDst+1 - iDstStride;
5848      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5849
5850      piSrcY    = piSrc;
5851      piDstYPel = piDst+1;
5852      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5853
5854      piSrcY    = piSrc   + iSrcStride;
5855      piDstYPel = piDst+1 + iDstStride;
5856      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5857
5858      break;
5859    }
5860    case 2:
5861    {
5862      //  Quater-pel interpolation : vertical
5863      piSrcYPel = piSrcPel - 3 - iSrcPelStride;;
5864      piDstY    = piSrc - 14 - iSrcStride;
5865      xCTI_FilterQuarter1Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 7, iHeight, iSrcStride4, 4, piDstY);
5866
5867      piSrcYPel = piSrcPel - 3;
5868      piDstY    = piSrc - 14 + iSrcStride;
5869      xCTI_FilterQuarter0Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 7, iHeight, iSrcStride4, 4, piDstY);
5870      // Above three pixels
5871      piSrcY    = piSrc-2 - iSrcStride;
5872      piDstYPel = piDst-1 - iDstStride;
5873      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5874
5875      piSrcY    = piSrc-2 - iSrcStride;
5876      piDstYPel = piDst   - iDstStride;;
5877      xCTI_FilterHalfHor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5878
5879      piSrcY    = piSrc-2 - iSrcStride;
5880      piDstYPel = piDst+1 - iDstStride;
5881      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5882
5883      // Middle two pixels
5884      piDstYPel = piDst - 1;
5885      xCTI_FilterQuarter0Hor(piSrcPel, iSrcPelStride, 1, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5886
5887      piDstYPel = piDst + 1;
5888      xCTI_FilterQuarter1Hor(piSrcPel, iSrcPelStride, 1, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5889
5890      // Below three pixels
5891      piSrcY    = piSrc-2 + iSrcStride;
5892      piDstYPel = piDst-1 + iDstStride;
5893      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5894
5895      piSrcY    = piSrc-2 + iSrcStride;
5896      piDstYPel = piDst   + iDstStride;;
5897      xCTI_FilterHalfHor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5898
5899      piSrcY    = piSrc-2 + iSrcStride;
5900      piDstYPel = piDst+1 + iDstStride;
5901      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5902      break;
5903    }
5904    case 3:
5905    {
5906      //  Quater-pel interpolation : vertical
5907      piSrcYPel = piSrcPel-4 - iSrcPelStride;
5908      piDstY    = piSrc-16 - iSrcStride;
5909      xCTI_FilterQuarter1Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 8, iHeight, iSrcStride4, 4, piDstY);
5910
5911      piSrcYPel = piSrcPel-4;
5912      piDstY    = piSrc-16 + iSrcStride;
5913      xCTI_FilterQuarter0Ver(piSrcYPel, iSrcPelStride, 1, iWidth + 8, iHeight, iSrcStride4, 4, piDstY);
5914      // Left three pixels
5915      piSrcY    = piSrc-4 - iSrcStride;
5916      piDstYPel = piDst-1 - iDstStride;
5917      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5918
5919      piSrcYPel = piSrcPel-1;
5920      piDstYPel = piDst-1;
5921      xCTI_FilterQuarter1Hor(piSrcYPel, iSrcPelStride, 1, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5922
5923      piSrcY    = piSrc-4 + iSrcStride;
5924      piDstYPel = piDst-1 + iDstStride;
5925      xCTI_FilterQuarter1Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5926
5927      // Middle two pixels
5928      piSrcY    = piSrc - iSrcStride;
5929      piDstYPel = piDst - iDstStride;
5930      Int iSrcStride2 = (iSrcStride<<1);
5931      Int iDstStride2 = (iDstStride<<1);
5932
5933      for (y=0; y < iHeight*2; y++)
5934      {
5935        for (x=0; x < iWidth; x++)
5936        {
5937          piDstYPel[x*4] = Clip( (piSrcY[x*4] + 32) >>  6 );
5938        }
5939        piSrcY+=iSrcStride2;
5940        piDstYPel+=iDstStride2;
5941      }
5942
5943      // Right three pixels
5944      piSrcY    = piSrc   - iSrcStride;
5945      piDstYPel = piDst+1 - iDstStride;
5946      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5947
5948      piDstYPel = piDst+1;
5949      xCTI_FilterQuarter0Hor(piSrcPel, iSrcPelStride, 1, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5950
5951      piSrcY    = piSrc   + iSrcStride;
5952      piDstYPel = piDst+1 + iDstStride;
5953      xCTI_FilterQuarter0Hor(piSrcY, iSrcStride4, 4, iWidth, iHeight, iDstStride4, 4, piDstYPel);
5954
5955      break;
5956    }
5957    default:
5958    {
5959      assert(0);
5960    }
5961  }
5962}
5963#ifdef WEIGHT_PRED
5964Void  TEncSearch::setWpScalingDistParam( TComDataCU* pcCU, Int iRefIdx0, Int iRefIdx1 , RefPicList eRefPicListCur )
5965{
5966  if ( iRefIdx0<0 && iRefIdx1<0 )
5967  {
5968    m_cDistParam.applyWeight = false;
5969    return;
5970  }
5971
5972  TComSlice       *pcSlice  = pcCU->getSlice();
5973  TComPPS         *pps      = pcCU->getSlice()->getPPS();
5974  wpScalingParam  *wp0 , *wp1;
5975
5976  m_cDistParam.applyWeight = ( pcSlice->getSliceType()==P_SLICE && pps->getUseWP() ) || ( pcSlice->getSliceType()==B_SLICE && pps->getWPBiPredIdc() ) ;
5977
5978  if ( !m_cDistParam.applyWeight ) return;
5979
5980  getWpScaling( pcCU, iRefIdx0, iRefIdx1, wp0 , wp1 );
5981
5982  if ( iRefIdx0 < 0 ) wp0 = NULL;
5983  if ( iRefIdx1 < 0 ) wp1 = NULL;
5984
5985  m_cDistParam.wpCur  = NULL;
5986  m_cDistParam.wpRef  = NULL;
5987
5988  if ( eRefPicListCur == REF_PIC_LIST_0 )
5989  {
5990    m_cDistParam.wpCur = wp0;
5991    m_cDistParam.wpRef = wp1;
5992  }
5993  else
5994  {
5995    m_cDistParam.wpCur = wp1;
5996    m_cDistParam.wpRef = wp0;
5997  }
5998}
5999#endif
6000
Note: See TracBrowser for help on using the repository browser.