source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSearch.cpp @ 504

Last change on this file since 504 was 504, checked in by zhang, 11 years ago

Merge Dev2.a to Dev2 and simulation results updated

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