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

Last change on this file since 510 was 510, checked in by mitsubishi-htm, 11 years ago

-VSP compensation part migration, not fully tested, intermediate version

  • Property svn:eol-style set to native
File size: 249.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
3174#if H_3D_VSP
3175                                 , Int* vspFlag
3176#endif
3177                                 , Int& numValidMergeCand
3178                                 )
3179{
3180  UInt uiAbsPartIdx = 0;
3181  Int iWidth = 0;
3182  Int iHeight = 0; 
3183
3184  pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
3185  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
3186  PartSize partSize = pcCU->getPartitionSize( 0 );
3187  if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && partSize != SIZE_2Nx2N && pcCU->getWidth( 0 ) <= 8 )
3188  {
3189    pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
3190    if ( iPUIdx == 0 )
3191    {
3192      pcCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours
3193#if H_3D_VSP
3194                                   , vspFlag
3195#endif
3196                                   , numValidMergeCand
3197                                   );
3198    }
3199    pcCU->setPartSizeSubParts( partSize, 0, uiDepth );
3200  }
3201  else
3202  {
3203    pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours
3204#if H_3D_VSP
3205                                 , vspFlag
3206#endif
3207                                 , numValidMergeCand
3208                                 );
3209  }
3210  xRestrictBipredMergeCand( pcCU, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
3211
3212  ruiCost = MAX_UINT;
3213  for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
3214  {
3215    {
3216      UInt uiCostCand = MAX_UINT;
3217      UInt uiBitsCand = 0;
3218     
3219      PartSize ePartSize = pcCU->getPartitionSize( 0 );
3220
3221      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
3222      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
3223
3224#if H_3D_VSP
3225      pcCU->setVSPFlagSubParts( vspFlag[uiMergeCand], uiAbsPartIdx, iPUIdx, pcCU->getDepth( uiAbsPartIdx ) );
3226#endif
3227
3228      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
3229      uiBitsCand = uiMergeCand + 1;
3230      if (uiMergeCand == m_pcEncCfg->getMaxNumMergeCand() -1)
3231      {
3232         uiBitsCand--;
3233      }
3234      uiCostCand = uiCostCand + m_pcRdCost->getCost( uiBitsCand );
3235      if ( uiCostCand < ruiCost )
3236      {
3237        ruiCost = uiCostCand;
3238        pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
3239        pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
3240        uiInterDir = uhInterDirNeighbours[uiMergeCand];
3241        uiMergeIndex = uiMergeCand;
3242      }
3243    }
3244  }
3245}
3246
3247/** convert bi-pred merge candidates to uni-pred
3248 * \param pcCU
3249 * \param puIdx
3250 * \param mvFieldNeighbours
3251 * \param interDirNeighbours
3252 * \param numValidMergeCand
3253 * \returns Void
3254 */
3255Void TEncSearch::xRestrictBipredMergeCand( TComDataCU* pcCU, UInt puIdx, TComMvField* mvFieldNeighbours, UChar* interDirNeighbours, Int numValidMergeCand )
3256{
3257  if ( pcCU->isBipredRestriction(puIdx) )
3258  {
3259    for( UInt mergeCand = 0; mergeCand < numValidMergeCand; ++mergeCand )
3260    {
3261      if ( interDirNeighbours[mergeCand] == 3 )
3262      {
3263        interDirNeighbours[mergeCand] = 1;
3264        mvFieldNeighbours[(mergeCand << 1) + 1].setMvField(TComMv(0,0), -1);
3265      }
3266    }
3267  }
3268}
3269
3270/** search of the best candidate for inter prediction
3271 * \param pcCU
3272 * \param pcOrgYuv
3273 * \param rpcPredYuv
3274 * \param rpcResiYuv
3275 * \param rpcRecoYuv
3276 * \param bUseRes
3277 * \returns Void
3278 */
3279#if AMP_MRG
3280Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes, Bool bUseMRG )
3281#else
3282Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes )
3283#endif
3284{
3285  m_acYuvPred[0].clear();
3286  m_acYuvPred[1].clear();
3287  m_cYuvPredTemp.clear();
3288  rpcPredYuv->clear();
3289 
3290  if ( !bUseRes )
3291  {
3292    rpcResiYuv->clear();
3293  }
3294 
3295  rpcRecoYuv->clear();
3296 
3297  TComMv        cMvSrchRngLT;
3298  TComMv        cMvSrchRngRB;
3299 
3300  TComMv        cMvZero;
3301  TComMv        TempMv; //kolya
3302 
3303  TComMv        cMv[2];
3304  TComMv        cMvBi[2];
3305  TComMv        cMvTemp[2][33];
3306 
3307  Int           iNumPart    = pcCU->getNumPartInter();
3308  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
3309 
3310  TComMv        cMvPred[2][33];
3311 
3312  TComMv        cMvPredBi[2][33];
3313  Int           aaiMvpIdxBi[2][33];
3314 
3315  Int           aaiMvpIdx[2][33];
3316  Int           aaiMvpNum[2][33];
3317 
3318  AMVPInfo aacAMVPInfo[2][33];
3319 
3320  Int           iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
3321  Int           iRefIdxBi[2];
3322 
3323  UInt          uiPartAddr;
3324  Int           iRoiWidth, iRoiHeight;
3325 
3326  UInt          uiMbBits[3] = {1, 1, 0};
3327 
3328  UInt          uiLastMode = 0;
3329  Int           iRefStart, iRefEnd;
3330 
3331  PartSize      ePartSize = pcCU->getPartitionSize( 0 );
3332
3333  Int           bestBiPRefIdxL1 = 0;
3334  Int           bestBiPMvpL1 = 0;
3335  UInt          biPDistTemp = MAX_INT;
3336
3337#if ZERO_MVD_EST
3338  Int           aiZeroMvdMvpIdx[2] = {-1, -1};
3339  Int           aiZeroMvdRefIdx[2] = {0, 0};
3340  Int           iZeroMvdDir = -1;
3341#endif
3342
3343#if H_3D_IV_MERGE
3344  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS_MEM << 1]; // double length for mv of both lists
3345  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS_MEM];
3346#else
3347  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
3348  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
3349#endif
3350  Int numValidMergeCand = 0 ;
3351
3352  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3353  {
3354    UInt          uiCost[2] = { MAX_UINT, MAX_UINT };
3355    UInt          uiCostBi  =   MAX_UINT;
3356    UInt          uiCostTemp;
3357   
3358    UInt          uiBits[3];
3359    UInt          uiBitsTemp;
3360#if ZERO_MVD_EST
3361    UInt          uiZeroMvdCost = MAX_UINT;
3362    UInt          uiZeroMvdCostTemp;
3363    UInt          uiZeroMvdBitsTemp;
3364    UInt          uiZeroMvdDistTemp = MAX_UINT;
3365    UInt          auiZeroMvdBits[3];
3366#endif
3367    UInt          bestBiPDist = MAX_INT;
3368
3369    UInt          uiCostTempL0[MAX_NUM_REF];
3370    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) uiCostTempL0[iNumRef] = MAX_UINT;
3371    UInt          uiBitsTempL0[MAX_NUM_REF];
3372
3373#if L0034_COMBINED_LIST_CLEANUP
3374    TComMv        mvValidList1;
3375    Int           refIdxValidList1 = 0;
3376    UInt          bitsValidList1 = MAX_UINT;
3377    UInt          costValidList1 = MAX_UINT;
3378#endif
3379
3380    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
3381   
3382    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3383
3384#if H_3D_VSP
3385    pcCU->setVSPFlagSubParts( 0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr) );
3386#endif
3387   
3388#if AMP_MRG
3389    Bool bTestNormalMC = true;
3390   
3391    if ( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 )
3392    {
3393      bTestNormalMC = false;
3394    }
3395   
3396    if (bTestNormalMC)
3397    {
3398#endif
3399
3400    //  Uni-directional prediction
3401    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
3402    {
3403      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3404     
3405      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
3406      {
3407        uiBitsTemp = uiMbBits[iRefList];
3408        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3409        {
3410          uiBitsTemp += iRefIdxTemp+1;
3411          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3412        }
3413#if ZERO_MVD_EST
3414        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp, &uiZeroMvdDistTemp);
3415#else
3416        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
3417#endif
3418        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
3419        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
3420       
3421        if(pcCU->getSlice()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
3422        {
3423          bestBiPDist = biPDistTemp;
3424          bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
3425          bestBiPRefIdxL1 = iRefIdxTemp;
3426        }
3427
3428        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3429#if ZERO_MVD_EST
3430#if L0034_COMBINED_LIST_CLEANUP
3431        if ( iRefList == 0 || pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
3432#else
3433        if ((iRefList != 1 || !pcCU->getSlice()->getNoBackPredFlag()) &&
3434            (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) <= 0 || pcCU->getSlice()->getRefIdxOfLC(eRefPicList, iRefIdxTemp)>=0))
3435#endif
3436        {
3437          uiZeroMvdBitsTemp = uiBitsTemp;
3438          uiZeroMvdBitsTemp += 2; //zero mvd bits
3439
3440          m_pcRdCost->getMotionCost( 1, 0 );
3441          uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost(uiZeroMvdBitsTemp);
3442
3443          if (uiZeroMvdCostTemp < uiZeroMvdCost)
3444          {
3445            uiZeroMvdCost = uiZeroMvdCostTemp;
3446            iZeroMvdDir = iRefList + 1;
3447            aiZeroMvdRefIdx[iRefList] = iRefIdxTemp;
3448            aiZeroMvdMvpIdx[iRefList] = aaiMvpIdx[iRefList][iRefIdxTemp];
3449            auiZeroMvdBits[iRefList] = uiZeroMvdBitsTemp;
3450          }         
3451        }
3452#endif
3453       
3454#if GPB_SIMPLE_UNI
3455#if L0034_COMBINED_LIST_CLEANUP
3456        if ( iRefList == 1 )    // list 1
3457        {
3458          if ( pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 )
3459          {
3460            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3461            uiCostTemp = uiCostTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3462            /*first subtract the bit-rate part of the cost of the other list*/
3463            uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )] );
3464            /*correct the bit-rate part of the current ref*/
3465            m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
3466            uiBitsTemp += m_pcRdCost->getBits( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
3467            /*calculate the correct cost*/
3468            uiCostTemp += m_pcRdCost->getCost( uiBitsTemp );
3469          }
3470          else
3471          {
3472            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3473          }
3474        }
3475        else
3476        {
3477          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3478        }
3479#else
3480        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0)
3481        {
3482          if ( iRefList && ( pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag() && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)>=0 ) ) )
3483            {
3484              if ( pcCU->getSlice()->getNoBackPredFlag() )
3485              {
3486                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3487                uiCostTemp = uiCostTempL0[iRefIdxTemp];
3488                /*first subtract the bit-rate part of the cost of the other list*/
3489                uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[iRefIdxTemp] );
3490              }
3491              else
3492              {
3493                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)]; 
3494                uiCostTemp = uiCostTempL0[pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
3495                /*first subtract the bit-rate part of the cost of the other list*/
3496                uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)] );
3497              }
3498              /*correct the bit-rate part of the current ref*/
3499              m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
3500              uiBitsTemp += m_pcRdCost->getBits( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
3501              /*calculate the correct cost*/
3502              uiCostTemp += m_pcRdCost->getCost( uiBitsTemp );
3503            }
3504            else
3505            {
3506              xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3507            }
3508        }
3509        else
3510        {
3511          if (iRefList && pcCU->getSlice()->getNoBackPredFlag())
3512          {
3513            uiCostTemp = MAX_UINT;
3514            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
3515          }
3516          else
3517          { 
3518            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3519          }       
3520        }
3521#endif
3522#else
3523        xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3524#endif
3525        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
3526        xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3527
3528#if L0034_COMBINED_LIST_CLEANUP
3529        if ( iRefList == 0 )
3530        {
3531          uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3532          uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
3533        }
3534        if ( uiCostTemp < uiCost[iRefList] )
3535        {
3536          uiCost[iRefList] = uiCostTemp;
3537          uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3538
3539          // set motion
3540          cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3541          iRefIdx[iRefList] = iRefIdxTemp;
3542        }
3543
3544        if ( iRefList == 1 && uiCostTemp < costValidList1 && pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
3545        {
3546          costValidList1 = uiCostTemp;
3547          bitsValidList1 = uiBitsTemp;
3548
3549          // set motion
3550          mvValidList1     = cMvTemp[iRefList][iRefIdxTemp];
3551          refIdxValidList1 = iRefIdxTemp;
3552        }
3553#else
3554        if(pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
3555        {
3556          if(iRefList==REF_PIC_LIST_0)
3557          {
3558            uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3559            uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
3560            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_0, iRefIdxTemp)<0)
3561            {
3562              uiCostTemp = MAX_UINT;
3563            }
3564          }
3565          else
3566          {
3567            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_1, iRefIdxTemp)<0)
3568            {
3569              uiCostTemp = MAX_UINT;
3570            }           
3571          }
3572        }
3573
3574        if ( ( iRefList == 0 && uiCostTemp < uiCost[iRefList] ) ||
3575            ( iRefList == 1 &&  pcCU->getSlice()->getNoBackPredFlag() && iRefIdxTemp == iRefIdx[0] ) ||
3576            ( iRefList == 1 && (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0) && (iRefIdxTemp==0 || iRefIdxTemp == iRefIdx[0]) && !pcCU->getSlice()->getNoBackPredFlag() && (iRefIdxTemp == pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)) ) ||
3577            ( iRefList == 1 && !pcCU->getSlice()->getNoBackPredFlag() && uiCostTemp < uiCost[iRefList] ) )
3578          {
3579            uiCost[iRefList] = uiCostTemp;
3580            uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3581           
3582            // set motion
3583            cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3584            iRefIdx[iRefList] = iRefIdxTemp;
3585            pcCU->getCUMvField(eRefPicList)->setAllMv( cMv[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3586            pcCU->getCUMvField(eRefPicList)->setAllRefIdx( iRefIdx[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3587
3588            if(!pcCU->getSlice()->getMvdL1ZeroFlag())
3589            {
3590              // storing list 1 prediction signal for iterative bi-directional prediction
3591              if ( eRefPicList == REF_PIC_LIST_1 )
3592              {
3593                TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3594                motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3595              }
3596              if ( (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) && eRefPicList == REF_PIC_LIST_0 )
3597              {
3598                TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
3599                motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3600              }
3601            }
3602          }
3603#endif
3604      }
3605    }
3606    //  Bi-directional prediction
3607    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
3608    {
3609     
3610      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
3611      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
3612     
3613      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
3614      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
3615     
3616      UInt uiMotBits[2];
3617
3618      if(pcCU->getSlice()->getMvdL1ZeroFlag())
3619      {
3620        xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3621        pcCU->setMVPIdxSubParts( bestBiPMvpL1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3622        aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1;
3623        cMvPredBi[1][bestBiPRefIdxL1]   = pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()->m_acMvCand[bestBiPMvpL1];
3624
3625        cMvBi[1] = cMvPredBi[1][bestBiPRefIdxL1];
3626        iRefIdxBi[1] = bestBiPRefIdxL1;
3627        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3628        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3629        TComYuv* pcYuvPred = &m_acYuvPred[1];
3630        motionCompensation( pcCU, pcYuvPred, REF_PIC_LIST_1, iPartIdx );
3631
3632        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3633        uiMotBits[1] = uiMbBits[1];
3634
3635        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3636        {
3637          uiMotBits[1] += bestBiPRefIdxL1+1;
3638          if ( bestBiPRefIdxL1 == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiMotBits[1]--;
3639        }
3640
3641        uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS];
3642
3643        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3644
3645        cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1];
3646      }
3647      else
3648      {
3649        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3650        uiMotBits[1] = uiBits[1] - uiMbBits[1];
3651        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3652      }
3653
3654      // 4-times iteration (default)
3655      Int iNumIter = 4;
3656     
3657      // fast encoder setting: only one iteration
3658      if ( m_pcEncCfg->getUseFastEnc() || pcCU->getSlice()->getMvdL1ZeroFlag())
3659      {
3660        iNumIter = 1;
3661      }
3662     
3663      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3664      {
3665       
3666        Int         iRefList    = iIter % 2;
3667#if L0034_COMBINED_LIST_CLEANUP
3668        if ( m_pcEncCfg->getUseFastEnc() )
3669        {
3670          if( uiCost[0] <= uiCost[1] )
3671          {
3672            iRefList = 1;
3673          }
3674          else
3675          {
3676            iRefList = 0;
3677          }
3678        }
3679        else if ( iIter == 0 )
3680        {
3681          iRefList = 0;
3682        }
3683        if ( iIter == 0 && !pcCU->getSlice()->getMvdL1ZeroFlag())
3684        {
3685          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllMv( cMv[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3686          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllRefIdx( iRefIdx[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3687          TComYuv*  pcYuvPred = &m_acYuvPred[1-iRefList];
3688          motionCompensation ( pcCU, pcYuvPred, RefPicList(1-iRefList), iPartIdx );
3689        }
3690#else
3691        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3692        {
3693          iRefList = 1;
3694        }
3695#endif
3696        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3697
3698        if(pcCU->getSlice()->getMvdL1ZeroFlag())
3699        {
3700          iRefList = 0;
3701          eRefPicList = REF_PIC_LIST_0;
3702        }
3703
3704        Bool bChanged = false;
3705       
3706        iRefStart = 0;
3707        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3708       
3709        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3710        {
3711          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3712          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3713          {
3714            uiBitsTemp += iRefIdxTemp+1;
3715            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3716          }
3717          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3718          // call ME
3719          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3720          xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3721          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3722
3723          if ( uiCostTemp < uiCostBi )
3724          {
3725            bChanged = true;
3726           
3727            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3728            iRefIdxBi[iRefList] = iRefIdxTemp;
3729           
3730            uiCostBi            = uiCostTemp;
3731            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3732            uiBits[2]           = uiBitsTemp;
3733           
3734            if(iNumIter!=1)
3735            {
3736              //  Set motion
3737              pcCU->getCUMvField( eRefPicList )->setAllMv( cMvBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3738              pcCU->getCUMvField( eRefPicList )->setAllRefIdx( iRefIdxBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3739
3740              TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3741              motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3742            }
3743          }
3744        } // for loop-iRefIdxTemp
3745       
3746        if ( !bChanged )
3747        {
3748          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] )
3749          {
3750            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3751            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3752            if(!pcCU->getSlice()->getMvdL1ZeroFlag())
3753            {
3754              xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3755              xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3756            }
3757          }
3758          break;
3759        }
3760      } // for loop-iter
3761    } // if (B_SLICE)
3762#if ZERO_MVD_EST
3763    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
3764    {
3765      m_pcRdCost->getMotionCost( 1, 0 );
3766
3767      for ( Int iL0RefIdxTemp = 0; iL0RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1; iL0RefIdxTemp++ )
3768      for ( Int iL1RefIdxTemp = 0; iL1RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1; iL1RefIdxTemp++ )
3769      {
3770        UInt uiRefIdxBitsTemp = 0;
3771        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 1 )
3772        {
3773          uiRefIdxBitsTemp += iL0RefIdxTemp+1;
3774          if ( iL0RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1 ) uiRefIdxBitsTemp--;
3775        }
3776        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3777        {
3778          uiRefIdxBitsTemp += iL1RefIdxTemp+1;
3779          if ( iL1RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiRefIdxBitsTemp--;
3780        }
3781
3782        Int iL0MVPIdx = 0;
3783        Int iL1MVPIdx = 0;
3784
3785        for (iL0MVPIdx = 0; iL0MVPIdx < aaiMvpNum[0][iL0RefIdxTemp]; iL0MVPIdx++)
3786        {
3787          for (iL1MVPIdx = 0; iL1MVPIdx < aaiMvpNum[1][iL1RefIdxTemp]; iL1MVPIdx++)
3788          {
3789            uiZeroMvdBitsTemp = uiRefIdxBitsTemp;
3790            uiZeroMvdBitsTemp += uiMbBits[2];
3791            uiZeroMvdBitsTemp += m_auiMVPIdxCost[iL0MVPIdx][aaiMvpNum[0][iL0RefIdxTemp]] + m_auiMVPIdxCost[iL1MVPIdx][aaiMvpNum[1][iL1RefIdxTemp]];
3792            uiZeroMvdBitsTemp += 4; //zero mvd for both directions
3793            pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( aacAMVPInfo[0][iL0RefIdxTemp].m_acMvCand[iL0MVPIdx], iL0RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3794            pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( aacAMVPInfo[1][iL1RefIdxTemp].m_acMvCand[iL1MVPIdx], iL1RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3795 
3796            xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiZeroMvdDistTemp, m_pcEncCfg->getUseHADME() );
3797            uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost( uiZeroMvdBitsTemp );
3798            if (uiZeroMvdCostTemp < uiZeroMvdCost)
3799            {
3800              uiZeroMvdCost = uiZeroMvdCostTemp;
3801              iZeroMvdDir = 3;
3802              aiZeroMvdMvpIdx[0] = iL0MVPIdx;
3803              aiZeroMvdMvpIdx[1] = iL1MVPIdx;
3804              aiZeroMvdRefIdx[0] = iL0RefIdxTemp;
3805              aiZeroMvdRefIdx[1] = iL1RefIdxTemp;
3806              auiZeroMvdBits[2] = uiZeroMvdBitsTemp;
3807            }
3808          }
3809        }
3810      }
3811    }
3812#endif
3813
3814#if AMP_MRG
3815    } //end if bTestNormalMC
3816#endif
3817    //  Clear Motion Field
3818    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3819    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3820    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3821    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3822
3823    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3824    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3825    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3826    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3827   
3828    UInt uiMEBits = 0;
3829    // Set Motion Field_
3830#if L0034_COMBINED_LIST_CLEANUP
3831    cMv[1] = mvValidList1;
3832    iRefIdx[1] = refIdxValidList1;
3833    uiBits[1] = bitsValidList1;
3834    uiCost[1] = costValidList1;
3835#else
3836    if ( pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 ) )
3837    {
3838      uiCost[1] = MAX_UINT;
3839    }
3840#endif
3841#if AMP_MRG
3842    if (bTestNormalMC)
3843    {
3844#endif
3845#if ZERO_MVD_EST
3846    if (uiZeroMvdCost <= uiCostBi && uiZeroMvdCost <= uiCost[0] && uiZeroMvdCost <= uiCost[1])
3847    {
3848      if (iZeroMvdDir == 3)
3849      {
3850        uiLastMode = 2;
3851
3852        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3853        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3854 
3855        pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3856       
3857        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3858        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3859        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3860        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3861        uiMEBits = auiZeroMvdBits[2];
3862      }
3863      else if (iZeroMvdDir == 1)
3864      {       
3865        uiLastMode = 0;
3866
3867        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3868
3869        pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3870       
3871        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3872        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3873        uiMEBits = auiZeroMvdBits[0];
3874      }
3875      else if (iZeroMvdDir == 2)
3876      {
3877        uiLastMode = 1;
3878
3879        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3880
3881        pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3882       
3883        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3884        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3885        uiMEBits = auiZeroMvdBits[1];
3886      }
3887      else
3888      {
3889        assert(0);
3890      }
3891    }
3892    else
3893#endif
3894    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3895    {
3896      uiLastMode = 2;
3897      {
3898            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMvBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3899            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdxBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3900            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3901            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3902      }
3903      {
3904        TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3905            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3906      }
3907      {
3908        TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3909            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3910      }
3911     
3912      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3913     
3914      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3915      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3916      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3917      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3918
3919      uiMEBits = uiBits[2];
3920    }
3921    else if ( uiCost[0] <= uiCost[1] )
3922    {
3923      uiLastMode = 0;
3924          pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
3925          pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
3926      {
3927        TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3928            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3929      }
3930      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3931     
3932      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3933      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3934
3935      uiMEBits = uiBits[0];
3936    }
3937    else
3938    {
3939      uiLastMode = 1;
3940          pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
3941          pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
3942      {
3943        TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3944            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3945      }
3946      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3947     
3948      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3949      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3950
3951      uiMEBits = uiBits[1];
3952    }
3953#if AMP_MRG
3954    } // end if bTestNormalMC
3955#endif
3956
3957    if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3958    {
3959      UInt uiMRGInterDir = 0;     
3960      TComMvField cMRGMvField[2];
3961      UInt uiMRGIndex = 0;
3962
3963      UInt uiMEInterDir = 0;
3964      TComMvField cMEMvField[2];
3965
3966      m_pcRdCost->getMotionCost( 1, 0 );
3967#if AMP_MRG
3968      // calculate ME cost
3969      UInt uiMEError = MAX_UINT;
3970      UInt uiMECost = MAX_UINT;
3971
3972      if (bTestNormalMC)
3973      {
3974        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3975        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3976      }
3977#else
3978      // calculate ME cost
3979      UInt uiMEError = MAX_UINT;
3980      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3981      UInt uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3982#endif
3983      // save ME result.
3984      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3985      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3986      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3987
3988      // find Merge result
3989      UInt uiMRGCost = MAX_UINT;
3990#if H_3D_VSP
3991      Int vspFlag[MRG_MAX_NUM_CANDS_MEM];
3992      memset(vspFlag, 0, sizeof(Int)*MRG_MAX_NUM_CANDS_MEM);
3993#endif
3994
3995      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours
3996#if H_3D_VSP
3997                      , vspFlag
3998#endif
3999                      , numValidMergeCand
4000                      );
4001      if ( uiMRGCost < uiMECost )
4002      {
4003        // set Merge result
4004        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
4005        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
4006#if H_3D_VSP
4007        pcCU->setVSPFlagSubParts( vspFlag[uiMRGIndex], uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
4008#endif
4009        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
4010        {
4011          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
4012          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
4013        }
4014
4015        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
4016        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
4017
4018        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
4019        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
4020        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
4021        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
4022      }
4023      else
4024      {
4025        // set ME result
4026        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
4027        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
4028#if H_3D_VSP
4029        pcCU->setVSPFlagSubParts ( 0,             uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
4030#endif
4031        {
4032          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
4033          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
4034        }
4035      }
4036    }
4037
4038    //  MC
4039    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
4040   
4041  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
4042
4043  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
4044
4045  return;
4046}
4047
4048// AMVP
4049#if ZERO_MVD_EST
4050Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDistBiP, UInt* puiDist  )
4051#else
4052Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDistBiP )
4053#endif
4054{
4055  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
4056 
4057  TComMv  cBestMv;
4058  Int     iBestIdx = 0;
4059  TComMv  cZeroMv;
4060  TComMv  cMvPred;
4061  UInt    uiBestCost = MAX_INT;
4062  UInt    uiPartAddr = 0;
4063  Int     iRoiWidth, iRoiHeight;
4064  Int     i;
4065 
4066  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
4067  // Fill the MV Candidates
4068  if (!bFilled)
4069  {
4070    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
4071  }
4072 
4073  // initialize Mvp index & Mvp
4074  iBestIdx = 0;
4075  cBestMv  = pcAMVPInfo->m_acMvCand[0];
4076#if !ZERO_MVD_EST
4077  if (pcAMVPInfo->iN <= 1)
4078  {
4079    rcMvPred = cBestMv;
4080   
4081    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
4082    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
4083
4084    if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefPicList==REF_PIC_LIST_1)
4085    {
4086#if ZERO_MVD_EST
4087      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
4088#else
4089      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
4090#endif
4091    }
4092    return;
4093  }
4094#endif 
4095  if (bFilled)
4096  {
4097    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
4098    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
4099    return;
4100  }
4101 
4102  m_cYuvPredTemp.clear();
4103#if ZERO_MVD_EST
4104  UInt uiDist;
4105#endif
4106  //-- Check Minimum Cost.
4107  for ( i = 0 ; i < pcAMVPInfo->iN; i++)
4108  {
4109    UInt uiTmpCost;
4110#if ZERO_MVD_EST
4111    uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
4112#else
4113    uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
4114#endif     
4115    if ( uiBestCost > uiTmpCost )
4116    {
4117      uiBestCost = uiTmpCost;
4118      cBestMv   = pcAMVPInfo->m_acMvCand[i];
4119      iBestIdx  = i;
4120      (*puiDistBiP) = uiTmpCost;
4121#if ZERO_MVD_EST
4122      (*puiDist) = uiDist;
4123#endif
4124    }
4125  }
4126
4127  m_cYuvPredTemp.clear();
4128 
4129  // Setting Best MVP
4130  rcMvPred = cBestMv;
4131  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
4132  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
4133  return;
4134}
4135
4136UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
4137{
4138  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
4139 
4140  if (iNum == 1)
4141    return 0;
4142 
4143  UInt uiLength = 1;
4144  Int iTemp = iIdx;
4145  if ( iTemp == 0 )
4146  {
4147    return uiLength;
4148  }
4149 
4150  Bool bCodeLast = ( iNum-1 > iTemp );
4151 
4152  uiLength += (iTemp-1);
4153 
4154  if( bCodeLast )
4155  {
4156    uiLength++;
4157  }
4158 
4159  return uiLength;
4160}
4161
4162Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
4163{
4164  if ( eCUMode == SIZE_2Nx2N )
4165  {
4166    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
4167    uiBlkBit[1] = 3;
4168    uiBlkBit[2] = 5;
4169  }
4170  else if ( (eCUMode == SIZE_2NxN || eCUMode == SIZE_2NxnU) || eCUMode == SIZE_2NxnD )
4171  {
4172    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} } };
4173    if ( bPSlice )
4174    {
4175      uiBlkBit[0] = 3;
4176      uiBlkBit[1] = 0;
4177      uiBlkBit[2] = 0;
4178    }
4179    else
4180    {
4181      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
4182    }
4183  }
4184  else if ( (eCUMode == SIZE_Nx2N || eCUMode == SIZE_nLx2N) || eCUMode == SIZE_nRx2N )
4185  {
4186    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} } };
4187    if ( bPSlice )
4188    {
4189      uiBlkBit[0] = 3;
4190      uiBlkBit[1] = 0;
4191      uiBlkBit[2] = 0;
4192    }
4193    else
4194    {
4195      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
4196    }
4197  }
4198  else if ( eCUMode == SIZE_NxN )
4199  {
4200    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
4201    uiBlkBit[1] = 3;
4202    uiBlkBit[2] = 5;
4203  }
4204  else
4205  {
4206    printf("Wrong!\n");
4207    assert( 0 );
4208  }
4209}
4210
4211Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
4212{
4213  pDst->iN = pSrc->iN;
4214  for (Int i = 0; i < pSrc->iN; i++)
4215  {
4216    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
4217  }
4218}
4219
4220Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, UInt& ruiCost )
4221{
4222  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
4223 
4224  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
4225 
4226  if (pcAMVPInfo->iN < 2) return;
4227 
4228  m_pcRdCost->getMotionCost( 1, 0 );
4229  m_pcRdCost->setCostScale ( 0    );
4230 
4231  Int iBestMVPIdx = riMVPIdx;
4232 
4233  m_pcRdCost->setPredictor( rcMvPred );
4234  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
4235  iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
4236  Int iBestMvBits = iOrgMvBits;
4237 
4238  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
4239  {
4240    if (iMVPIdx == riMVPIdx) continue;
4241   
4242    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
4243   
4244    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
4245    iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
4246   
4247    if (iMvBits < iBestMvBits)
4248    {
4249      iBestMvBits = iMvBits;
4250      iBestMVPIdx = iMVPIdx;
4251    }
4252  }
4253 
4254  if (iBestMVPIdx != riMVPIdx)  //if changed
4255  {
4256    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
4257   
4258    riMVPIdx = iBestMVPIdx;
4259    UInt uiOrgBits = ruiBits;
4260    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
4261    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
4262  }
4263}
4264
4265UInt TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
4266                                  UInt        uiPartIdx,
4267                                  UInt      uiPartAddr,
4268                                  TComYuv*    pcOrgYuv,
4269                                  TComYuv*    pcTemplateCand,
4270                                  TComMv      cMvCand,
4271                                  Int         iMVPIdx,
4272                                  Int     iMVPNum,
4273                                  RefPicList  eRefPicList,
4274                                  Int         iRefIdx,
4275                                  Int         iSizeX,
4276                                  Int         iSizeY
4277                               #if ZERO_MVD_EST
4278                                , UInt&       ruiDist
4279                               #endif
4280                                  )
4281{
4282  UInt uiCost  = MAX_INT;
4283 
4284  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
4285 
4286  pcCU->clipMv( cMvCand );
4287
4288#if H_3D_IC
4289  Bool bICFlag = pcCU->getICFlag( uiPartAddr ) && ( pcCU->getSlice()->getViewIndex() != pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getViewIndex() );
4290#endif
4291
4292  // prediction pattern
4293  if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType()==P_SLICE )
4294  {
4295    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, true );
4296  }
4297  else
4298  {
4299    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false
4300#if H_3D_ARP
4301      , false
4302#endif
4303#if H_3D_IC
4304    , bICFlag
4305#endif
4306      );
4307  }
4308
4309  if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType()==P_SLICE )
4310  {
4311    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, iRefIdx );
4312  }
4313
4314  // calc distortion
4315#if ZERO_MVD_EST
4316  m_pcRdCost->getMotionCost( 1, 0 );
4317  DistParam cDistParam;
4318  m_pcRdCost->setDistParam( cDistParam, g_bitDepthY,
4319                            pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), 
4320                            pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), 
4321#if NS_HAD
4322                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME(), m_pcEncCfg->getUseNSQT() );
4323#else
4324                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME() );
4325#endif
4326  ruiDist = cDistParam.DistFunc( &cDistParam );
4327  uiCost = ruiDist + m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] );
4328#else
4329#if WEIGHTED_CHROMA_DISTORTION
4330  uiCost = m_pcRdCost->getDistPart(g_bitDepthY, pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, TEXT_LUMA, DF_SAD );
4331#else
4332  uiCost = m_pcRdCost->getDistPart(g_bitDepthY, pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, DF_SAD );
4333#endif
4334  uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
4335#endif
4336  return uiCost;
4337}
4338
4339Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, UInt& ruiCost, Bool bBi  )
4340{
4341  UInt          uiPartAddr;
4342  Int           iRoiWidth;
4343  Int           iRoiHeight;
4344 
4345  TComMv        cMvHalf, cMvQter;
4346  TComMv        cMvSrchRngLT;
4347  TComMv        cMvSrchRngRB;
4348 
4349  TComYuv*      pcYuv = pcYuvOrg;
4350  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
4351 
4352  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
4353  TComPattern*  pcPatternKey  = pcCU->getPattern        ();
4354 
4355  Double        fWeight       = 1.0;
4356 
4357  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
4358 
4359#if H_3D_IC
4360  Bool bICFlag = pcCU->getICFlag( uiPartAddr ) && ( pcCU->getSlice()->getViewIndex() != pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getViewIndex() );
4361  pcPatternKey->setICFlag( bICFlag );
4362#endif
4363
4364  if ( bBi )
4365  {
4366    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
4367    pcYuv                = &m_cYuvPredTemp;
4368   
4369    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
4370   
4371    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight );
4372   
4373    fWeight = 0.5;
4374  }
4375 
4376  //  Search key pattern initialization
4377  pcPatternKey->initPattern( pcYuv->getLumaAddr( uiPartAddr ),
4378                            pcYuv->getCbAddr  ( uiPartAddr ),
4379                            pcYuv->getCrAddr  ( uiPartAddr ),
4380                            iRoiWidth,
4381                            iRoiHeight,
4382                            pcYuv->getStride(),
4383                            0, 0 );
4384 
4385  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr );
4386  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride();
4387 
4388  TComMv      cMvPred = *pcMvPred;
4389 
4390  if ( bBi )  xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4391  else        xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4392 
4393  m_pcRdCost->getMotionCost ( 1, 0 );
4394 
4395  m_pcRdCost->setPredictor  ( *pcMvPred );
4396#if H_3D_IC
4397  if( pcCU->getSlice()->getIsDepth() )
4398    m_pcRdCost->setCostScale  ( 0 );
4399  else
4400#endif
4401  m_pcRdCost->setCostScale  ( 2 );
4402
4403  setWpScalingDistParam( pcCU, iRefIdxPred, eRefPicList );
4404  //  Do integer search
4405  if ( !m_iFastSearch || bBi )
4406  {
4407    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4408  }
4409  else
4410  {
4411    rcMv = *pcMvPred;
4412    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4413  }
4414 
4415  m_pcRdCost->getMotionCost( 1, 0 );
4416#if H_3D_IC
4417  if( ! pcCU->getSlice()->getIsDepth() )
4418  {
4419#endif
4420  m_pcRdCost->setCostScale ( 1 );
4421 
4422  {
4423    xPatternSearchFracDIF( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost
4424                          ,bBi
4425                          );
4426  }
4427 
4428 
4429 
4430  m_pcRdCost->setCostScale( 0 );
4431  rcMv <<= 2;
4432  rcMv += (cMvHalf <<= 1);
4433  rcMv +=  cMvQter;
4434#if H_3D_IC
4435  }
4436#endif
4437 
4438  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
4439#if H_3D_IC
4440  if( pcCU->getSlice()->getIsDepth() )
4441    ruiCost += m_pcRdCost->getCost( uiMvBits );
4442#endif
4443  ruiBits      += uiMvBits;
4444  ruiCost       = (UInt)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
4445}
4446
4447
4448Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
4449{
4450  Int  iMvShift = 2;
4451#if H_3D_IC
4452  if( pcCU->getSlice()->getIsDepth() )
4453    iMvShift = 0;
4454#endif
4455  TComMv cTmpMvPred = cMvPred;
4456  pcCU->clipMv( cTmpMvPred );
4457
4458  rcMvSrchRngLT.setHor( cTmpMvPred.getHor() - (iSrchRng << iMvShift) );
4459  rcMvSrchRngLT.setVer( cTmpMvPred.getVer() - (iSrchRng << iMvShift) );
4460 
4461  rcMvSrchRngRB.setHor( cTmpMvPred.getHor() + (iSrchRng << iMvShift) );
4462  rcMvSrchRngRB.setVer( cTmpMvPred.getVer() + (iSrchRng << iMvShift) );
4463  pcCU->clipMv        ( rcMvSrchRngLT );
4464  pcCU->clipMv        ( rcMvSrchRngRB );
4465 
4466  rcMvSrchRngLT >>= iMvShift;
4467  rcMvSrchRngRB >>= iMvShift;
4468}
4469
4470Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4471{
4472  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4473  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4474  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4475  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4476 
4477  UInt  uiSad;
4478  UInt  uiSadBest         = MAX_UINT;
4479  Int   iBestX = 0;
4480  Int   iBestY = 0;
4481 
4482  Pel*  piRefSrch;
4483 
4484  //-- jclee for using the SAD function pointer
4485  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
4486 
4487  // fast encoder decision: use subsampled SAD for integer ME
4488  if ( m_pcEncCfg->getUseFastEnc() )
4489  {
4490    if ( m_cDistParam.iRows > 8 )
4491    {
4492      m_cDistParam.iSubShift = 1;
4493    }
4494  }
4495 
4496  piRefY += (iSrchRngVerTop * iRefStride);
4497  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4498  {
4499    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4500    {
4501      //  find min. distortion position
4502      piRefSrch = piRefY + x;
4503      m_cDistParam.pCur = piRefSrch;
4504
4505      setDistParamComp(0);
4506#if H_3D_IC
4507      m_cDistParam.bUseIC = pcPatternKey->getICFlag();
4508#endif
4509      m_cDistParam.bitDepth = g_bitDepthY;
4510      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
4511     
4512      // motion cost
4513      uiSad += m_pcRdCost->getCost( x, y );
4514     
4515      if ( uiSad < uiSadBest )
4516      {
4517        uiSadBest = uiSad;
4518        iBestX    = x;
4519        iBestY    = y;
4520      }
4521    }
4522    piRefY += iRefStride;
4523  }
4524 
4525  rcMv.set( iBestX, iBestY );
4526 
4527  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4528  return;
4529}
4530
4531Void TEncSearch::xPatternSearchFast( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4532{
4533  pcCU->getMvPredLeft       ( m_acMvPredictors[0] );
4534  pcCU->getMvPredAbove      ( m_acMvPredictors[1] );
4535  pcCU->getMvPredAboveRight ( m_acMvPredictors[2] );
4536 
4537  switch ( m_iFastSearch )
4538  {
4539    case 1:
4540      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD );
4541      break;
4542     
4543    default:
4544      break;
4545  }
4546}
4547
4548Void TEncSearch::xTZSearch( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4549{
4550  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4551  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4552  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4553  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4554 
4555  TZ_SEARCH_CONFIGURATION
4556 
4557  UInt uiSearchRange = m_iSearchRange;
4558  pcCU->clipMv( rcMv );
4559#if H_3D_IC
4560  if( ! pcCU->getSlice()->getIsDepth() )
4561#endif
4562  rcMv >>= 2;
4563  // init TZSearchStruct
4564  IntTZSearchStruct cStruct;
4565  cStruct.iYStride    = iRefStride;
4566  cStruct.piRefY      = piRefY;
4567  cStruct.uiBestSad   = MAX_UINT;
4568 
4569  // set rcMv (Median predictor) as start point and as best point
4570  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4571 
4572  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4573  if ( bTestOtherPredictedMV )
4574  {
4575    for ( UInt index = 0; index < 3; index++ )
4576    {
4577      TComMv cMv = m_acMvPredictors[index];
4578      pcCU->clipMv( cMv );
4579#if H_3D_IC
4580      if( ! pcCU->getSlice()->getIsDepth() )
4581#endif
4582      cMv >>= 2;
4583      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4584    }
4585  }
4586 
4587  // test whether zero Mv is better start point than Median predictor
4588  if ( bTestZeroVector )
4589  {
4590    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4591  }
4592 
4593  // start search
4594  Int  iDist = 0;
4595  Int  iStartX = cStruct.iBestX;
4596  Int  iStartY = cStruct.iBestY;
4597 
4598  // first search
4599  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4600  {
4601    if ( bFirstSearchDiamond == 1 )
4602    {
4603      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4604    }
4605    else
4606    {
4607      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4608    }
4609   
4610    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4611    {
4612      break;
4613    }
4614  }
4615 
4616  // test whether zero Mv is a better start point than Median predictor
4617  if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4618  {
4619    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4620    if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4621    {
4622      // test its neighborhood
4623      for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4624      {
4625        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
4626        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4627        {
4628          break;
4629        }
4630      }
4631    }
4632  }
4633 
4634  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4635  if ( cStruct.uiBestDistance == 1 )
4636  {
4637    cStruct.uiBestDistance = 0;
4638    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4639  }
4640 
4641  // raster search if distance is too big
4642  if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4643  {
4644    cStruct.uiBestDistance = iRaster;
4645    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4646    {
4647      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4648      {
4649        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4650      }
4651    }
4652  }
4653 
4654  // raster refinement
4655  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4656  {
4657    while ( cStruct.uiBestDistance > 0 )
4658    {
4659      iStartX = cStruct.iBestX;
4660      iStartY = cStruct.iBestY;
4661      if ( cStruct.uiBestDistance > 1 )
4662      {
4663        iDist = cStruct.uiBestDistance >>= 1;
4664        if ( bRasterRefinementDiamond == 1 )
4665        {
4666          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4667        }
4668        else
4669        {
4670          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4671        }
4672      }
4673     
4674      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4675      if ( cStruct.uiBestDistance == 1 )
4676      {
4677        cStruct.uiBestDistance = 0;
4678        if ( cStruct.ucPointNr != 0 )
4679        {
4680          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4681        }
4682      }
4683    }
4684  }
4685 
4686  // start refinement
4687  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4688  {
4689    while ( cStruct.uiBestDistance > 0 )
4690    {
4691      iStartX = cStruct.iBestX;
4692      iStartY = cStruct.iBestY;
4693      cStruct.uiBestDistance = 0;
4694      cStruct.ucPointNr = 0;
4695      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4696      {
4697        if ( bStarRefinementDiamond == 1 )
4698        {
4699          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4700        }
4701        else
4702        {
4703          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4704        }
4705        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4706        {
4707          break;
4708        }
4709      }
4710     
4711      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4712      if ( cStruct.uiBestDistance == 1 )
4713      {
4714        cStruct.uiBestDistance = 0;
4715        if ( cStruct.ucPointNr != 0 )
4716        {
4717          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4718        }
4719      }
4720    }
4721  }
4722 
4723  // write out best match
4724  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4725  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4726}
4727
4728Void TEncSearch::xPatternSearchFracDIF(TComDataCU* pcCU,
4729                                       TComPattern* pcPatternKey,
4730                                       Pel* piRefY,
4731                                       Int iRefStride,
4732                                       TComMv* pcMvInt,
4733                                       TComMv& rcMvHalf,
4734                                       TComMv& rcMvQter,
4735                                       UInt& ruiCost
4736                                       ,Bool biPred
4737                                       )
4738{
4739  //  Reference pattern initialization (integer scale)
4740  TComPattern cPatternRoi;
4741  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4742  cPatternRoi.initPattern( piRefY +  iOffset,
4743                          NULL,
4744                          NULL,
4745                          pcPatternKey->getROIYWidth(),
4746                          pcPatternKey->getROIYHeight(),
4747                          iRefStride,
4748                          0, 0 );
4749 
4750  //  Half-pel refinement
4751  xExtDIFUpSamplingH ( &cPatternRoi, biPred );
4752 
4753  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4754  TComMv baseRefMv(0, 0);
4755  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 2, rcMvHalf   );
4756 
4757  m_pcRdCost->setCostScale( 0 );
4758 
4759  xExtDIFUpSamplingQ ( &cPatternRoi, rcMvHalf, biPred );
4760  baseRefMv = rcMvHalf;
4761  baseRefMv <<= 1;
4762 
4763  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4764  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4765  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 1, rcMvQter );
4766}
4767
4768/** encode residual and calculate rate-distortion for a CU block
4769 * \param pcCU
4770 * \param pcYuvOrg
4771 * \param pcYuvPred
4772 * \param rpcYuvResi
4773 * \param rpcYuvResiBest
4774 * \param rpcYuvRec
4775 * \param bSkipRes
4776 * \returns Void
4777 */
4778Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred, TComYuv*& rpcYuvResi, TComYuv*& rpcYuvResiBest, TComYuv*& rpcYuvRec, Bool bSkipRes )
4779{
4780  if ( pcCU->isIntra(0) )
4781  {
4782    return;
4783  }
4784 
4785  Bool      bHighPass    = pcCU->getSlice()->getDepth() ? true : false;
4786  UInt      uiBits       = 0, uiBitsBest = 0;
4787#if H_3D_VSO
4788  Dist      uiDistortion = 0, uiDistortionBest = 0;
4789#else
4790  UInt      uiDistortion = 0, uiDistortionBest = 0;
4791#endif
4792 
4793  UInt      uiWidth      = pcCU->getWidth ( 0 );
4794  UInt      uiHeight     = pcCU->getHeight( 0 );
4795 
4796  //  No residual coding : SKIP mode
4797  if ( bSkipRes )
4798  {
4799    pcCU->setSkipFlagSubParts( true, 0, pcCU->getDepth(0) );
4800
4801    rpcYuvResi->clear();
4802   
4803    pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4804
4805#if H_3D_VSO // M13
4806    if ( m_pcRdCost->getUseVSO() )
4807    {
4808      uiDistortion = m_pcRdCost->getDistPartVSO( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight     , false );
4809    }
4810    else   
4811    {
4812#endif
4813#if WEIGHTED_CHROMA_DISTORTION
4814    uiDistortion = m_pcRdCost->getDistPart(g_bitDepthY, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4815    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, TEXT_CHROMA_U )
4816    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, TEXT_CHROMA_V );
4817#else
4818    uiDistortion = m_pcRdCost->getDistPart(g_bitDepthY, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4819    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4820    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4821#endif
4822
4823#if H_3D_VSO // MIgnore
4824    }
4825#endif
4826
4827    if( m_bUseSBACRD )
4828      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4829   
4830    m_pcEntropyCoder->resetBits();
4831    if (pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
4832    {
4833      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
4834    }
4835    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4836    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, true );
4837#if H_3D_IC
4838    m_pcEntropyCoder->encodeICFlag( pcCU, 0, true );
4839#endif
4840#if H_3D_ARP
4841    m_pcEntropyCoder->encodeARPW( pcCU, 0 );
4842#endif
4843    uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4844    pcCU->getTotalBits()       = uiBits;
4845    pcCU->getTotalDistortion() = uiDistortion;
4846#if H_3D_VSO //M 14
4847    if ( m_pcRdCost->getUseLambdaScaleVSO() )   
4848      pcCU->getTotalCost() = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );   
4849    else
4850#endif   
4851    pcCU->getTotalCost() = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4852
4853    if( m_bUseSBACRD )
4854      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4855   
4856    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4857    pcCU->setTrIdxSubParts( 0, 0, pcCU->getDepth(0) );
4858
4859#if H_3D_VSO // necessary? // M15
4860    // set Model
4861    if( !m_pcRdCost->getUseEstimatedVSD()&& m_pcRdCost->getUseRenModel() )
4862    {
4863      Pel*  piSrc       = rpcYuvRec->getLumaAddr();
4864      UInt  uiSrcStride = rpcYuvRec->getStride();
4865      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4866    }
4867#endif
4868
4869    return;
4870  }
4871 
4872  //  Residual coding.
4873  Int    qp, qpBest = 0, qpMin, qpMax;
4874  Double  dCost, dCostBest = MAX_DOUBLE;
4875 
4876  UInt uiTrLevel = 0;
4877  if( (pcCU->getWidth(0) > pcCU->getSlice()->getSPS()->getMaxTrSize()) )
4878  {
4879    while( pcCU->getWidth(0) > (pcCU->getSlice()->getSPS()->getMaxTrSize()<<uiTrLevel) ) uiTrLevel++;
4880  }
4881  UInt uiMaxTrMode = 1 + uiTrLevel;
4882 
4883  while((uiWidth>>uiMaxTrMode) < (g_uiMaxCUWidth>>g_uiMaxCUDepth)) uiMaxTrMode--;
4884 
4885  qpMin =  bHighPass ? Clip3( -pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, pcCU->getQP(0) - m_iMaxDeltaQP ) : pcCU->getQP( 0 );
4886  qpMax =  bHighPass ? Clip3( -pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, pcCU->getQP(0) + m_iMaxDeltaQP ) : pcCU->getQP( 0 );
4887
4888  rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4889
4890  for ( qp = qpMin; qp <= qpMax; qp++ )
4891  {
4892    dCost = 0.;
4893    uiBits = 0;
4894    uiDistortion = 0;
4895    if( m_bUseSBACRD )
4896    {
4897      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4898    }   
4899
4900#if H_3D_VSO // M16 // M18
4901    Dist uiZeroDistortion = 0;
4902    if ( m_pcRdCost->getUseVSO() )  // This creating and destroying need to be fixed.
4903    {
4904      m_cYuvRecTemp.create( pcYuvPred->getWidth(), pcYuvPred->getHeight()  );
4905    }
4906
4907    xEstimateResidualQT( pcCU, 0, 0, 0, pcYuvOrg, pcYuvPred, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4908   
4909    if ( m_pcRdCost->getUseVSO() )
4910    {
4911      m_cYuvRecTemp.destroy();
4912    }
4913#else
4914    UInt uiZeroDistortion = 0;
4915    xEstimateResidualQT( pcCU, 0, 0, 0, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4916#endif
4917   
4918    m_pcEntropyCoder->resetBits();
4919    m_pcEntropyCoder->encodeQtRootCbfZero( pcCU );
4920    UInt zeroResiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4921
4922#if H_3D_VSO  // M19
4923    Double dZeroCost; 
4924    if( m_pcRdCost->getUseLambdaScaleVSO() )   
4925      dZeroCost = m_pcRdCost->calcRdCostVSO( 0, uiZeroDistortion );
4926    else
4927      dZeroCost = m_pcRdCost->calcRdCost( zeroResiBits, uiZeroDistortion );
4928#else
4929    Double dZeroCost = m_pcRdCost->calcRdCost( zeroResiBits, uiZeroDistortion );
4930#endif
4931    if(pcCU->isLosslessCoded( 0 ))
4932    { 
4933      dZeroCost = dCost + 1;
4934    }
4935    if ( dZeroCost < dCost )
4936    {
4937      dCost        = dZeroCost;
4938      uiBits       = 0;
4939      uiDistortion = uiZeroDistortion;
4940     
4941      const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4942      ::memset( pcCU->getTransformIdx()      , 0, uiQPartNum * sizeof(UChar) );
4943      ::memset( pcCU->getCbf( TEXT_LUMA )    , 0, uiQPartNum * sizeof(UChar) );
4944      ::memset( pcCU->getCbf( TEXT_CHROMA_U ), 0, uiQPartNum * sizeof(UChar) );
4945      ::memset( pcCU->getCbf( TEXT_CHROMA_V ), 0, uiQPartNum * sizeof(UChar) );
4946      ::memset( pcCU->getCoeffY()            , 0, uiWidth * uiHeight * sizeof( TCoeff )      );
4947      ::memset( pcCU->getCoeffCb()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4948      ::memset( pcCU->getCoeffCr()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4949      pcCU->setTransformSkipSubParts ( 0, 0, 0, 0, pcCU->getDepth(0) );
4950    }
4951    else
4952    {
4953      xSetResidualQTData( pcCU, 0, 0, 0, NULL, pcCU->getDepth(0), false );
4954    }
4955   
4956    if( m_bUseSBACRD )
4957    {
4958      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4959    }
4960#if 0 // check
4961    {
4962      m_pcEntropyCoder->resetBits();
4963      m_pcEntropyCoder->encodeCoeff( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
4964      const UInt uiBitsForCoeff = m_pcEntropyCoder->getNumberOfWrittenBits();
4965      if( m_bUseSBACRD )
4966      {
4967        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4968      }
4969      if( uiBitsForCoeff != uiBits )
4970        assert( 0 );
4971    }
4972#endif
4973    uiBits = 0;
4974    {
4975      TComYuv *pDummy = NULL;
4976      xAddSymbolBitsInter( pcCU, 0, 0, uiBits, pDummy, NULL, pDummy );
4977    }
4978   
4979#if H_3D_VSO // M20
4980    Double dExactCost; 
4981    if( m_pcRdCost->getUseLambdaScaleVSO() )   
4982      dExactCost = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );   
4983    else
4984      dExactCost = m_pcRdCost->calcRdCost   ( uiBits, uiDistortion );
4985#else   
4986    Double dExactCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4987#endif
4988    dCost = dExactCost;
4989   
4990    if ( dCost < dCostBest )
4991    {
4992      if ( !pcCU->getQtRootCbf( 0 ) )
4993      {
4994        rpcYuvResiBest->clear();
4995      }
4996      else
4997      {
4998        xSetResidualQTData( pcCU, 0, 0, 0, rpcYuvResiBest, pcCU->getDepth(0), true );
4999      }
5000     
5001      if( qpMin != qpMax && qp != qpMax )
5002      {
5003        const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
5004        ::memcpy( m_puhQTTempTrIdx, pcCU->getTransformIdx(),        uiQPartNum * sizeof(UChar) );
5005        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA ),     uiQPartNum * sizeof(UChar) );
5006        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPartNum * sizeof(UChar) );
5007        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPartNum * sizeof(UChar) );
5008        ::memcpy( m_pcQTTempCoeffY,  pcCU->getCoeffY(),  uiWidth * uiHeight * sizeof( TCoeff )      );
5009        ::memcpy( m_pcQTTempCoeffCb, pcCU->getCoeffCb(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
5010        ::memcpy( m_pcQTTempCoeffCr, pcCU->getCoeffCr(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
5011#if ADAPTIVE_QP_SELECTION
5012        ::memcpy( m_pcQTTempArlCoeffY,  pcCU->getArlCoeffY(),  uiWidth * uiHeight * sizeof( Int )      );
5013        ::memcpy( m_pcQTTempArlCoeffCb, pcCU->getArlCoeffCb(), uiWidth * uiHeight * sizeof( Int ) >> 2 );
5014        ::memcpy( m_pcQTTempArlCoeffCr, pcCU->getArlCoeffCr(), uiWidth * uiHeight * sizeof( Int ) >> 2 );
5015#endif
5016        ::memcpy( m_puhQTTempTransformSkipFlag[0], pcCU->getTransformSkip(TEXT_LUMA),     uiQPartNum * sizeof( UChar ) );
5017        ::memcpy( m_puhQTTempTransformSkipFlag[1], pcCU->getTransformSkip(TEXT_CHROMA_U), uiQPartNum * sizeof( UChar ) );
5018        ::memcpy( m_puhQTTempTransformSkipFlag[2], pcCU->getTransformSkip(TEXT_CHROMA_V), uiQPartNum * sizeof( UChar ) );
5019      }
5020      uiBitsBest       = uiBits;
5021      uiDistortionBest = uiDistortion;
5022      dCostBest        = dCost;
5023      qpBest           = qp;
5024      if( m_bUseSBACRD )
5025      {
5026        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
5027      }
5028    }
5029#if H_3D_VSO // M21
5030    if( m_pcRdCost->getUseRenModel() && !m_pcRdCost->getUseEstimatedVSD() )
5031    {
5032      Pel*  piSrc       = pcYuvOrg->getLumaAddr();
5033      UInt  uiSrcStride = pcYuvOrg->getStride();
5034      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
5035    }
5036#endif
5037  }
5038 
5039  assert ( dCostBest != MAX_DOUBLE );
5040 
5041  if( qpMin != qpMax && qpBest != qpMax )
5042  {
5043    if( m_bUseSBACRD )
5044    {
5045      assert( 0 ); // check
5046      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
5047    }
5048    // copy best cbf and trIdx to pcCU
5049    const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
5050    ::memcpy( pcCU->getTransformIdx(),       m_puhQTTempTrIdx,  uiQPartNum * sizeof(UChar) );
5051    ::memcpy( pcCU->getCbf( TEXT_LUMA ),     m_puhQTTempCbf[0], uiQPartNum * sizeof(UChar) );
5052    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPartNum * sizeof(UChar) );
5053    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPartNum * sizeof(UChar) );
5054    ::memcpy( pcCU->getCoeffY(),  m_pcQTTempCoeffY,  uiWidth * uiHeight * sizeof( TCoeff )      );
5055    ::memcpy( pcCU->getCoeffCb(), m_pcQTTempCoeffCb, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
5056    ::memcpy( pcCU->getCoeffCr(), m_pcQTTempCoeffCr, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
5057#if ADAPTIVE_QP_SELECTION
5058    ::memcpy( pcCU->getArlCoeffY(),  m_pcQTTempArlCoeffY,  uiWidth * uiHeight * sizeof( Int )      );
5059    ::memcpy( pcCU->getArlCoeffCb(), m_pcQTTempArlCoeffCb, uiWidth * uiHeight * sizeof( Int ) >> 2 );
5060    ::memcpy( pcCU->getArlCoeffCr(), m_pcQTTempArlCoeffCr, uiWidth * uiHeight * sizeof( Int ) >> 2 );
5061#endif
5062    ::memcpy( pcCU->getTransformSkip(TEXT_LUMA),     m_puhQTTempTransformSkipFlag[0], uiQPartNum * sizeof( UChar ) );
5063    ::memcpy( pcCU->getTransformSkip(TEXT_CHROMA_U), m_puhQTTempTransformSkipFlag[1], uiQPartNum * sizeof( UChar ) );
5064    ::memcpy( pcCU->getTransformSkip(TEXT_CHROMA_V), m_puhQTTempTransformSkipFlag[2], uiQPartNum * sizeof( UChar ) );
5065  }
5066  rpcYuvRec->addClip ( pcYuvPred, rpcYuvResiBest, 0, uiWidth );
5067
5068#if H_3D_VSO  // M22 // GT: might be removed since VSO already provided clipped distortion
5069  if ( m_pcRdCost->getUseVSO() )
5070  {
5071    uiDistortionBest = m_pcRdCost->getDistPartVSO  ( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight, false );
5072  }
5073  else
5074  {
5075#endif
5076  // update with clipped distortion and cost (qp estimation loop uses unclipped values)
5077#if WEIGHTED_CHROMA_DISTORTION
5078    uiDistortionBest = m_pcRdCost->getDistPart(g_bitDepthY, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
5079    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec<