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

Last change on this file since 56 was 56, checked in by hschwarz, 12 years ago

updated trunk (move to HM6.1)

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