source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncSearch.cpp @ 363

Last change on this file since 363 was 345, checked in by seregin, 11 years ago

merge SHM-3.0-dev branch

  • Property svn:eol-style set to native
File size: 239.5 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 
320  //-- jclee for using the SAD function pointer
321  m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );
322 
323  // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
324  if ( m_pcEncCfg->getUseFastEnc() )
325  {
326    if ( m_cDistParam.iRows > 8 )
327    {
328      m_cDistParam.iSubShift = 1;
329    }
330  }
331
332  setDistParamComp(0);  // Y component
333
334  // distortion
335  m_cDistParam.bitDepth = g_bitDepthY;
336  uiSad = m_cDistParam.DistFunc( &m_cDistParam );
337 
338  // motion cost
339  uiSad += m_pcRdCost->getCost( iSearchX, iSearchY );
340 
341  if( uiSad < rcStruct.uiBestSad )
342  {
343    rcStruct.uiBestSad      = uiSad;
344    rcStruct.iBestX         = iSearchX;
345    rcStruct.iBestY         = iSearchY;
346    rcStruct.uiBestDistance = uiDistance;
347    rcStruct.uiBestRound    = 0;
348    rcStruct.ucPointNr      = ucPointNr;
349  }
350}
351
352__inline Void TEncSearch::xTZ2PointSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB )
353{
354  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
355  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
356  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
357  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
358 
359  // 2 point search,                   //   1 2 3
360  // check only the 2 untested points  //   4 0 5
361  // around the start point            //   6 7 8
362  Int iStartX = rcStruct.iBestX;
363  Int iStartY = rcStruct.iBestY;
364  switch( rcStruct.ucPointNr )
365  {
366    case 1:
367    {
368      if ( (iStartX - 1) >= iSrchRngHorLeft )
369      {
370        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY, 0, 2 );
371      }
372      if ( (iStartY - 1) >= iSrchRngVerTop )
373      {
374        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
375      }
376    }
377      break;
378    case 2:
379    {
380      if ( (iStartY - 1) >= iSrchRngVerTop )
381      {
382        if ( (iStartX - 1) >= iSrchRngHorLeft )
383        {
384          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
385        }
386        if ( (iStartX + 1) <= iSrchRngHorRight )
387        {
388          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
389        }
390      }
391    }
392      break;
393    case 3:
394    {
395      if ( (iStartY - 1) >= iSrchRngVerTop )
396      {
397        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
398      }
399      if ( (iStartX + 1) <= iSrchRngHorRight )
400      {
401        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
402      }
403    }
404      break;
405    case 4:
406    {
407      if ( (iStartX - 1) >= iSrchRngHorLeft )
408      {
409        if ( (iStartY + 1) <= iSrchRngVerBottom )
410        {
411          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
412        }
413        if ( (iStartY - 1) >= iSrchRngVerTop )
414        {
415          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
416        }
417      }
418    }
419      break;
420    case 5:
421    {
422      if ( (iStartX + 1) <= iSrchRngHorRight )
423      {
424        if ( (iStartY - 1) >= iSrchRngVerTop )
425        {
426          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
427        }
428        if ( (iStartY + 1) <= iSrchRngVerBottom )
429        {
430          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
431        }
432      }
433    }
434      break;
435    case 6:
436    {
437      if ( (iStartX - 1) >= iSrchRngHorLeft )
438      {
439        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY , 0, 2 );
440      }
441      if ( (iStartY + 1) <= iSrchRngVerBottom )
442      {
443        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
444      }
445    }
446      break;
447    case 7:
448    {
449      if ( (iStartY + 1) <= iSrchRngVerBottom )
450      {
451        if ( (iStartX - 1) >= iSrchRngHorLeft )
452        {
453          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
454        }
455        if ( (iStartX + 1) <= iSrchRngHorRight )
456        {
457          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
458        }
459      }
460    }
461      break;
462    case 8:
463    {
464      if ( (iStartX + 1) <= iSrchRngHorRight )
465      {
466        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
467      }
468      if ( (iStartY + 1) <= iSrchRngVerBottom )
469      {
470        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
471      }
472    }
473      break;
474    default:
475    {
476      assert( false );
477    }
478      break;
479  } // switch( rcStruct.ucPointNr )
480}
481
482__inline Void TEncSearch::xTZ8PointSquareSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
483{
484  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
485  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
486  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
487  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
488 
489  // 8 point search,                   //   1 2 3
490  // search around the start point     //   4 0 5
491  // with the required  distance       //   6 7 8
492  assert( iDist != 0 );
493  const Int iTop        = iStartY - iDist;
494  const Int iBottom     = iStartY + iDist;
495  const Int iLeft       = iStartX - iDist;
496  const Int iRight      = iStartX + iDist;
497  rcStruct.uiBestRound += 1;
498 
499  if ( iTop >= iSrchRngVerTop ) // check top
500  {
501    if ( iLeft >= iSrchRngHorLeft ) // check top left
502    {
503      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iTop, 1, iDist );
504    }
505    // top middle
506    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
507   
508    if ( iRight <= iSrchRngHorRight ) // check top right
509    {
510      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iTop, 3, iDist );
511    }
512  } // check top
513  if ( iLeft >= iSrchRngHorLeft ) // check middle left
514  {
515    xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
516  }
517  if ( iRight <= iSrchRngHorRight ) // check middle right
518  {
519    xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
520  }
521  if ( iBottom <= iSrchRngVerBottom ) // check bottom
522  {
523    if ( iLeft >= iSrchRngHorLeft ) // check bottom left
524    {
525      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iBottom, 6, iDist );
526    }
527    // check bottom middle
528    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
529   
530    if ( iRight <= iSrchRngHorRight ) // check bottom right
531    {
532      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iBottom, 8, iDist );
533    }
534  } // check bottom
535}
536
537__inline Void TEncSearch::xTZ8PointDiamondSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
538{
539  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
540  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
541  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
542  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
543 
544  // 8 point search,                   //   1 2 3
545  // search around the start point     //   4 0 5
546  // with the required  distance       //   6 7 8
547  assert ( iDist != 0 );
548  const Int iTop        = iStartY - iDist;
549  const Int iBottom     = iStartY + iDist;
550  const Int iLeft       = iStartX - iDist;
551  const Int iRight      = iStartX + iDist;
552  rcStruct.uiBestRound += 1;
553 
554  if ( iDist == 1 ) // iDist == 1
555  {
556    if ( iTop >= iSrchRngVerTop ) // check top
557    {
558      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
559    }
560    if ( iLeft >= iSrchRngHorLeft ) // check middle left
561    {
562      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
563    }
564    if ( iRight <= iSrchRngHorRight ) // check middle right
565    {
566      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
567    }
568    if ( iBottom <= iSrchRngVerBottom ) // check bottom
569    {
570      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
571    }
572  }
573  else // if (iDist != 1)
574  {
575    if ( iDist <= 8 )
576    {
577      const Int iTop_2      = iStartY - (iDist>>1);
578      const Int iBottom_2   = iStartY + (iDist>>1);
579      const Int iLeft_2     = iStartX - (iDist>>1);
580      const Int iRight_2    = iStartX + (iDist>>1);
581     
582      if (  iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
583          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
584      {
585        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iTop,      2, iDist    );
586        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iTop_2,    1, iDist>>1 );
587        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2,    3, iDist>>1 );
588        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,    iStartY,   4, iDist    );
589        xTZSearchHelp( pcPatternKey, rcStruct, iRight,   iStartY,   5, iDist    );
590        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iBottom_2, 6, iDist>>1 );
591        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, iDist>>1 );
592        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iBottom,   7, iDist    );
593      }
594      else // check border
595      {
596        if ( iTop >= iSrchRngVerTop ) // check top
597        {
598          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
599        }
600        if ( iTop_2 >= iSrchRngVerTop ) // check half top
601        {
602          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
603          {
604            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iTop_2, 1, (iDist>>1) );
605          }
606          if ( iRight_2 <= iSrchRngHorRight ) // check half right
607          {
608            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2, 3, (iDist>>1) );
609          }
610        } // check half top
611        if ( iLeft >= iSrchRngHorLeft ) // check left
612        {
613          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
614        }
615        if ( iRight <= iSrchRngHorRight ) // check right
616        {
617          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
618        }
619        if ( iBottom_2 <= iSrchRngVerBottom ) // check half bottom
620        {
621          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
622          {
623            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iBottom_2, 6, (iDist>>1) );
624          }
625          if ( iRight_2 <= iSrchRngHorRight ) // check half right
626          {
627            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, (iDist>>1) );
628          }
629        } // check half bottom
630        if ( iBottom <= iSrchRngVerBottom ) // check bottom
631        {
632          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
633        }
634      } // check border
635    }
636    else // iDist > 8
637    {
638      if ( iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
639          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
640      {
641        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop,    0, iDist );
642        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,   iStartY, 0, iDist );
643        xTZSearchHelp( pcPatternKey, rcStruct, iRight,  iStartY, 0, iDist );
644        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
645        for ( Int index = 1; index < 4; index++ )
646        {
647          Int iPosYT = iTop    + ((iDist>>2) * index);
648          Int iPosYB = iBottom - ((iDist>>2) * index);
649          Int iPosXL = iStartX - ((iDist>>2) * index);
650          Int iPosXR = iStartX + ((iDist>>2) * index);
651          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
652          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
653          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
654          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
655        }
656      }
657      else // check border
658      {
659        if ( iTop >= iSrchRngVerTop ) // check top
660        {
661          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 0, iDist );
662        }
663        if ( iLeft >= iSrchRngHorLeft ) // check left
664        {
665          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 0, iDist );
666        }
667        if ( iRight <= iSrchRngHorRight ) // check right
668        {
669          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 0, iDist );
670        }
671        if ( iBottom <= iSrchRngVerBottom ) // check bottom
672        {
673          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
674        }
675        for ( Int index = 1; index < 4; index++ )
676        {
677          Int iPosYT = iTop    + ((iDist>>2) * index);
678          Int iPosYB = iBottom - ((iDist>>2) * index);
679          Int iPosXL = iStartX - ((iDist>>2) * index);
680          Int iPosXR = iStartX + ((iDist>>2) * index);
681         
682          if ( iPosYT >= iSrchRngVerTop ) // check top
683          {
684            if ( iPosXL >= iSrchRngHorLeft ) // check left
685            {
686              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
687            }
688            if ( iPosXR <= iSrchRngHorRight ) // check right
689            {
690              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
691            }
692          } // check top
693          if ( iPosYB <= iSrchRngVerBottom ) // check bottom
694          {
695            if ( iPosXL >= iSrchRngHorLeft ) // check left
696            {
697              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
698            }
699            if ( iPosXR <= iSrchRngHorRight ) // check right
700            {
701              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
702            }
703          } // check bottom
704        } // for ...
705      } // check border
706    } // iDist <= 8
707  } // iDist == 1
708}
709
710//<--
711
712UInt TEncSearch::xPatternRefinement( TComPattern* pcPatternKey,
713                                    TComMv baseRefMv,
714                                    Int iFrac, TComMv& rcMvFrac )
715{
716  UInt  uiDist;
717  UInt  uiDistBest  = MAX_UINT;
718  UInt  uiDirecBest = 0;
719 
720  Pel*  piRefPos;
721  Int iRefStride = m_filteredBlock[0][0].getStride();
722#if NS_HAD
723  m_pcRdCost->setDistParam( pcPatternKey, m_filteredBlock[0][0].getLumaAddr(), iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME(), m_pcEncCfg->getUseNSQT() );
724#else
725  m_pcRdCost->setDistParam( pcPatternKey, m_filteredBlock[0][0].getLumaAddr(), iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME() );
726#endif
727 
728  const TComMv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
729 
730  for (UInt i = 0; i < 9; i++)
731  {
732    TComMv cMvTest = pcMvRefine[i];
733    cMvTest += baseRefMv;
734   
735    Int horVal = cMvTest.getHor() * iFrac;
736    Int verVal = cMvTest.getVer() * iFrac;
737    piRefPos = m_filteredBlock[ verVal & 3 ][ horVal & 3 ].getLumaAddr();
738    if ( horVal == 2 && ( verVal & 1 ) == 0 )
739      piRefPos += 1;
740    if ( ( horVal & 1 ) == 0 && verVal == 2 )
741      piRefPos += iRefStride;
742    cMvTest = pcMvRefine[i];
743    cMvTest += rcMvFrac;
744
745    setDistParamComp(0);  // Y component
746
747    m_cDistParam.pCur = piRefPos;
748    m_cDistParam.bitDepth = g_bitDepthY;
749    uiDist = m_cDistParam.DistFunc( &m_cDistParam );
750    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
751   
752    if ( uiDist < uiDistBest )
753    {
754      uiDistBest  = uiDist;
755      uiDirecBest = i;
756    }
757  }
758 
759  rcMvFrac = pcMvRefine[uiDirecBest];
760 
761  return uiDistBest;
762}
763
764Void
765TEncSearch::xEncSubdivCbfQT( TComDataCU*  pcCU,
766                            UInt         uiTrDepth,
767                            UInt         uiAbsPartIdx,
768                            Bool         bLuma,
769                            Bool         bChroma )
770{
771  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
772  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
773  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
774  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
775
776  {
777    if( pcCU->getPredictionMode(0) == MODE_INTRA && pcCU->getPartitionSize(0) == SIZE_NxN && uiTrDepth == 0 )
778    {
779      assert( uiSubdiv );
780    }
781    else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
782    {
783      assert( uiSubdiv );
784    }
785    else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
786    {
787      assert( !uiSubdiv );
788    }
789    else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
790    {
791      assert( !uiSubdiv );
792    }
793    else
794    {
795      assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
796      if( bLuma )
797      {
798        m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize );
799      }
800    }
801  }
802 
803  if ( bChroma )
804  {
805    if( uiLog2TrafoSize > 2 )
806    {
807      if( uiTrDepth==0 || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth-1 ) )
808        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
809      if( uiTrDepth==0 || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth-1 ) )
810        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
811    }
812  }
813
814  if( uiSubdiv )
815  {
816    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
817    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
818    {
819      xEncSubdivCbfQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, bLuma, bChroma );
820    }
821    return;
822  }
823 
824  {
825    //===== Cbfs =====
826    if( bLuma )
827    {
828      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
829    }
830  }
831}
832
833Void
834TEncSearch::xEncCoeffQT( TComDataCU*  pcCU,
835                        UInt         uiTrDepth,
836                        UInt         uiAbsPartIdx,
837                        TextType     eTextType,
838                        Bool         bRealCoeff )
839{
840  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
841  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
842  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
843  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
844  UInt  uiChroma        = ( eTextType != TEXT_LUMA ? 1 : 0 );
845 
846  if( uiSubdiv )
847  {
848    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
849      for( UInt uiPart = 0; uiPart < 4; uiPart++ )
850      {
851        xEncCoeffQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, eTextType, bRealCoeff );
852      }
853    return;
854  }
855 
856  if( eTextType != TEXT_LUMA && uiLog2TrafoSize == 2 )
857  {
858    assert( uiTrDepth > 0 );
859    uiTrDepth--;
860    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
861    Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
862    if( !bFirstQ )
863    {
864      return;
865    }
866  }
867 
868  //===== coefficients =====
869  UInt    uiWidth         = pcCU->getWidth  ( 0 ) >> ( uiTrDepth + uiChroma );
870  UInt    uiHeight        = pcCU->getHeight ( 0 ) >> ( uiTrDepth + uiChroma );
871  UInt    uiCoeffOffset   = ( pcCU->getPic()->getMinCUWidth() * pcCU->getPic()->getMinCUHeight() * uiAbsPartIdx ) >> ( uiChroma << 1 );
872  UInt    uiQTLayer       = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrafoSize;
873  TCoeff* pcCoeff         = 0;
874  switch( eTextType )
875  {
876    case TEXT_LUMA:     pcCoeff = ( bRealCoeff ? pcCU->getCoeffY () : m_ppcQTTempCoeffY [uiQTLayer] );  break;
877    case TEXT_CHROMA_U: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCb() : m_ppcQTTempCoeffCb[uiQTLayer] );  break;
878    case TEXT_CHROMA_V: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCr() : m_ppcQTTempCoeffCr[uiQTLayer] );  break;
879    default:            assert(0);
880  }
881  pcCoeff += uiCoeffOffset;
882 
883  m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiWidth, uiHeight, uiFullDepth, eTextType );
884}
885
886
887Void
888TEncSearch::xEncIntraHeader( TComDataCU*  pcCU,
889                            UInt         uiTrDepth,
890                            UInt         uiAbsPartIdx,
891                            Bool         bLuma,
892                            Bool         bChroma )
893{
894  if( bLuma )
895  {
896    // CU header
897    if( uiAbsPartIdx == 0 )
898    {
899      if( !pcCU->getSlice()->isIntra() )
900      {
901        if (pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
902        {
903          m_pcEntropyCoder->encodeCUTransquantBypassFlag( pcCU, 0, true );
904        }
905        m_pcEntropyCoder->encodeSkipFlag( pcCU, 0, true );
906        m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
907      }
908   
909      m_pcEntropyCoder  ->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
910
911      if (pcCU->isIntra(0) && pcCU->getPartitionSize(0) == SIZE_2Nx2N )
912      {
913        m_pcEntropyCoder->encodeIPCMInfo( pcCU, 0, true );
914
915        if ( pcCU->getIPCMFlag (0))
916        {
917          return;
918        }
919      }
920    }
921    // luma prediction mode
922    if( pcCU->getPartitionSize(0) == SIZE_2Nx2N )
923    {
924      if( uiAbsPartIdx == 0 )
925      {
926        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, 0 );
927      }
928    }
929    else
930    {
931      UInt uiQNumParts = pcCU->getTotalNumPart() >> 2;
932      if( uiTrDepth == 0 )
933      {
934        assert( uiAbsPartIdx == 0 );
935        for( UInt uiPart = 0; uiPart < 4; uiPart++ )
936        {
937          m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPart * uiQNumParts );
938        }
939      }
940      else if( ( uiAbsPartIdx % uiQNumParts ) == 0 )
941      {
942        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiAbsPartIdx );
943      }
944    }
945  }
946
947  if( bChroma )
948  {
949    // chroma prediction mode
950    if( uiAbsPartIdx == 0 )
951    {
952      m_pcEntropyCoder->encodeIntraDirModeChroma( pcCU, 0, true );
953    }
954  }
955}
956
957
958UInt
959TEncSearch::xGetIntraBitsQT( TComDataCU*  pcCU,
960                            UInt         uiTrDepth,
961                            UInt         uiAbsPartIdx,
962                            Bool         bLuma,
963                            Bool         bChroma,
964                            Bool         bRealCoeff /* just for test */ )
965{
966  m_pcEntropyCoder->resetBits();
967  xEncIntraHeader ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
968  xEncSubdivCbfQT ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
969 
970  if( bLuma )
971  {
972    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_LUMA,      bRealCoeff );
973  }
974  if( bChroma )
975  {
976    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_U,  bRealCoeff );
977    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_V,  bRealCoeff );
978  }
979  UInt   uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
980  return uiBits;
981}
982
983UInt
984TEncSearch::xGetIntraBitsQTChroma( TComDataCU*  pcCU,
985                                  UInt         uiTrDepth,
986                                  UInt         uiAbsPartIdx,
987                                  UInt         uiChromaId,
988                                  Bool         bRealCoeff /* just for test */ )
989{
990  m_pcEntropyCoder->resetBits();
991  if( uiChromaId == TEXT_CHROMA_U)
992  {
993    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_U,  bRealCoeff );
994  }
995  else if(uiChromaId == TEXT_CHROMA_V)
996  {
997    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_V,  bRealCoeff );
998  }
999
1000  UInt   uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
1001  return uiBits;
1002}
1003
1004Void
1005TEncSearch::xIntraCodingLumaBlk( TComDataCU* pcCU,
1006                                UInt        uiTrDepth,
1007                                UInt        uiAbsPartIdx,
1008                                TComYuv*    pcOrgYuv, 
1009                                TComYuv*    pcPredYuv, 
1010                                TComYuv*    pcResiYuv, 
1011                                UInt&       ruiDist,
1012                                Int        default0Save1Load2 )
1013{
1014  UInt    uiLumaPredMode    = pcCU     ->getLumaIntraDir     ( uiAbsPartIdx );
1015  UInt    uiFullDepth       = pcCU     ->getDepth   ( 0 )  + uiTrDepth;
1016  UInt    uiWidth           = pcCU     ->getWidth   ( 0 ) >> uiTrDepth;
1017  UInt    uiHeight          = pcCU     ->getHeight  ( 0 ) >> uiTrDepth;
1018  UInt    uiStride          = pcOrgYuv ->getStride  ();
1019  Pel*    piOrg             = pcOrgYuv ->getLumaAddr( uiAbsPartIdx );
1020  Pel*    piPred            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
1021  Pel*    piResi            = pcResiYuv->getLumaAddr( uiAbsPartIdx );
1022  Pel*    piReco            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
1023 
1024  UInt    uiLog2TrSize      = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1025  UInt    uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1026  UInt    uiNumCoeffPerInc  = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
1027  TCoeff* pcCoeff           = m_ppcQTTempCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;
1028#if ADAPTIVE_QP_SELECTION
1029  Int*    pcArlCoeff        = m_ppcQTTempArlCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;
1030#endif
1031  Pel*    piRecQt           = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
1032  UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
1033 
1034  UInt    uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1035  Pel*    piRecIPred        = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
1036  UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getStride  ();
1037  Bool    useTransformSkip  = pcCU->getTransformSkip(uiAbsPartIdx, TEXT_LUMA);
1038  //===== init availability pattern =====
1039  Bool  bAboveAvail = false;
1040  Bool  bLeftAvail  = false;
1041  if(default0Save1Load2 != 2)
1042  {
1043    pcCU->getPattern()->initPattern   ( pcCU, uiTrDepth, uiAbsPartIdx );
1044    pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1045    //===== get prediction signal =====
1046    predIntraLumaAng( pcCU->getPattern(), uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail );
1047    // save prediction
1048    if(default0Save1Load2 == 1)
1049    {
1050      Pel*  pPred   = piPred;
1051      Pel*  pPredBuf = m_pSharedPredTransformSkip[0];
1052      Int k = 0;
1053      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1054      {
1055        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1056        {
1057          pPredBuf[ k ++ ] = pPred[ uiX ];
1058        }
1059        pPred += uiStride;
1060      }
1061    }
1062  }
1063  else 
1064  {
1065    // load prediction
1066    Pel*  pPred   = piPred;
1067    Pel*  pPredBuf = m_pSharedPredTransformSkip[0];
1068    Int k = 0;
1069    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1070    {
1071      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1072      {
1073        pPred[ uiX ] = pPredBuf[ k ++ ];
1074      }
1075      pPred += uiStride;
1076    }
1077  }
1078  //===== get residual signal =====
1079  {
1080    // get residual
1081    Pel*  pOrg    = piOrg;
1082    Pel*  pPred   = piPred;
1083    Pel*  pResi   = piResi;
1084    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1085    {
1086      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1087      {
1088        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1089      }
1090      pOrg  += uiStride;
1091      pResi += uiStride;
1092      pPred += uiStride;
1093    }
1094  }
1095 
1096  //===== transform and quantization =====
1097  //--- init rate estimation arrays for RDOQ ---
1098  if( useTransformSkip? m_pcEncCfg->getUseRDOQTS():m_pcEncCfg->getUseRDOQ())
1099  {
1100    m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, uiWidth, TEXT_LUMA );
1101  }
1102  //--- transform and quantization ---
1103  UInt uiAbsSum = 0;
1104  pcCU       ->setTrIdxSubParts ( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1105
1106  m_pcTrQuant->setQPforQuant    ( pcCU->getQP( 0 ), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
1107
1108#if RDOQ_CHROMA_LAMBDA
1109  m_pcTrQuant->selectLambda     (TEXT_LUMA); 
1110#endif
1111
1112  m_pcTrQuant->transformNxN     ( pcCU, piResi, uiStride, pcCoeff, 
1113#if ADAPTIVE_QP_SELECTION
1114    pcArlCoeff, 
1115#endif
1116    uiWidth, uiHeight, uiAbsSum, TEXT_LUMA, uiAbsPartIdx,useTransformSkip );
1117 
1118  //--- set coded block flag ---
1119  pcCU->setCbfSubParts          ( ( uiAbsSum ? 1 : 0 ) << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );
1120  //--- inverse transform ---
1121  if( uiAbsSum )
1122  {
1123    Int scalingListType = 0 + g_eTTable[(Int)TEXT_LUMA];
1124    assert(scalingListType < 6);
1125    m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_LUMA,pcCU->getLumaIntraDir( uiAbsPartIdx ), piResi, uiStride, pcCoeff, uiWidth, uiHeight, scalingListType, useTransformSkip );
1126  }
1127  else
1128  {
1129    Pel* pResi = piResi;
1130    memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );
1131    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1132    {
1133      memset( pResi, 0, sizeof( Pel ) * uiWidth );
1134      pResi += uiStride;
1135    }
1136  }
1137 
1138  //===== reconstruction =====
1139  {
1140    Pel* pPred      = piPred;
1141    Pel* pResi      = piResi;
1142    Pel* pReco      = piReco;
1143    Pel* pRecQt     = piRecQt;
1144    Pel* pRecIPred  = piRecIPred;
1145    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1146    {
1147      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1148      {
1149        pReco    [ uiX ] = ClipY( pPred[ uiX ] + pResi[ uiX ] );
1150        pRecQt   [ uiX ] = pReco[ uiX ];
1151        pRecIPred[ uiX ] = pReco[ uiX ];
1152      }
1153      pPred     += uiStride;
1154      pResi     += uiStride;
1155      pReco     += uiStride;
1156      pRecQt    += uiRecQtStride;
1157      pRecIPred += uiRecIPredStride;
1158    }
1159  }
1160 
1161  //===== update distortion =====
1162  ruiDist += m_pcRdCost->getDistPart(g_bitDepthY, piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight );
1163}
1164
1165Void
1166TEncSearch::xIntraCodingChromaBlk( TComDataCU* pcCU,
1167                                  UInt        uiTrDepth,
1168                                  UInt        uiAbsPartIdx,
1169                                  TComYuv*    pcOrgYuv, 
1170                                  TComYuv*    pcPredYuv, 
1171                                  TComYuv*    pcResiYuv, 
1172                                  UInt&       ruiDist,
1173                                  UInt        uiChromaId,
1174                                  Int        default0Save1Load2 )
1175{
1176  UInt uiOrgTrDepth = uiTrDepth;
1177  UInt uiFullDepth  = pcCU->getDepth( 0 ) + uiTrDepth;
1178  UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1179  if( uiLog2TrSize == 2 )
1180  {
1181    assert( uiTrDepth > 0 );
1182    uiTrDepth--;
1183    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
1184    Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
1185    if( !bFirstQ )
1186    {
1187      return;
1188    }
1189  }
1190 
1191  TextType  eText             = ( uiChromaId > 0 ? TEXT_CHROMA_V : TEXT_CHROMA_U );
1192  UInt      uiChromaPredMode  = pcCU     ->getChromaIntraDir( uiAbsPartIdx );
1193  UInt      uiWidth           = pcCU     ->getWidth   ( 0 ) >> ( uiTrDepth + 1 );
1194  UInt      uiHeight          = pcCU     ->getHeight  ( 0 ) >> ( uiTrDepth + 1 );
1195  UInt      uiStride          = pcOrgYuv ->getCStride ();
1196  Pel*      piOrg             = ( uiChromaId > 0 ? pcOrgYuv ->getCrAddr( uiAbsPartIdx ) : pcOrgYuv ->getCbAddr( uiAbsPartIdx ) );
1197  Pel*      piPred            = ( uiChromaId > 0 ? pcPredYuv->getCrAddr( uiAbsPartIdx ) : pcPredYuv->getCbAddr( uiAbsPartIdx ) );
1198  Pel*      piResi            = ( uiChromaId > 0 ? pcResiYuv->getCrAddr( uiAbsPartIdx ) : pcResiYuv->getCbAddr( uiAbsPartIdx ) );
1199  Pel*      piReco            = ( uiChromaId > 0 ? pcPredYuv->getCrAddr( uiAbsPartIdx ) : pcPredYuv->getCbAddr( uiAbsPartIdx ) );
1200 
1201  UInt      uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1202  UInt      uiNumCoeffPerInc  = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) ) >> 2;
1203  TCoeff*   pcCoeff           = ( uiChromaId > 0 ? m_ppcQTTempCoeffCr[ uiQTLayer ] : m_ppcQTTempCoeffCb[ uiQTLayer ] ) + uiNumCoeffPerInc * uiAbsPartIdx;
1204#if ADAPTIVE_QP_SELECTION
1205  Int*      pcArlCoeff        = ( uiChromaId > 0 ? m_ppcQTTempArlCoeffCr[ uiQTLayer ] : m_ppcQTTempArlCoeffCb[ uiQTLayer ] ) + uiNumCoeffPerInc * uiAbsPartIdx;
1206#endif
1207  Pel*      piRecQt           = ( uiChromaId > 0 ? m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr( uiAbsPartIdx ) : m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr( uiAbsPartIdx ) );
1208  UInt      uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getCStride();
1209 
1210  UInt      uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1211  Pel*      piRecIPred        = ( uiChromaId > 0 ? pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder ) : pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder ) );
1212  UInt      uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getCStride();
1213  Bool      useTransformSkipChroma       = pcCU->getTransformSkip(uiAbsPartIdx, eText);
1214  //===== update chroma mode =====
1215  if( uiChromaPredMode == DM_CHROMA_IDX )
1216  {
1217    uiChromaPredMode          = pcCU->getLumaIntraDir( 0 );
1218  }
1219 
1220  //===== init availability pattern =====
1221  Bool  bAboveAvail = false;
1222  Bool  bLeftAvail  = false;
1223  if( default0Save1Load2 != 2 )
1224  {
1225    pcCU->getPattern()->initPattern         ( pcCU, uiTrDepth, uiAbsPartIdx );
1226
1227    pcCU->getPattern()->initAdiPatternChroma( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1228    Int*  pPatChroma  = ( uiChromaId > 0 ? pcCU->getPattern()->getAdiCrBuf( uiWidth, uiHeight, m_piYuvExt ) : pcCU->getPattern()->getAdiCbBuf( uiWidth, uiHeight, m_piYuvExt ) );
1229
1230    //===== get prediction signal =====
1231    predIntraChromaAng( pPatChroma, uiChromaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail );
1232
1233    // save prediction
1234    if( default0Save1Load2 == 1 )
1235    {
1236      Pel*  pPred   = piPred;
1237      Pel*  pPredBuf = m_pSharedPredTransformSkip[1 + uiChromaId];
1238      Int k = 0;
1239      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1240      {
1241        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1242        {
1243          pPredBuf[ k ++ ] = pPred[ uiX ];
1244        }
1245        pPred += uiStride;
1246      }
1247    }
1248  }
1249  else
1250  {
1251    // load prediction
1252    Pel*  pPred   = piPred;
1253    Pel*  pPredBuf = m_pSharedPredTransformSkip[1 + uiChromaId];
1254    Int k = 0;
1255    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1256    {
1257      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1258      {
1259        pPred[ uiX ] = pPredBuf[ k ++ ];
1260      }
1261      pPred += uiStride;
1262    }
1263  }
1264  //===== get residual signal =====
1265  {
1266    // get residual
1267    Pel*  pOrg    = piOrg;
1268    Pel*  pPred   = piPred;
1269    Pel*  pResi   = piResi;
1270    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1271    {
1272      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1273      {
1274        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1275      }
1276      pOrg  += uiStride;
1277      pResi += uiStride;
1278      pPred += uiStride;
1279    }
1280  }
1281 
1282  //===== transform and quantization =====
1283  {
1284    //--- init rate estimation arrays for RDOQ ---
1285    if( useTransformSkipChroma? m_pcEncCfg->getUseRDOQTS():m_pcEncCfg->getUseRDOQ())
1286    {
1287      m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, uiWidth, eText );
1288    }
1289    //--- transform and quantization ---
1290    UInt uiAbsSum = 0;
1291
1292    Int curChromaQpOffset;
1293    if(eText == TEXT_CHROMA_U)
1294    {
1295      curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCbQpOffset() + pcCU->getSlice()->getSliceQpDeltaCb();
1296    }
1297    else
1298    {
1299      curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCrQpOffset() + pcCU->getSlice()->getSliceQpDeltaCr();
1300    }
1301    m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
1302
1303#if RDOQ_CHROMA_LAMBDA
1304    m_pcTrQuant->selectLambda      (TEXT_CHROMA); 
1305#endif
1306    m_pcTrQuant->transformNxN      ( pcCU, piResi, uiStride, pcCoeff, 
1307#if ADAPTIVE_QP_SELECTION
1308                                     pcArlCoeff, 
1309#endif
1310                                     uiWidth, uiHeight, uiAbsSum, eText, uiAbsPartIdx, useTransformSkipChroma );
1311    //--- set coded block flag ---
1312    pcCU->setCbfSubParts           ( ( uiAbsSum ? 1 : 0 ) << uiOrgTrDepth, eText, uiAbsPartIdx, pcCU->getDepth(0) + uiTrDepth );
1313    //--- inverse transform ---
1314    if( uiAbsSum )
1315    {
1316      Int scalingListType = 0 + g_eTTable[(Int)eText];
1317      assert(scalingListType < 6);
1318      m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_CHROMA, REG_DCT, piResi, uiStride, pcCoeff, uiWidth, uiHeight, scalingListType, useTransformSkipChroma );
1319    }
1320    else
1321    {
1322      Pel* pResi = piResi;
1323      memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );
1324      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1325      {
1326        memset( pResi, 0, sizeof( Pel ) * uiWidth );
1327        pResi += uiStride;
1328      }
1329    }
1330  }
1331 
1332  //===== reconstruction =====
1333  {
1334    Pel* pPred      = piPred;
1335    Pel* pResi      = piResi;
1336    Pel* pReco      = piReco;
1337    Pel* pRecQt     = piRecQt;
1338    Pel* pRecIPred  = piRecIPred;
1339    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1340    {
1341      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1342      {
1343        pReco    [ uiX ] = ClipC( pPred[ uiX ] + pResi[ uiX ] );
1344        pRecQt   [ uiX ] = pReco[ uiX ];
1345        pRecIPred[ uiX ] = pReco[ uiX ];
1346      }
1347      pPred     += uiStride;
1348      pResi     += uiStride;
1349      pReco     += uiStride;
1350      pRecQt    += uiRecQtStride;
1351      pRecIPred += uiRecIPredStride;
1352    }
1353  }
1354 
1355  //===== update distortion =====
1356#if WEIGHTED_CHROMA_DISTORTION
1357  ruiDist += m_pcRdCost->getDistPart(g_bitDepthC, piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight, eText );
1358#else
1359  ruiDist += m_pcRdCost->getDistPart(g_bitDepthC, piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight );
1360#endif
1361}
1362
1363
1364
1365Void
1366TEncSearch::xRecurIntraCodingQT( TComDataCU*  pcCU, 
1367                                UInt         uiTrDepth,
1368                                UInt         uiAbsPartIdx, 
1369                                Bool         bLumaOnly,
1370                                TComYuv*     pcOrgYuv, 
1371                                TComYuv*     pcPredYuv, 
1372                                TComYuv*     pcResiYuv, 
1373                                UInt&        ruiDistY,
1374                                UInt&        ruiDistC,
1375#if HHI_RQT_INTRA_SPEEDUP
1376                                Bool         bCheckFirst,
1377#endif
1378                                Double&      dRDCost )
1379{
1380  UInt    uiFullDepth   = pcCU->getDepth( 0 ) +  uiTrDepth;
1381  UInt    uiLog2TrSize  = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1382  Bool    bCheckFull    = ( uiLog2TrSize  <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
1383  Bool    bCheckSplit   = ( uiLog2TrSize  >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
1384 
1385#if HHI_RQT_INTRA_SPEEDUP
1386  Int maxTuSize = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize();
1387  Int isIntraSlice = (pcCU->getSlice()->getSliceType() == I_SLICE);
1388  // don't check split if TU size is less or equal to max TU size
1389  Bool noSplitIntraMaxTuSize = bCheckFull;
1390  if(m_pcEncCfg->getRDpenalty() && ! isIntraSlice)
1391  {
1392    // in addition don't check split if TU size is less or equal to 16x16 TU size for non-intra slice
1393    noSplitIntraMaxTuSize = ( uiLog2TrSize  <= min(maxTuSize,4) );
1394
1395    // if maximum RD-penalty don't check TU size 32x32
1396    if(m_pcEncCfg->getRDpenalty()==2)
1397    {
1398      bCheckFull    = ( uiLog2TrSize  <= min(maxTuSize,4));
1399    }
1400  }
1401  if( bCheckFirst && noSplitIntraMaxTuSize )
1402  {
1403    bCheckSplit = false;
1404  }
1405#else
1406  Int maxTuSize = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize();
1407  Int isIntraSlice = (pcCU->getSlice()->getSliceType() == I_SLICE);
1408  // if maximum RD-penalty don't check TU size 32x32
1409  if((m_pcEncCfg->getRDpenalty()==2)  && !isIntraSlice)
1410  {
1411    bCheckFull    = ( uiLog2TrSize  <= min(maxTuSize,4));
1412  }
1413#endif
1414  Double  dSingleCost   = MAX_DOUBLE;
1415  UInt    uiSingleDistY = 0;
1416  UInt    uiSingleDistC = 0;
1417  UInt    uiSingleCbfY  = 0;
1418  UInt    uiSingleCbfU  = 0;
1419  UInt    uiSingleCbfV  = 0;
1420  Bool    checkTransformSkip  = pcCU->getSlice()->getPPS()->getUseTransformSkip();
1421  UInt    widthTransformSkip  = pcCU->getWidth ( 0 ) >> uiTrDepth;
1422  UInt    heightTransformSkip = pcCU->getHeight( 0 ) >> uiTrDepth;
1423  Int     bestModeId    = 0;
1424  Int     bestModeIdUV[2] = {0, 0};
1425  checkTransformSkip         &= (widthTransformSkip == 4 && heightTransformSkip == 4);
1426  checkTransformSkip         &= (!pcCU->getCUTransquantBypass(0));
1427  checkTransformSkip         &= (!((pcCU->getQP( 0 ) == 0) && (pcCU->getSlice()->getSPS()->getUseLossless())));
1428  if ( m_pcEncCfg->getUseTransformSkipFast() )
1429  {
1430    checkTransformSkip       &= (pcCU->getPartitionSize(uiAbsPartIdx)==SIZE_NxN);
1431  }
1432  if( bCheckFull )
1433  {
1434    if(checkTransformSkip == true)
1435    {
1436      //----- store original entropy coding status -----
1437      if( m_bUseSBACRD)
1438      {
1439        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1440      }
1441      UInt   singleDistYTmp     = 0;
1442      UInt   singleDistCTmp     = 0;
1443      UInt   singleCbfYTmp      = 0;
1444      UInt   singleCbfUTmp      = 0;
1445      UInt   singleCbfVTmp      = 0;
1446      Double singleCostTmp      = 0;
1447      Int    default0Save1Load2 = 0;
1448      Int    firstCheckId       = 0;
1449
1450      UInt   uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + (uiTrDepth - 1) ) << 1 );
1451      Bool   bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
1452
1453      for(Int modeId = firstCheckId; modeId < 2; modeId ++)
1454      {
1455        singleDistYTmp = 0;
1456        singleDistCTmp = 0;
1457        pcCU ->setTransformSkipSubParts ( modeId, TEXT_LUMA, uiAbsPartIdx, uiFullDepth ); 
1458        if(modeId == firstCheckId)
1459        {
1460          default0Save1Load2 = 1;
1461        }
1462        else
1463        {
1464          default0Save1Load2 = 2;
1465        }
1466        //----- code luma block with given intra prediction mode and store Cbf-----
1467        xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, singleDistYTmp,default0Save1Load2); 
1468        singleCbfYTmp = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrDepth );
1469        //----- code chroma blocks with given intra prediction mode and store Cbf-----
1470        if( !bLumaOnly )
1471        {
1472          if(bFirstQ)
1473          {
1474            pcCU ->setTransformSkipSubParts ( modeId, TEXT_CHROMA_U, uiAbsPartIdx, uiFullDepth); 
1475            pcCU ->setTransformSkipSubParts ( modeId, TEXT_CHROMA_V, uiAbsPartIdx, uiFullDepth); 
1476          }
1477          xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, singleDistCTmp, 0, default0Save1Load2); 
1478          xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, singleDistCTmp, 1, default0Save1Load2); 
1479          singleCbfUTmp = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
1480          singleCbfVTmp = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
1481        }
1482        //----- determine rate and r-d cost -----
1483        if(modeId == 1 && singleCbfYTmp == 0)
1484        {
1485          //In order not to code TS flag when cbf is zero, the case for TS with cbf being zero is forbidden.
1486          singleCostTmp = MAX_DOUBLE; 
1487        }
1488        else
1489        {
1490          UInt uiSingleBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );
1491          singleCostTmp     = m_pcRdCost->calcRdCost( uiSingleBits, singleDistYTmp + singleDistCTmp );
1492        }
1493
1494        if(singleCostTmp < dSingleCost)
1495        {
1496          dSingleCost   = singleCostTmp;
1497          uiSingleDistY = singleDistYTmp;
1498          uiSingleDistC = singleDistCTmp;
1499          uiSingleCbfY  = singleCbfYTmp;
1500          uiSingleCbfU  = singleCbfUTmp;
1501          uiSingleCbfV  = singleCbfVTmp;
1502          bestModeId    = modeId;
1503          if(bestModeId == firstCheckId)
1504          {
1505            xStoreIntraResultQT(pcCU, uiTrDepth, uiAbsPartIdx,bLumaOnly );
1506            if( m_bUseSBACRD) 
1507            {
1508              m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
1509            }
1510          }
1511        }
1512        if(modeId == firstCheckId)
1513        {
1514          m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1515        }
1516      }
1517
1518      pcCU ->setTransformSkipSubParts ( bestModeId, TEXT_LUMA, uiAbsPartIdx, uiFullDepth ); 
1519
1520      if(bestModeId == firstCheckId)
1521      {
1522        xLoadIntraResultQT(pcCU, uiTrDepth, uiAbsPartIdx,bLumaOnly );
1523        pcCU->setCbfSubParts  ( uiSingleCbfY << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );
1524        if( !bLumaOnly )
1525        {
1526          if(bFirstQ)
1527          {
1528            pcCU->setCbfSubParts( uiSingleCbfU << uiTrDepth, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth( 0 ) + uiTrDepth - 1 );
1529            pcCU->setCbfSubParts( uiSingleCbfV << uiTrDepth, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth( 0 ) + uiTrDepth - 1 );
1530          }
1531        }
1532        if(m_bUseSBACRD)
1533        {
1534          m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
1535        } 
1536      }
1537
1538      if( !bLumaOnly )
1539      {
1540        bestModeIdUV[0] = bestModeIdUV[1] = bestModeId;
1541        if(bFirstQ && bestModeId == 1)
1542        {
1543          //In order not to code TS flag when cbf is zero, the case for TS with cbf being zero is forbidden.
1544          if(uiSingleCbfU == 0)
1545          {
1546            pcCU ->setTransformSkipSubParts ( 0, TEXT_CHROMA_U, uiAbsPartIdx, uiFullDepth); 
1547            bestModeIdUV[0] = 0;
1548          }
1549          if(uiSingleCbfV == 0)
1550          {
1551            pcCU ->setTransformSkipSubParts ( 0, TEXT_CHROMA_V, uiAbsPartIdx, uiFullDepth); 
1552            bestModeIdUV[1] = 0;
1553          }
1554        }
1555      }
1556    }
1557    else
1558    {
1559      pcCU ->setTransformSkipSubParts ( 0, TEXT_LUMA, uiAbsPartIdx, uiFullDepth ); 
1560      //----- store original entropy coding status -----
1561      if( m_bUseSBACRD && bCheckSplit )
1562      {
1563        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1564      }
1565      //----- code luma block with given intra prediction mode and store Cbf-----
1566      dSingleCost   = 0.0;
1567      xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistY ); 
1568      if( bCheckSplit )
1569      {
1570        uiSingleCbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrDepth );
1571      }
1572      //----- code chroma blocks with given intra prediction mode and store Cbf-----
1573      if( !bLumaOnly )
1574      {
1575        pcCU ->setTransformSkipSubParts ( 0, TEXT_CHROMA_U, uiAbsPartIdx, uiFullDepth ); 
1576        pcCU ->setTransformSkipSubParts ( 0, TEXT_CHROMA_V, uiAbsPartIdx, uiFullDepth ); 
1577        xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 0 ); 
1578        xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 1 ); 
1579        if( bCheckSplit )
1580        {
1581          uiSingleCbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
1582          uiSingleCbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
1583        }
1584      }
1585      //----- determine rate and r-d cost -----
1586      UInt uiSingleBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );
1587      if(m_pcEncCfg->getRDpenalty() && (uiLog2TrSize==5) && !isIntraSlice)
1588      {
1589        uiSingleBits=uiSingleBits*4; 
1590      }
1591      dSingleCost       = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDistY + uiSingleDistC );
1592    }
1593  }
1594 
1595  if( bCheckSplit )
1596  {
1597    //----- store full entropy coding status, load original entropy coding status -----
1598    if( m_bUseSBACRD )
1599    {
1600      if( bCheckFull )
1601      {
1602        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1603        m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1604      }
1605      else
1606      {
1607        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1608      }
1609    }
1610    //----- code splitted block -----
1611    Double  dSplitCost      = 0.0;
1612    UInt    uiSplitDistY    = 0;
1613    UInt    uiSplitDistC    = 0;
1614    UInt    uiQPartsDiv     = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1615    UInt    uiAbsPartIdxSub = uiAbsPartIdx;
1616
1617    UInt    uiSplitCbfY = 0;
1618    UInt    uiSplitCbfU = 0;
1619    UInt    uiSplitCbfV = 0;
1620
1621    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiAbsPartIdxSub += uiQPartsDiv )
1622    {
1623#if HHI_RQT_INTRA_SPEEDUP
1624      xRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, bCheckFirst, dSplitCost );
1625#else
1626      xRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, dSplitCost );
1627#endif
1628
1629      uiSplitCbfY |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_LUMA, uiTrDepth + 1 );
1630      if(!bLumaOnly)
1631      {
1632        uiSplitCbfU |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_U, uiTrDepth + 1 );
1633        uiSplitCbfV |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_V, uiTrDepth + 1 );
1634      }
1635    }
1636
1637    for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1638    {
1639      pcCU->getCbf( TEXT_LUMA )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfY << uiTrDepth );
1640    }
1641    if( !bLumaOnly )
1642    {
1643      for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1644      {
1645        pcCU->getCbf( TEXT_CHROMA_U )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfU << uiTrDepth );
1646        pcCU->getCbf( TEXT_CHROMA_V )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfV << uiTrDepth );
1647      }
1648    }
1649    //----- restore context states -----
1650    if( m_bUseSBACRD )
1651    {
1652      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1653    }
1654    //----- determine rate and r-d cost -----
1655    UInt uiSplitBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );
1656    dSplitCost       = m_pcRdCost->calcRdCost( uiSplitBits, uiSplitDistY + uiSplitDistC );
1657   
1658    //===== compare and set best =====
1659    if( dSplitCost < dSingleCost )
1660    {
1661      //--- update cost ---
1662      ruiDistY += uiSplitDistY;
1663      ruiDistC += uiSplitDistC;
1664      dRDCost  += dSplitCost;
1665      return;
1666    }
1667    //----- set entropy coding status -----
1668    if( m_bUseSBACRD )
1669    {
1670      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1671    }
1672   
1673    //--- set transform index and Cbf values ---
1674    pcCU->setTrIdxSubParts( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1675    pcCU->setCbfSubParts  ( uiSingleCbfY << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );
1676    pcCU ->setTransformSkipSubParts  ( bestModeId, TEXT_LUMA, uiAbsPartIdx, uiFullDepth ); 
1677    if( !bLumaOnly )
1678    {
1679      pcCU->setCbfSubParts( uiSingleCbfU << uiTrDepth, TEXT_CHROMA_U, uiAbsPartIdx, uiFullDepth );
1680      pcCU->setCbfSubParts( uiSingleCbfV << uiTrDepth, TEXT_CHROMA_V, uiAbsPartIdx, uiFullDepth );
1681      pcCU->setTransformSkipSubParts ( bestModeIdUV[0], TEXT_CHROMA_U, uiAbsPartIdx, uiFullDepth); 
1682      pcCU->setTransformSkipSubParts ( bestModeIdUV[1], TEXT_CHROMA_V, uiAbsPartIdx, uiFullDepth); 
1683    }
1684   
1685    //--- set reconstruction for next intra prediction blocks ---
1686    UInt  uiWidth     = pcCU->getWidth ( 0 ) >> uiTrDepth;
1687    UInt  uiHeight    = pcCU->getHeight( 0 ) >> uiTrDepth;
1688    UInt  uiQTLayer   = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1689    UInt  uiZOrder    = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1690    Pel*  piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
1691    UInt  uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
1692    Pel*  piDes       = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
1693    UInt  uiDesStride = pcCU->getPic()->getPicYuvRec()->getStride  ();
1694    for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1695    {
1696      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1697      {
1698        piDes[ uiX ] = piSrc[ uiX ];
1699      }
1700    }
1701    if( !bLumaOnly )
1702    {
1703      uiWidth   >>= 1;
1704      uiHeight  >>= 1;
1705      piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr  ( uiAbsPartIdx );
1706      uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getCStride ();
1707      piDes       = pcCU->getPic()->getPicYuvRec()->getCbAddr ( pcCU->getAddr(), uiZOrder );
1708      uiDesStride = pcCU->getPic()->getPicYuvRec()->getCStride();
1709      for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1710      {
1711        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1712        {
1713          piDes[ uiX ] = piSrc[ uiX ];
1714        }
1715      }
1716      piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr  ( uiAbsPartIdx );
1717      piDes       = pcCU->getPic()->getPicYuvRec()->getCrAddr ( pcCU->getAddr(), uiZOrder );
1718      for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1719      {
1720        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1721        {
1722          piDes[ uiX ] = piSrc[ uiX ];
1723        }
1724      }
1725    }
1726  }
1727  ruiDistY += uiSingleDistY;
1728  ruiDistC += uiSingleDistC;
1729  dRDCost  += dSingleCost;
1730}
1731
1732
1733Void
1734TEncSearch::xSetIntraResultQT( TComDataCU* pcCU,
1735                              UInt        uiTrDepth,
1736                              UInt        uiAbsPartIdx,
1737                              Bool        bLumaOnly,
1738                              TComYuv*    pcRecoYuv )
1739{
1740  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
1741  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1742  if(  uiTrMode == uiTrDepth )
1743  {
1744    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1745    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1746   
1747    Bool bSkipChroma  = false;
1748    Bool bChromaSame  = false;
1749    if( !bLumaOnly && uiLog2TrSize == 2 )
1750    {
1751      assert( uiTrDepth > 0 );
1752      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
1753      bSkipChroma  = ( ( uiAbsPartIdx % uiQPDiv ) != 0 );
1754      bChromaSame  = true;
1755    }
1756   
1757    //===== copy transform coefficients =====
1758    UInt uiNumCoeffY    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
1759    UInt uiNumCoeffIncY = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
1760    TCoeff* pcCoeffSrcY = m_ppcQTTempCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1761    TCoeff* pcCoeffDstY = pcCU->getCoeffY ()              + ( uiNumCoeffIncY * uiAbsPartIdx );
1762    ::memcpy( pcCoeffDstY, pcCoeffSrcY, sizeof( TCoeff ) * uiNumCoeffY );
1763#if ADAPTIVE_QP_SELECTION
1764    Int* pcArlCoeffSrcY = m_ppcQTTempArlCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1765    Int* pcArlCoeffDstY = pcCU->getArlCoeffY ()              + ( uiNumCoeffIncY * uiAbsPartIdx );
1766    ::memcpy( pcArlCoeffDstY, pcArlCoeffSrcY, sizeof( Int ) * uiNumCoeffY );
1767#endif
1768    if( !bLumaOnly && !bSkipChroma )
1769    {
1770      UInt uiNumCoeffC    = ( bChromaSame ? uiNumCoeffY    : uiNumCoeffY    >> 2 );
1771      UInt uiNumCoeffIncC = uiNumCoeffIncY >> 2;
1772      TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1773      TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1774      TCoeff* pcCoeffDstU = pcCU->getCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1775      TCoeff* pcCoeffDstV = pcCU->getCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1776      ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
1777      ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
1778#if ADAPTIVE_QP_SELECTION
1779      Int* pcArlCoeffSrcU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1780      Int* pcArlCoeffSrcV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1781      Int* pcArlCoeffDstU = pcCU->getArlCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1782      Int* pcArlCoeffDstV = pcCU->getArlCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1783      ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
1784      ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
1785#endif
1786    }
1787   
1788    //===== copy reconstruction =====
1789    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartLuma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSize, 1 << uiLog2TrSize );
1790    if( !bLumaOnly && !bSkipChroma )
1791    {
1792      UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
1793      m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
1794    }
1795  }
1796  else
1797  {
1798    UInt uiNumQPart  = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1799    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
1800    {
1801      xSetIntraResultQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiNumQPart, bLumaOnly, pcRecoYuv );
1802    }
1803  }
1804}
1805
1806Void
1807TEncSearch::xStoreIntraResultQT( TComDataCU* pcCU,
1808                                UInt        uiTrDepth,
1809                                UInt        uiAbsPartIdx,
1810                                Bool        bLumaOnly )
1811{
1812  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
1813  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1814  assert(  uiTrMode == uiTrDepth );
1815  UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1816  UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1817
1818  Bool bSkipChroma  = false;
1819  Bool bChromaSame  = false;
1820  if( !bLumaOnly && uiLog2TrSize == 2 )
1821  {
1822    assert( uiTrDepth > 0 );
1823    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
1824    bSkipChroma  = ( ( uiAbsPartIdx % uiQPDiv ) != 0 );
1825    bChromaSame  = true;
1826  }
1827
1828  //===== copy transform coefficients =====
1829  UInt uiNumCoeffY    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
1830  UInt uiNumCoeffIncY = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
1831  TCoeff* pcCoeffSrcY = m_ppcQTTempCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1832  TCoeff* pcCoeffDstY = m_pcQTTempTUCoeffY;
1833
1834  ::memcpy( pcCoeffDstY, pcCoeffSrcY, sizeof( TCoeff ) * uiNumCoeffY );
1835#if ADAPTIVE_QP_SELECTION
1836  Int* pcArlCoeffSrcY = m_ppcQTTempArlCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1837  Int* pcArlCoeffDstY = m_ppcQTTempTUArlCoeffY;
1838  ::memcpy( pcArlCoeffDstY, pcArlCoeffSrcY, sizeof( Int ) * uiNumCoeffY );
1839#endif
1840  if( !bLumaOnly && !bSkipChroma )
1841  {
1842    UInt uiNumCoeffC    = ( bChromaSame ? uiNumCoeffY    : uiNumCoeffY    >> 2 );
1843    UInt uiNumCoeffIncC = uiNumCoeffIncY >> 2;
1844    TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1845    TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1846    TCoeff* pcCoeffDstU = m_pcQTTempTUCoeffCb;
1847    TCoeff* pcCoeffDstV = m_pcQTTempTUCoeffCr;
1848    ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
1849    ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
1850#if ADAPTIVE_QP_SELECTION
1851    Int* pcArlCoeffSrcU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1852    Int* pcArlCoeffSrcV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1853    Int* pcArlCoeffDstU = m_ppcQTTempTUArlCoeffCb;
1854    Int* pcArlCoeffDstV = m_ppcQTTempTUArlCoeffCr;
1855    ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
1856    ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
1857#endif
1858  }
1859
1860  //===== copy reconstruction =====
1861  m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartLuma( &m_pcQTTempTransformSkipTComYuv, uiAbsPartIdx, 1 << uiLog2TrSize, 1 << uiLog2TrSize );
1862
1863  if( !bLumaOnly && !bSkipChroma )
1864  {
1865    UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
1866    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma( &m_pcQTTempTransformSkipTComYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
1867  }
1868}
1869
1870Void
1871TEncSearch::xLoadIntraResultQT( TComDataCU* pcCU,
1872                               UInt        uiTrDepth,
1873                               UInt        uiAbsPartIdx,
1874                               Bool        bLumaOnly )
1875{
1876  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
1877  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1878  assert(  uiTrMode == uiTrDepth );
1879  UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1880  UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1881
1882  Bool bSkipChroma  = false;
1883  Bool bChromaSame  = false;
1884  if( !bLumaOnly && uiLog2TrSize == 2 )
1885  {
1886    assert( uiTrDepth > 0 );
1887    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
1888    bSkipChroma  = ( ( uiAbsPartIdx % uiQPDiv ) != 0 );
1889    bChromaSame  = true;
1890  }
1891
1892  //===== copy transform coefficients =====
1893  UInt uiNumCoeffY    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
1894  UInt uiNumCoeffIncY = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
1895  TCoeff* pcCoeffDstY = m_ppcQTTempCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1896  TCoeff* pcCoeffSrcY = m_pcQTTempTUCoeffY;
1897
1898  ::memcpy( pcCoeffDstY, pcCoeffSrcY, sizeof( TCoeff ) * uiNumCoeffY );
1899#if ADAPTIVE_QP_SELECTION
1900  Int* pcArlCoeffDstY = m_ppcQTTempArlCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1901  Int* pcArlCoeffSrcY = m_ppcQTTempTUArlCoeffY;
1902  ::memcpy( pcArlCoeffDstY, pcArlCoeffSrcY, sizeof( Int ) * uiNumCoeffY );
1903#endif
1904  if( !bLumaOnly && !bSkipChroma )
1905  {
1906    UInt uiNumCoeffC    = ( bChromaSame ? uiNumCoeffY    : uiNumCoeffY    >> 2 );
1907    UInt uiNumCoeffIncC = uiNumCoeffIncY >> 2;
1908    TCoeff* pcCoeffDstU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1909    TCoeff* pcCoeffDstV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1910    TCoeff* pcCoeffSrcU = m_pcQTTempTUCoeffCb;
1911    TCoeff* pcCoeffSrcV = m_pcQTTempTUCoeffCr;
1912    ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
1913    ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
1914#if ADAPTIVE_QP_SELECTION
1915    Int* pcArlCoeffDstU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1916    Int* pcArlCoeffDstV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1917    Int* pcArlCoeffSrcU = m_ppcQTTempTUArlCoeffCb;
1918    Int* pcArlCoeffSrcV = m_ppcQTTempTUArlCoeffCr;
1919    ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
1920    ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
1921#endif
1922  }
1923
1924  //===== copy reconstruction =====
1925  m_pcQTTempTransformSkipTComYuv.copyPartToPartLuma( &m_pcQTTempTComYuv[ uiQTLayer ] , uiAbsPartIdx, 1 << uiLog2TrSize, 1 << uiLog2TrSize );
1926
1927  if( !bLumaOnly && !bSkipChroma )
1928  {
1929    UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
1930    m_pcQTTempTransformSkipTComYuv.copyPartToPartChroma( &m_pcQTTempTComYuv[ uiQTLayer ], uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
1931  }
1932
1933  UInt    uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1934  Pel*    piRecIPred        = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
1935  UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getStride  ();
1936  Pel*    piRecQt           = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
1937  UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
1938  UInt    uiWidth           = pcCU     ->getWidth   ( 0 ) >> uiTrDepth;
1939  UInt    uiHeight          = pcCU     ->getHeight  ( 0 ) >> uiTrDepth;
1940  Pel* pRecQt     = piRecQt;
1941  Pel* pRecIPred  = piRecIPred;
1942  for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1943  {
1944    for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1945    {
1946      pRecIPred[ uiX ] = pRecQt   [ uiX ];
1947    }
1948    pRecQt    += uiRecQtStride;
1949    pRecIPred += uiRecIPredStride;
1950  }
1951
1952  if( !bLumaOnly && !bSkipChroma )
1953  {
1954    piRecIPred = pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder );
1955    piRecQt    = m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr( uiAbsPartIdx );
1956    pRecQt     = piRecQt;
1957    pRecIPred  = piRecIPred;
1958    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1959    {
1960      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1961      {
1962        pRecIPred[ uiX ] = pRecQt[ uiX ];
1963      }
1964      pRecQt    += uiRecQtStride;
1965      pRecIPred += uiRecIPredStride;
1966    }
1967
1968    piRecIPred = pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder );
1969    piRecQt    = m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr( uiAbsPartIdx );
1970    pRecQt     = piRecQt;
1971    pRecIPred  = piRecIPred;
1972    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1973    {
1974      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1975      {
1976        pRecIPred[ uiX ] = pRecQt[ uiX ];
1977      }
1978      pRecQt    += uiRecQtStride;
1979      pRecIPred += uiRecIPredStride;
1980    }
1981  }
1982}
1983
1984Void
1985TEncSearch::xStoreIntraResultChromaQT( TComDataCU* pcCU,
1986                                      UInt        uiTrDepth,
1987                                      UInt        uiAbsPartIdx,
1988                                      UInt        stateU0V1Both2 )
1989{
1990  UInt uiFullDepth = pcCU->getDepth(0) + uiTrDepth;
1991  UInt uiTrMode    = pcCU->getTransformIdx( uiAbsPartIdx );
1992  if(  uiTrMode == uiTrDepth )
1993  {
1994    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1995    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1996
1997    Bool bChromaSame = false;
1998    if( uiLog2TrSize == 2 )
1999    {
2000      assert( uiTrDepth > 0 );
2001      uiTrDepth --;
2002      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth) << 1 );
2003      if( ( uiAbsPartIdx % uiQPDiv ) != 0 )
2004      {
2005        return;
2006      }
2007      bChromaSame = true;
2008    }
2009
2010    //===== copy transform coefficients =====
2011    UInt uiNumCoeffC    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
2012    if( !bChromaSame )
2013    {
2014      uiNumCoeffC     >>= 2;
2015    }
2016    UInt uiNumCoeffIncC = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) + 2 );
2017    if(stateU0V1Both2 == 0 || stateU0V1Both2 == 2)
2018    {
2019      TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2020      TCoeff* pcCoeffDstU = m_pcQTTempTUCoeffCb;
2021      ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
2022
2023#if ADAPTIVE_QP_SELECTION   
2024      Int* pcArlCoeffSrcU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2025      Int* pcArlCoeffDstU = m_ppcQTTempTUArlCoeffCb;
2026      ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
2027#endif
2028    }
2029    if(stateU0V1Both2 == 1 || stateU0V1Both2 == 2)
2030    {
2031      TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2032      TCoeff* pcCoeffDstV = m_pcQTTempTUCoeffCr;
2033      ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
2034#if ADAPTIVE_QP_SELECTION   
2035      Int* pcArlCoeffSrcV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2036      Int* pcArlCoeffDstV = m_ppcQTTempTUArlCoeffCr;
2037      ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
2038#endif
2039    }
2040
2041    //===== copy reconstruction =====
2042    UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
2043    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma(&m_pcQTTempTransformSkipTComYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma, stateU0V1Both2 );
2044  }
2045}
2046
2047
2048Void
2049TEncSearch::xLoadIntraResultChromaQT( TComDataCU* pcCU,
2050                                     UInt        uiTrDepth,
2051                                     UInt        uiAbsPartIdx,
2052                                     UInt        stateU0V1Both2 )
2053{
2054  UInt uiFullDepth = pcCU->getDepth(0) + uiTrDepth;
2055  UInt uiTrMode    = pcCU->getTransformIdx( uiAbsPartIdx );
2056  if(  uiTrMode == uiTrDepth )
2057  {
2058    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
2059    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
2060
2061    Bool bChromaSame = false;
2062    if( uiLog2TrSize == 2 )
2063    {
2064      assert( uiTrDepth > 0 );
2065      uiTrDepth --;
2066      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
2067      if( ( uiAbsPartIdx % uiQPDiv ) != 0 )
2068      {
2069        return;
2070      }
2071      bChromaSame = true;
2072    }
2073
2074    //===== copy transform coefficients =====
2075    UInt uiNumCoeffC = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
2076    if( !bChromaSame )
2077    {
2078      uiNumCoeffC >>= 2;
2079    }
2080    UInt uiNumCoeffIncC = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) + 2 );
2081
2082    if(stateU0V1Both2 ==0 || stateU0V1Both2 == 2)
2083    {
2084      TCoeff* pcCoeffDstU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2085      TCoeff* pcCoeffSrcU = m_pcQTTempTUCoeffCb;
2086      ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
2087#if ADAPTIVE_QP_SELECTION   
2088      Int* pcArlCoeffDstU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2089      Int* pcArlCoeffSrcU = m_ppcQTTempTUArlCoeffCb;
2090      ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
2091#endif
2092    }
2093    if(stateU0V1Both2 ==1 || stateU0V1Both2 == 2)
2094    {
2095      TCoeff* pcCoeffDstV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2096      TCoeff* pcCoeffSrcV = m_pcQTTempTUCoeffCr;
2097      ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
2098#if ADAPTIVE_QP_SELECTION   
2099      Int* pcArlCoeffDstV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2100      Int* pcArlCoeffSrcV = m_ppcQTTempTUArlCoeffCr;       
2101      ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
2102#endif
2103    }
2104
2105    //===== copy reconstruction =====
2106    UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
2107    m_pcQTTempTransformSkipTComYuv.copyPartToPartChroma( &m_pcQTTempTComYuv[ uiQTLayer ], uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma, stateU0V1Both2);
2108
2109    UInt    uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
2110    UInt    uiWidth           = pcCU->getWidth   ( 0 ) >> (uiTrDepth + 1);
2111    UInt    uiHeight          = pcCU->getHeight  ( 0 ) >> (uiTrDepth + 1);
2112    UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getCStride  ();
2113    UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getCStride  ();
2114
2115    if(stateU0V1Both2 ==0 || stateU0V1Both2 == 2)
2116    {
2117      Pel* piRecIPred = pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder );
2118      Pel* piRecQt    = m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr( uiAbsPartIdx );
2119      Pel* pRecQt     = piRecQt;
2120      Pel* pRecIPred  = piRecIPred;
2121      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
2122      {
2123        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
2124        {
2125          pRecIPred[ uiX ] = pRecQt[ uiX ];
2126        }
2127        pRecQt    += uiRecQtStride;
2128        pRecIPred += uiRecIPredStride;
2129      }
2130    }
2131    if(stateU0V1Both2 == 1 || stateU0V1Both2 == 2)
2132    {
2133      Pel* piRecIPred = pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder );
2134      Pel* piRecQt    = m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr( uiAbsPartIdx );
2135      Pel* pRecQt     = piRecQt;
2136      Pel* pRecIPred  = piRecIPred;
2137      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
2138      {
2139        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
2140        {
2141          pRecIPred[ uiX ] = pRecQt[ uiX ];
2142        }
2143        pRecQt    += uiRecQtStride;
2144        pRecIPred += uiRecIPredStride;
2145      }
2146    }
2147  }
2148}
2149
2150Void
2151TEncSearch::xRecurIntraChromaCodingQT( TComDataCU*  pcCU, 
2152                                      UInt         uiTrDepth,
2153                                      UInt         uiAbsPartIdx, 
2154                                      TComYuv*     pcOrgYuv, 
2155                                      TComYuv*     pcPredYuv, 
2156                                      TComYuv*     pcResiYuv, 
2157                                      UInt&        ruiDist )
2158{
2159  UInt uiFullDepth = pcCU->getDepth( 0 ) +  uiTrDepth;
2160  UInt uiTrMode    = pcCU->getTransformIdx( uiAbsPartIdx );
2161  if(  uiTrMode == uiTrDepth )
2162  {
2163    Bool checkTransformSkip = pcCU->getSlice()->getPPS()->getUseTransformSkip();
2164    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
2165
2166    UInt actualTrDepth = uiTrDepth;
2167    if( uiLog2TrSize == 2 )
2168    {
2169      assert( uiTrDepth > 0 );
2170      actualTrDepth--;
2171      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + actualTrDepth) << 1 );
2172      Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
2173      if( !bFirstQ )
2174      {
2175        return;
2176      }
2177    }
2178
2179    checkTransformSkip &= (uiLog2TrSize <= 3);
2180    if ( m_pcEncCfg->getUseTransformSkipFast() )
2181    {
2182      checkTransformSkip &= (uiLog2TrSize < 3);
2183      if (checkTransformSkip)
2184      {
2185        Int nbLumaSkip = 0;
2186        for(UInt absPartIdxSub = uiAbsPartIdx; absPartIdxSub < uiAbsPartIdx + 4; absPartIdxSub ++)
2187        {
2188          nbLumaSkip += pcCU->getTransformSkip(absPartIdxSub, TEXT_LUMA);
2189        }
2190        checkTransformSkip &= (nbLumaSkip > 0);
2191      }
2192    }
2193
2194    if(checkTransformSkip)
2195    {
2196        //use RDO to decide whether Cr/Cb takes TS
2197        if( m_bUseSBACRD )
2198        {
2199          m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[uiFullDepth][CI_QT_TRAFO_ROOT] );
2200        }
2201
2202        for(Int chromaId = 0; chromaId < 2; chromaId ++)
2203        {
2204          Double  dSingleCost    = MAX_DOUBLE;
2205          Int     bestModeId     = 0;
2206          UInt    singleDistC    = 0;
2207          UInt    singleCbfC     = 0;
2208          UInt    singleDistCTmp = 0;
2209          Double  singleCostTmp  = 0;
2210          UInt    singleCbfCTmp  = 0;
2211
2212          Int     default0Save1Load2 = 0;
2213          Int     firstCheckId       = 0;
2214
2215          for(Int chromaModeId = firstCheckId; chromaModeId < 2; chromaModeId ++)
2216          {
2217            pcCU->setTransformSkipSubParts ( chromaModeId, (TextType)(chromaId + 2), uiAbsPartIdx, pcCU->getDepth( 0 ) +  actualTrDepth); 
2218            if(chromaModeId == firstCheckId)
2219            {
2220              default0Save1Load2 = 1;
2221            }
2222            else
2223            {
2224              default0Save1Load2 = 2;
2225            }
2226            singleDistCTmp = 0;
2227            xIntraCodingChromaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, singleDistCTmp, chromaId ,default0Save1Load2);
2228            singleCbfCTmp = pcCU->getCbf( uiAbsPartIdx, (TextType)(chromaId + 2), uiTrDepth);
2229           
2230            if(chromaModeId == 1 && singleCbfCTmp == 0)
2231            {
2232              //In order not to code TS flag when cbf is zero, the case for TS with cbf being zero is forbidden.
2233              singleCostTmp = MAX_DOUBLE;
2234            }
2235            else
2236            {
2237              UInt bitsTmp = xGetIntraBitsQTChroma( pcCU,uiTrDepth, uiAbsPartIdx,chromaId + 2, false );
2238              singleCostTmp  = m_pcRdCost->calcRdCost( bitsTmp, singleDistCTmp);
2239            }
2240
2241            if(singleCostTmp < dSingleCost)
2242            {
2243              dSingleCost = singleCostTmp;
2244              singleDistC = singleDistCTmp;
2245              bestModeId  = chromaModeId;
2246              singleCbfC  = singleCbfCTmp;
2247
2248              if(bestModeId == firstCheckId)
2249              {
2250                xStoreIntraResultChromaQT(pcCU, uiTrDepth, uiAbsPartIdx,chromaId);
2251                if( m_bUseSBACRD) 
2252                {
2253                  m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
2254                }
2255              }
2256            }
2257            if(chromaModeId == firstCheckId)
2258            {
2259              m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
2260            }
2261          }
2262
2263          if(bestModeId == firstCheckId)
2264          {
2265            xLoadIntraResultChromaQT(pcCU, uiTrDepth, uiAbsPartIdx,chromaId);
2266            pcCU->setCbfSubParts ( singleCbfC << uiTrDepth, (TextType)(chromaId + 2), uiAbsPartIdx, pcCU->getDepth(0) + actualTrDepth );
2267            if(m_bUseSBACRD)
2268            {
2269              m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiFullDepth ][ CI_TEMP_BEST ] );
2270            } 
2271          }
2272          pcCU ->setTransformSkipSubParts( bestModeId, (TextType)(chromaId + 2), uiAbsPartIdx, pcCU->getDepth( 0 ) +  actualTrDepth ); 
2273          ruiDist += singleDistC;
2274
2275          if(chromaId == 0)
2276          {
2277            if( m_bUseSBACRD )
2278            {
2279              m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[uiFullDepth][CI_QT_TRAFO_ROOT] );
2280            }
2281          }
2282        }
2283    }
2284    else
2285    {
2286      pcCU ->setTransformSkipSubParts( 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth( 0 ) +  actualTrDepth ); 
2287      pcCU ->setTransformSkipSubParts( 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth( 0 ) +  actualTrDepth ); 
2288      xIntraCodingChromaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist, 0 ); 
2289      xIntraCodingChromaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist, 1 ); 
2290    }
2291  }
2292  else
2293  {
2294    UInt uiSplitCbfU     = 0;
2295    UInt uiSplitCbfV     = 0;
2296    UInt uiQPartsDiv     = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
2297    UInt uiAbsPartIdxSub = uiAbsPartIdx;
2298    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiAbsPartIdxSub += uiQPartsDiv )
2299    {
2300      xRecurIntraChromaCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist );
2301      uiSplitCbfU |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_U, uiTrDepth + 1 );
2302      uiSplitCbfV |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_V, uiTrDepth + 1 );
2303    }
2304    for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
2305    {
2306      pcCU->getCbf( TEXT_CHROMA_U )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfU << uiTrDepth );
2307      pcCU->getCbf( TEXT_CHROMA_V )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfV << uiTrDepth );
2308    }
2309  }
2310}
2311
2312Void
2313TEncSearch::xSetIntraResultChromaQT( TComDataCU* pcCU,
2314                                    UInt        uiTrDepth,
2315                                    UInt        uiAbsPartIdx,
2316                                    TComYuv*    pcRecoYuv )
2317{
2318  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
2319  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
2320  if(  uiTrMode == uiTrDepth )
2321  {
2322    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
2323    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
2324   
2325    Bool bChromaSame  = false;
2326    if( uiLog2TrSize == 2 )
2327    {
2328      assert( uiTrDepth > 0 );
2329      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
2330      if( ( uiAbsPartIdx % uiQPDiv ) != 0 )
2331      {
2332        return;
2333      }
2334      bChromaSame     = true;
2335    }
2336   
2337    //===== copy transform coefficients =====
2338    UInt uiNumCoeffC    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
2339    if( !bChromaSame )
2340    {
2341      uiNumCoeffC     >>= 2;
2342    }
2343    UInt uiNumCoeffIncC = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) + 2 );
2344    TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2345    TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2346    TCoeff* pcCoeffDstU = pcCU->getCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
2347    TCoeff* pcCoeffDstV = pcCU->getCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
2348    ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
2349    ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
2350#if ADAPTIVE_QP_SELECTION   
2351    Int* pcArlCoeffSrcU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2352    Int* pcArlCoeffSrcV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
2353    Int* pcArlCoeffDstU = pcCU->getArlCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
2354    Int* pcArlCoeffDstV = pcCU->getArlCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
2355    ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
2356    ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
2357#endif
2358   
2359    //===== copy reconstruction =====
2360    UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
2361    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
2362  }
2363  else
2364  {
2365    UInt uiNumQPart  = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
2366    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
2367    {
2368      xSetIntraResultChromaQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiNumQPart, pcRecoYuv );
2369    }
2370  }
2371}
2372
2373
2374Void
2375TEncSearch::preestChromaPredMode( TComDataCU* pcCU, 
2376                                 TComYuv*    pcOrgYuv, 
2377                                 TComYuv*    pcPredYuv )
2378{
2379  UInt  uiWidth     = pcCU->getWidth ( 0 ) >> 1;
2380  UInt  uiHeight    = pcCU->getHeight( 0 ) >> 1;
2381  UInt  uiStride    = pcOrgYuv ->getCStride();
2382  Pel*  piOrgU      = pcOrgYuv ->getCbAddr ( 0 );
2383  Pel*  piOrgV      = pcOrgYuv ->getCrAddr ( 0 );
2384  Pel*  piPredU     = pcPredYuv->getCbAddr ( 0 );
2385  Pel*  piPredV     = pcPredYuv->getCrAddr ( 0 );
2386 
2387  //===== init pattern =====
2388  Bool  bAboveAvail = false;
2389  Bool  bLeftAvail  = false;
2390  pcCU->getPattern()->initPattern         ( pcCU, 0, 0 );
2391  pcCU->getPattern()->initAdiPatternChroma( pcCU, 0, 0, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
2392  Int*  pPatChromaU = pcCU->getPattern()->getAdiCbBuf( uiWidth, uiHeight, m_piYuvExt );
2393  Int*  pPatChromaV = pcCU->getPattern()->getAdiCrBuf( uiWidth, uiHeight, m_piYuvExt );
2394 
2395  //===== get best prediction modes (using SAD) =====
2396  UInt  uiMinMode   = 0;
2397  UInt  uiMaxMode   = 4;
2398  UInt  uiBestMode  = MAX_UINT;
2399  UInt  uiMinSAD    = MAX_UINT;
2400  for( UInt uiMode  = uiMinMode; uiMode < uiMaxMode; uiMode++ )
2401  {
2402    //--- get prediction ---
2403    predIntraChromaAng( pPatChromaU, uiMode, piPredU, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail );
2404    predIntraChromaAng( pPatChromaV, uiMode, piPredV, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail );
2405   
2406    //--- get SAD ---
2407    UInt  uiSAD  = m_pcRdCost->calcHAD(g_bitDepthC, piOrgU, uiStride, piPredU, uiStride, uiWidth, uiHeight );
2408    uiSAD       += m_pcRdCost->calcHAD(g_bitDepthC, piOrgV, uiStride, piPredV, uiStride, uiWidth, uiHeight );
2409    //--- check ---
2410    if( uiSAD < uiMinSAD )
2411    {
2412      uiMinSAD   = uiSAD;
2413      uiBestMode = uiMode;
2414    }
2415  }
2416 
2417  //===== set chroma pred mode =====
2418  pcCU->setChromIntraDirSubParts( uiBestMode, 0, pcCU->getDepth( 0 ) );
2419}
2420
2421Void
2422TEncSearch::estIntraPredQT( TComDataCU* pcCU, 
2423                           TComYuv*    pcOrgYuv, 
2424                           TComYuv*    pcPredYuv, 
2425                           TComYuv*    pcResiYuv, 
2426                           TComYuv*    pcRecoYuv,
2427                           UInt&       ruiDistC,
2428                           Bool        bLumaOnly )
2429{
2430  UInt    uiDepth        = pcCU->getDepth(0);
2431  UInt    uiNumPU        = pcCU->getNumPartInter();
2432  UInt    uiInitTrDepth  = pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1;
2433  UInt    uiWidth        = pcCU->getWidth (0) >> uiInitTrDepth;
2434  UInt    uiHeight       = pcCU->getHeight(0) >> uiInitTrDepth;
2435  UInt    uiQNumParts    = pcCU->getTotalNumPart() >> 2;
2436  UInt    uiWidthBit     = pcCU->getIntraSizeIdx(0);
2437  UInt    uiOverallDistY = 0;
2438  UInt    uiOverallDistC = 0;
2439  UInt    CandNum;
2440  Double  CandCostList[ FAST_UDI_MAX_RDMODE_NUM ];
2441 
2442  //===== set QP and clear Cbf =====
2443  if ( pcCU->getSlice()->getPPS()->getUseDQP() == true)
2444  {
2445    pcCU->setQPSubParts( pcCU->getQP(0), 0, uiDepth );
2446  }
2447  else
2448  {
2449    pcCU->setQPSubParts( pcCU->getSlice()->getSliceQp(), 0, uiDepth );
2450  }
2451 
2452  //===== loop over partitions =====
2453  UInt uiPartOffset = 0;
2454  for( UInt uiPU = 0; uiPU < uiNumPU; uiPU++, uiPartOffset += uiQNumParts )
2455  {
2456    //===== init pattern for luma prediction =====
2457    Bool bAboveAvail = false;
2458    Bool bLeftAvail  = false;
2459    pcCU->getPattern()->initPattern   ( pcCU, uiInitTrDepth, uiPartOffset );
2460    pcCU->getPattern()->initAdiPattern( pcCU, uiPartOffset, uiInitTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
2461   
2462    //===== determine set of modes to be tested (using prediction signal only) =====
2463    Int numModesAvailable     = 35; //total number of Intra modes
2464    Pel* piOrg         = pcOrgYuv ->getLumaAddr( uiPU, uiWidth );
2465    Pel* piPred        = pcPredYuv->getLumaAddr( uiPU, uiWidth );
2466    UInt uiStride      = pcPredYuv->getStride();
2467    UInt uiRdModeList[FAST_UDI_MAX_RDMODE_NUM];
2468    Int numModesForFullRD = g_aucIntraModeNumFast[ uiWidthBit ];
2469   
2470    Bool doFastSearch = (numModesForFullRD != numModesAvailable);
2471    if (doFastSearch)
2472    {
2473      assert(numModesForFullRD < numModesAvailable);
2474#if FAST_INTRA_SHVC
2475      Int   uiPreds[3] = {-1, -1, -1};
2476      Int   iMode = -1;
2477      Bool  skipFastHAD = false;
2478      Int numCand = pcCU->getIntraDirLumaPredictor( uiPartOffset, uiPreds, &iMode );
2479
2480      if ( m_pcEncCfg->getUseFastIntraScalable() )
2481      {
2482        if( pcCU->getLayerId() > 0 )
2483        {
2484          numModesAvailable = pcCU->reduceSetOfIntraModes(uiPartOffset, uiPreds, iMode );
2485          if( numModesForFullRD > numModesAvailable ) //fast HAD can be skipped
2486          {
2487            skipFastHAD = true;
2488            numModesForFullRD = numModesAvailable;
2489            for( Int i=0; i < numModesForFullRD; i++ ) 
2490              uiRdModeList[ i ] = g_reducedSetIntraModes[ i ];
2491          }
2492        }
2493      }
2494#endif
2495
2496      for( Int i=0; i < numModesForFullRD; i++ ) 
2497      {
2498        CandCostList[ i ] = MAX_DOUBLE;
2499      }
2500      CandNum = 0;
2501     
2502      for( Int modeIdx = 0; modeIdx < numModesAvailable; modeIdx++ )
2503      {
2504        UInt uiMode = modeIdx;
2505#if FAST_INTRA_SHVC
2506        if ( m_pcEncCfg->getUseFastIntraScalable() )
2507        {
2508          if( skipFastHAD )//indicates that fast HAD can be skipped
2509            break;
2510          uiMode = ( iMode==0 ) ? g_reducedSetIntraModes[modeIdx] : uiMode; //(iMode=0) indicates reduced set of modes
2511        }
2512#endif
2513
2514        predIntraLumaAng( pcCU->getPattern(), uiMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail );
2515       
2516        // use hadamard transform here
2517        UInt uiSad = m_pcRdCost->calcHAD(g_bitDepthY, piOrg, uiStride, piPred, uiStride, uiWidth, uiHeight );
2518       
2519        UInt   iModeBits = xModeBitsIntra( pcCU, uiMode, uiPU, uiPartOffset, uiDepth, uiInitTrDepth );
2520        Double cost      = (Double)uiSad + (Double)iModeBits * m_pcRdCost->getSqrtLambda();
2521       
2522        CandNum += xUpdateCandList( uiMode, cost, numModesForFullRD, uiRdModeList, CandCostList );
2523      }
2524   
2525#if FAST_UDI_USE_MPM
2526#if FAST_INTRA_SHVC == 0
2527      Int uiPreds[3] = {-1, -1, -1};
2528      Int iMode = -1;
2529      Int numCand = pcCU->getIntraDirLumaPredictor( uiPartOffset, uiPreds, &iMode );
2530#endif
2531      if( iMode >= 0 )
2532      {
2533        numCand = iMode;
2534      }
2535     
2536      for( Int j=0; j < numCand; j++)
2537
2538      {
2539        Bool mostProbableModeIncluded = false;
2540        Int mostProbableMode = uiPreds[j];
2541       
2542        for( Int i=0; i < numModesForFullRD; i++)
2543        {
2544          mostProbableModeIncluded |= (mostProbableMode == uiRdModeList[i]);
2545        }
2546        if (!mostProbableModeIncluded)
2547        {
2548          uiRdModeList[numModesForFullRD++] = mostProbableMode;
2549        }
2550      }
2551#endif // FAST_UDI_USE_MPM
2552    }
2553    else
2554    {
2555      for( Int i=0; i < numModesForFullRD; i++)
2556      {
2557        uiRdModeList[i] = i;
2558      }
2559    }
2560   
2561    //===== check modes (using r-d costs) =====
2562#if HHI_RQT_INTRA_SPEEDUP_MOD
2563    UInt   uiSecondBestMode  = MAX_UINT;
2564    Double dSecondBestPUCost = MAX_DOUBLE;
2565#endif
2566   
2567    UInt    uiBestPUMode  = 0;
2568    UInt    uiBestPUDistY = 0;
2569    UInt    uiBestPUDistC = 0;
2570    Double  dBestPUCost   = MAX_DOUBLE;
2571    for( UInt uiMode = 0; uiMode < numModesForFullRD; uiMode++ )
2572    {
2573      // set luma prediction mode
2574      UInt uiOrgMode = uiRdModeList[uiMode];
2575     
2576      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2577     
2578      // set context models
2579      if( m_bUseSBACRD )
2580      {
2581        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2582      }
2583     
2584      // determine residual for partition
2585      UInt   uiPUDistY = 0;
2586      UInt   uiPUDistC = 0;
2587      Double dPUCost   = 0.0;
2588#if HHI_RQT_INTRA_SPEEDUP
2589      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );
2590#else
2591      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
2592#endif
2593     
2594      // check r-d cost
2595      if( dPUCost < dBestPUCost )
2596      {
2597#if HHI_RQT_INTRA_SPEEDUP_MOD
2598        uiSecondBestMode  = uiBestPUMode;
2599        dSecondBestPUCost = dBestPUCost;
2600#endif
2601        uiBestPUMode  = uiOrgMode;
2602        uiBestPUDistY = uiPUDistY;
2603        uiBestPUDistC = uiPUDistC;
2604        dBestPUCost   = dPUCost;
2605       
2606        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2607       
2608        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2609        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2610        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2611        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2612        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2613        ::memcpy( m_puhQTTempTransformSkipFlag[0], pcCU->getTransformSkip(TEXT_LUMA)     + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2614        ::memcpy( m_puhQTTempTransformSkipFlag[1], pcCU->getTransformSkip(TEXT_CHROMA_U) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2615        ::memcpy( m_puhQTTempTransformSkipFlag[2], pcCU->getTransformSkip(TEXT_CHROMA_V) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2616      }
2617#if HHI_RQT_INTRA_SPEEDUP_MOD
2618      else if( dPUCost < dSecondBestPUCost )
2619      {
2620        uiSecondBestMode  = uiOrgMode;
2621        dSecondBestPUCost = dPUCost;
2622      }
2623#endif
2624    } // Mode loop
2625   
2626#if HHI_RQT_INTRA_SPEEDUP
2627#if HHI_RQT_INTRA_SPEEDUP_MOD
2628    for( UInt ui =0; ui < 2; ++ui )
2629#endif
2630    {
2631#if HHI_RQT_INTRA_SPEEDUP_MOD
2632      UInt uiOrgMode   = ui ? uiSecondBestMode  : uiBestPUMode;
2633      if( uiOrgMode == MAX_UINT )
2634      {
2635        break;
2636      }
2637#else
2638      UInt uiOrgMode = uiBestPUMode;
2639#endif
2640     
2641      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2642     
2643      // set context models
2644      if( m_bUseSBACRD )
2645      {
2646        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2647      }
2648     
2649      // determine residual for partition
2650      UInt   uiPUDistY = 0;
2651      UInt   uiPUDistC = 0;
2652      Double dPUCost   = 0.0;
2653      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, false, dPUCost );
2654     
2655      // check r-d cost
2656      if( dPUCost < dBestPUCost )
2657      {
2658        uiBestPUMode  = uiOrgMode;
2659        uiBestPUDistY = uiPUDistY;
2660        uiBestPUDistC = uiPUDistC;
2661        dBestPUCost   = dPUCost;
2662       
2663        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2664       
2665        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2666        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2667        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2668        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2669        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2670        ::memcpy( m_puhQTTempTransformSkipFlag[0], pcCU->getTransformSkip(TEXT_LUMA)     + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2671        ::memcpy( m_puhQTTempTransformSkipFlag[1], pcCU->getTransformSkip(TEXT_CHROMA_U) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2672        ::memcpy( m_puhQTTempTransformSkipFlag[2], pcCU->getTransformSkip(TEXT_CHROMA_V) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2673      }
2674    } // Mode loop
2675#endif
2676   
2677    //--- update overall distortion ---
2678    uiOverallDistY += uiBestPUDistY;
2679    uiOverallDistC += uiBestPUDistC;
2680   
2681    //--- update transform index and cbf ---
2682    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2683    ::memcpy( pcCU->getTransformIdx()       + uiPartOffset, m_puhQTTempTrIdx,  uiQPartNum * sizeof( UChar ) );
2684    ::memcpy( pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, m_puhQTTempCbf[0], uiQPartNum * sizeof( UChar ) );
2685    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, m_puhQTTempCbf[1], uiQPartNum * sizeof( UChar ) );
2686    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, m_puhQTTempCbf[2], uiQPartNum * sizeof( UChar ) );
2687    ::memcpy( pcCU->getTransformSkip(TEXT_LUMA)     + uiPartOffset, m_puhQTTempTransformSkipFlag[0], uiQPartNum * sizeof( UChar ) );
2688    ::memcpy( pcCU->getTransformSkip(TEXT_CHROMA_U) + uiPartOffset, m_puhQTTempTransformSkipFlag[1], uiQPartNum * sizeof( UChar ) );
2689    ::memcpy( pcCU->getTransformSkip(TEXT_CHROMA_V) + uiPartOffset, m_puhQTTempTransformSkipFlag[2], uiQPartNum * sizeof( UChar ) );
2690    //--- set reconstruction for next intra prediction blocks ---
2691    if( uiPU != uiNumPU - 1 )
2692    {
2693      Bool bSkipChroma  = false;
2694      Bool bChromaSame  = false;
2695      UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> ( pcCU->getDepth(0) + uiInitTrDepth ) ] + 2;
2696      if( !bLumaOnly && uiLog2TrSize == 2 )
2697      {
2698        assert( uiInitTrDepth  > 0 );
2699        bSkipChroma  = ( uiPU != 0 );
2700        bChromaSame  = true;
2701      }
2702     
2703      UInt    uiCompWidth   = pcCU->getWidth ( 0 ) >> uiInitTrDepth;
2704      UInt    uiCompHeight  = pcCU->getHeight( 0 ) >> uiInitTrDepth;
2705      UInt    uiZOrder      = pcCU->getZorderIdxInCU() + uiPartOffset;
2706      Pel*    piDes         = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
2707      UInt    uiDesStride   = pcCU->getPic()->getPicYuvRec()->getStride();
2708      Pel*    piSrc         = pcRecoYuv->getLumaAddr( uiPartOffset );
2709      UInt    uiSrcStride   = pcRecoYuv->getStride();
2710      for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2711      {
2712        for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2713        {
2714          piDes[ uiX ] = piSrc[ uiX ];
2715        }
2716      }
2717      if( !bLumaOnly && !bSkipChroma )
2718      {
2719        if( !bChromaSame )
2720        {
2721          uiCompWidth   >>= 1;
2722          uiCompHeight  >>= 1;
2723        }
2724        piDes         = pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder );
2725        uiDesStride   = pcCU->getPic()->getPicYuvRec()->getCStride();
2726        piSrc         = pcRecoYuv->getCbAddr( uiPartOffset );
2727        uiSrcStride   = pcRecoYuv->getCStride();
2728        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2729        {
2730          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2731          {
2732            piDes[ uiX ] = piSrc[ uiX ];
2733          }
2734        }
2735        piDes         = pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder );
2736        piSrc         = pcRecoYuv->getCrAddr( uiPartOffset );
2737        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2738        {
2739          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2740          {
2741            piDes[ uiX ] = piSrc[ uiX ];
2742          }
2743        }
2744      }
2745    }
2746   
2747    //=== update PU data ====
2748    pcCU->setLumaIntraDirSubParts     ( uiBestPUMode, uiPartOffset, uiDepth + uiInitTrDepth );
2749    pcCU->copyToPic                   ( uiDepth, uiPU, uiInitTrDepth );
2750  } // PU loop
2751 
2752 
2753  if( uiNumPU > 1 )
2754  { // set Cbf for all blocks
2755    UInt uiCombCbfY = 0;
2756    UInt uiCombCbfU = 0;
2757    UInt uiCombCbfV = 0;
2758    UInt uiPartIdx  = 0;
2759    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += uiQNumParts )
2760    {
2761      uiCombCbfY |= pcCU->getCbf( uiPartIdx, TEXT_LUMA,     1 );
2762      uiCombCbfU |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_U, 1 );
2763      uiCombCbfV |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_V, 1 );
2764    }
2765    for( UInt uiOffs = 0; uiOffs < 4 * uiQNumParts; uiOffs++ )
2766    {
2767      pcCU->getCbf( TEXT_LUMA     )[ uiOffs ] |= uiCombCbfY;
2768      pcCU->getCbf( TEXT_CHROMA_U )[ uiOffs ] |= uiCombCbfU;
2769      pcCU->getCbf( TEXT_CHROMA_V )[ uiOffs ] |= uiCombCbfV;
2770    }
2771  }
2772 
2773  //===== reset context models =====
2774  if(m_bUseSBACRD)
2775  {
2776    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2777  }
2778 
2779  //===== set distortion (rate and r-d costs are determined later) =====
2780  ruiDistC                   = uiOverallDistC;
2781  pcCU->getTotalDistortion() = uiOverallDistY + uiOverallDistC;
2782}
2783
2784
2785
2786Void
2787TEncSearch::estIntraPredChromaQT( TComDataCU* pcCU, 
2788                                 TComYuv*    pcOrgYuv, 
2789                                 TComYuv*    pcPredYuv, 
2790                                 TComYuv*    pcResiYuv, 
2791                                 TComYuv*    pcRecoYuv,
2792                                 UInt        uiPreCalcDistC )
2793{
2794  UInt    uiDepth     = pcCU->getDepth(0);
2795  UInt    uiBestMode  = 0;
2796  UInt    uiBestDist  = 0;
2797  Double  dBestCost   = MAX_DOUBLE;
2798 
2799  //----- init mode list -----
2800  UInt  uiMinMode = 0;
2801  UInt  uiModeList[ NUM_CHROMA_MODE ];
2802  pcCU->getAllowedChromaDir( 0, uiModeList );
2803  UInt  uiMaxMode = NUM_CHROMA_MODE;
2804
2805  //----- check chroma modes -----
2806  for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )
2807  {
2808    //----- restore context models -----
2809    if( m_bUseSBACRD )
2810    {
2811      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2812    }
2813   
2814    //----- chroma coding -----
2815    UInt    uiDist = 0;
2816    pcCU->setChromIntraDirSubParts  ( uiModeList[uiMode], 0, uiDepth );
2817    xRecurIntraChromaCodingQT       ( pcCU,   0, 0, pcOrgYuv, pcPredYuv, pcResiYuv, uiDist );
2818    if( m_bUseSBACRD && pcCU->getSlice()->getPPS()->getUseTransformSkip() )
2819    {
2820      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2821    }
2822    UInt    uiBits = xGetIntraBitsQT( pcCU,   0, 0, false, true, false );
2823    Double  dCost  = m_pcRdCost->calcRdCost( uiBits, uiDist );
2824   
2825    //----- compare -----
2826    if( dCost < dBestCost )
2827    {
2828      dBestCost   = dCost;
2829      uiBestDist  = uiDist;
2830      uiBestMode  = uiModeList[uiMode];
2831      UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2832      xSetIntraResultChromaQT( pcCU, 0, 0, pcRecoYuv );
2833      ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
2834      ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
2835      ::memcpy( m_puhQTTempTransformSkipFlag[1], pcCU->getTransformSkip( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
2836      ::memcpy( m_puhQTTempTransformSkipFlag[2], pcCU->getTransformSkip( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
2837    }
2838  }
2839 
2840  //----- set data -----
2841  UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2842  ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPN * sizeof( UChar ) );
2843  ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPN * sizeof( UChar ) );
2844  ::memcpy( pcCU->getTransformSkip( TEXT_CHROMA_U ), m_puhQTTempTransformSkipFlag[1], uiQPN * sizeof( UChar ) );
2845  ::memcpy( pcCU->getTransformSkip( TEXT_CHROMA_V ), m_puhQTTempTransformSkipFlag[2], uiQPN * sizeof( UChar ) );
2846  pcCU->setChromIntraDirSubParts( uiBestMode, 0, uiDepth );
2847  pcCU->getTotalDistortion      () += uiBestDist - uiPreCalcDistC;
2848 
2849  //----- restore context models -----
2850  if( m_bUseSBACRD )
2851  {
2852    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2853  }
2854}
2855
2856/** Function for encoding and reconstructing luma/chroma samples of a PCM mode CU.
2857 * \param pcCU pointer to current CU
2858 * \param uiAbsPartIdx part index
2859 * \param piOrg pointer to original sample arrays
2860 * \param piPCM pointer to PCM code arrays
2861 * \param piPred pointer to prediction signal arrays
2862 * \param piResi pointer to residual signal arrays
2863 * \param piReco pointer to reconstructed sample arrays
2864 * \param uiStride stride of the original/prediction/residual sample arrays
2865 * \param uiWidth block width
2866 * \param uiHeight block height
2867 * \param ttText texture component type
2868 * \returns Void
2869 */
2870Void TEncSearch::xEncPCM (TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piOrg, Pel* piPCM, Pel* piPred, Pel* piResi, Pel* piReco, UInt uiStride, UInt uiWidth, UInt uiHeight, TextType eText )
2871{
2872  UInt uiX, uiY;
2873  UInt uiReconStride;
2874  Pel* pOrg  = piOrg;
2875  Pel* pPCM  = piPCM;
2876  Pel* pPred = piPred;
2877  Pel* pResi = piResi;
2878  Pel* pReco = piReco;
2879  Pel* pRecoPic;
2880  Int shiftPcm;
2881
2882  if( eText == TEXT_LUMA)
2883  {
2884    uiReconStride = pcCU->getPic()->getPicYuvRec()->getStride();
2885    pRecoPic      = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiAbsPartIdx);
2886    shiftPcm = g_bitDepthY - pcCU->getSlice()->getSPS()->getPCMBitDepthLuma();
2887  }
2888  else
2889  {
2890    uiReconStride = pcCU->getPic()->getPicYuvRec()->getCStride();
2891
2892    if( eText == TEXT_CHROMA_U )
2893    {
2894      pRecoPic = pcCU->getPic()->getPicYuvRec()->getCbAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiAbsPartIdx);
2895    }
2896    else
2897    {
2898      pRecoPic = pcCU->getPic()->getPicYuvRec()->getCrAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiAbsPartIdx);
2899    }
2900    shiftPcm = g_bitDepthC - pcCU->getSlice()->getSPS()->getPCMBitDepthChroma();
2901  }
2902
2903  // Reset pred and residual
2904  for( uiY = 0; uiY < uiHeight; uiY++ )
2905  {
2906    for( uiX = 0; uiX < uiWidth; uiX++ )
2907    {
2908      pPred[uiX] = 0;
2909      pResi[uiX] = 0;
2910    }
2911    pPred += uiStride;
2912    pResi += uiStride;
2913  }
2914
2915  // Encode
2916  for( uiY = 0; uiY < uiHeight; uiY++ )
2917  {
2918    for( uiX = 0; uiX < uiWidth; uiX++ )
2919    {
2920      pPCM[uiX] = pOrg[uiX]>> shiftPcm;
2921    }
2922    pPCM += uiWidth;
2923    pOrg += uiStride;
2924  }
2925
2926  pPCM  = piPCM;
2927
2928  // Reconstruction
2929  for( uiY = 0; uiY < uiHeight; uiY++ )
2930  {
2931    for( uiX = 0; uiX < uiWidth; uiX++ )
2932    {
2933      pReco   [uiX] = pPCM[uiX]<< shiftPcm;
2934      pRecoPic[uiX] = pReco[uiX];
2935    }
2936    pPCM += uiWidth;
2937    pReco += uiStride;
2938    pRecoPic += uiReconStride;
2939  }
2940}
2941
2942/**  Function for PCM mode estimation.
2943 * \param pcCU
2944 * \param pcOrgYuv
2945 * \param rpcPredYuv
2946 * \param rpcResiYuv
2947 * \param rpcRecoYuv
2948 * \returns Void
2949 */
2950Void TEncSearch::IPCMSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv )
2951{
2952  UInt   uiDepth        = pcCU->getDepth(0);
2953  UInt   uiWidth        = pcCU->getWidth(0);
2954  UInt   uiHeight       = pcCU->getHeight(0);
2955  UInt   uiStride       = rpcPredYuv->getStride();
2956  UInt   uiStrideC      = rpcPredYuv->getCStride();
2957  UInt   uiWidthC       = uiWidth  >> 1;
2958  UInt   uiHeightC      = uiHeight >> 1;
2959  UInt   uiDistortion = 0;
2960  UInt   uiBits;
2961
2962  Double dCost;
2963
2964  Pel*    pOrig;
2965  Pel*    pResi;
2966  Pel*    pReco;
2967  Pel*    pPred;
2968  Pel*    pPCM;
2969
2970  UInt uiAbsPartIdx = 0;
2971
2972  UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
2973  UInt uiLumaOffset   = uiMinCoeffSize*uiAbsPartIdx;
2974  UInt uiChromaOffset = uiLumaOffset>>2;
2975
2976  // Luminance
2977  pOrig    = pcOrgYuv->getLumaAddr(0, uiWidth);
2978  pResi    = rpcResiYuv->getLumaAddr(0, uiWidth);
2979  pPred    = rpcPredYuv->getLumaAddr(0, uiWidth);
2980  pReco    = rpcRecoYuv->getLumaAddr(0, uiWidth);
2981  pPCM     = pcCU->getPCMSampleY() + uiLumaOffset;
2982
2983  xEncPCM ( pcCU, 0, pOrig, pPCM, pPred, pResi, pReco, uiStride, uiWidth, uiHeight, TEXT_LUMA );
2984
2985  // Chroma U
2986  pOrig    = pcOrgYuv->getCbAddr();
2987  pResi    = rpcResiYuv->getCbAddr();
2988  pPred    = rpcPredYuv->getCbAddr();
2989  pReco    = rpcRecoYuv->getCbAddr();
2990  pPCM     = pcCU->getPCMSampleCb() + uiChromaOffset;
2991
2992  xEncPCM ( pcCU, 0, pOrig, pPCM, pPred, pResi, pReco, uiStrideC, uiWidthC, uiHeightC, TEXT_CHROMA_U );
2993
2994  // Chroma V
2995  pOrig    = pcOrgYuv->getCrAddr();
2996  pResi    = rpcResiYuv->getCrAddr();
2997  pPred    = rpcPredYuv->getCrAddr();
2998  pReco    = rpcRecoYuv->getCrAddr();
2999  pPCM     = pcCU->getPCMSampleCr() + uiChromaOffset;
3000
3001  xEncPCM ( pcCU, 0, pOrig, pPCM, pPred, pResi, pReco, uiStrideC, uiWidthC, uiHeightC, TEXT_CHROMA_V );
3002
3003  m_pcEntropyCoder->resetBits();
3004  xEncIntraHeader ( pcCU, uiDepth, uiAbsPartIdx, true, false);
3005  uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
3006
3007  dCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
3008
3009  if(m_bUseSBACRD)
3010  {
3011    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
3012  }
3013
3014  pcCU->getTotalBits()       = uiBits;
3015  pcCU->getTotalCost()       = dCost;
3016  pcCU->getTotalDistortion() = uiDistortion;
3017
3018  pcCU->copyToPic(uiDepth, 0, 0);
3019}
3020
3021Void TEncSearch::xGetInterPredictionError( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, UInt& ruiErr, Bool bHadamard )
3022{
3023  motionCompensation( pcCU, &m_tmpYuvPred, REF_PIC_LIST_X, iPartIdx );
3024
3025  UInt uiAbsPartIdx = 0;
3026  Int iWidth = 0;
3027  Int iHeight = 0;
3028  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
3029
3030  DistParam cDistParam;
3031
3032  cDistParam.bApplyWeight = false;
3033
3034  m_pcRdCost->setDistParam( cDistParam, g_bitDepthY,
3035                            pcYuvOrg->getLumaAddr( uiAbsPartIdx ), pcYuvOrg->getStride(), 
3036                            m_tmpYuvPred .getLumaAddr( uiAbsPartIdx ), m_tmpYuvPred .getStride(), 
3037#if NS_HAD
3038                            iWidth, iHeight, m_pcEncCfg->getUseHADME(), m_pcEncCfg->getUseNSQT() );
3039#else
3040                            iWidth, iHeight, m_pcEncCfg->getUseHADME() );
3041#endif
3042  ruiErr = cDistParam.DistFunc( &cDistParam );
3043}
3044
3045/** estimation of best merge coding
3046 * \param pcCU
3047 * \param pcYuvOrg
3048 * \param iPUIdx
3049 * \param uiInterDir
3050 * \param pacMvField
3051 * \param uiMergeIndex
3052 * \param ruiCost
3053 * \param ruiBits
3054 * \param puhNeighCands
3055 * \param bValid
3056 * \returns Void
3057 */
3058Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost, TComMvField* cMvFieldNeighbours, UChar* uhInterDirNeighbours, Int& numValidMergeCand )
3059{
3060  UInt uiAbsPartIdx = 0;
3061  Int iWidth = 0;
3062  Int iHeight = 0; 
3063
3064  pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
3065  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
3066  PartSize partSize = pcCU->getPartitionSize( 0 );
3067  if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && partSize != SIZE_2Nx2N && pcCU->getWidth( 0 ) <= 8 )
3068  {
3069    pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
3070    if ( iPUIdx == 0 )
3071    {
3072      pcCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
3073    }
3074    pcCU->setPartSizeSubParts( partSize, 0, uiDepth );
3075  }
3076  else
3077  {
3078    pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
3079  }
3080  xRestrictBipredMergeCand( pcCU, iPUIdx, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
3081
3082  ruiCost = MAX_UINT;
3083  for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
3084  {
3085#if REF_IDX_ME_ZEROMV
3086    Bool bZeroMVILR = pcCU->xCheckZeroMVILRMerge(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]);
3087    if(bZeroMVILR)
3088    {
3089#endif
3090      UInt uiCostCand = MAX_UINT;
3091      UInt uiBitsCand = 0;
3092     
3093      PartSize ePartSize = pcCU->getPartitionSize( 0 );
3094
3095      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
3096      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
3097
3098      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
3099      uiBitsCand = uiMergeCand + 1;
3100      if (uiMergeCand == m_pcEncCfg->getMaxNumMergeCand() -1)
3101      {
3102         uiBitsCand--;
3103      }
3104      uiCostCand = uiCostCand + m_pcRdCost->getCost( uiBitsCand );
3105      if ( uiCostCand < ruiCost )
3106      {
3107        ruiCost = uiCostCand;
3108        pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
3109        pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
3110        uiInterDir = uhInterDirNeighbours[uiMergeCand];
3111        uiMergeIndex = uiMergeCand;
3112      }
3113#if REF_IDX_ME_ZEROMV
3114    }
3115#endif
3116  }
3117}
3118
3119/** convert bi-pred merge candidates to uni-pred
3120 * \param pcCU
3121 * \param puIdx
3122 * \param mvFieldNeighbours
3123 * \param interDirNeighbours
3124 * \param numValidMergeCand
3125 * \returns Void
3126 */
3127Void TEncSearch::xRestrictBipredMergeCand( TComDataCU* pcCU, UInt puIdx, TComMvField* mvFieldNeighbours, UChar* interDirNeighbours, Int numValidMergeCand )
3128{
3129  if ( pcCU->isBipredRestriction(puIdx) )
3130  {
3131    for( UInt mergeCand = 0; mergeCand < numValidMergeCand; ++mergeCand )
3132    {
3133      if ( interDirNeighbours[mergeCand] == 3 )
3134      {
3135        interDirNeighbours[mergeCand] = 1;
3136        mvFieldNeighbours[(mergeCand << 1) + 1].setMvField(TComMv(0,0), -1);
3137      }
3138    }
3139  }
3140}
3141
3142/** search of the best candidate for inter prediction
3143 * \param pcCU
3144 * \param pcOrgYuv
3145 * \param rpcPredYuv
3146 * \param rpcResiYuv
3147 * \param rpcRecoYuv
3148 * \param bUseRes
3149 * \returns Void
3150 */
3151#if AMP_MRG
3152Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes, Bool bUseMRG )
3153#else
3154Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes )
3155#endif
3156{
3157  m_acYuvPred[0].clear();
3158  m_acYuvPred[1].clear();
3159  m_cYuvPredTemp.clear();
3160  rpcPredYuv->clear();
3161 
3162  if ( !bUseRes )
3163  {
3164    rpcResiYuv->clear();
3165  }
3166 
3167  rpcRecoYuv->clear();
3168 
3169  TComMv        cMvSrchRngLT;
3170  TComMv        cMvSrchRngRB;
3171 
3172  TComMv        cMvZero;
3173  TComMv        TempMv; //kolya
3174 
3175  TComMv        cMv[2];
3176  TComMv        cMvBi[2];
3177  TComMv        cMvTemp[2][33];
3178 
3179  Int           iNumPart    = pcCU->getNumPartInter();
3180  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
3181 
3182  TComMv        cMvPred[2][33];
3183 
3184  TComMv        cMvPredBi[2][33];
3185  Int           aaiMvpIdxBi[2][33];
3186 
3187  Int           aaiMvpIdx[2][33];
3188  Int           aaiMvpNum[2][33];
3189 
3190  AMVPInfo aacAMVPInfo[2][33];
3191 
3192  Int           iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
3193  Int           iRefIdxBi[2];
3194 
3195  UInt          uiPartAddr;
3196  Int           iRoiWidth, iRoiHeight;
3197 
3198  UInt          uiMbBits[3] = {1, 1, 0};
3199 
3200  UInt          uiLastMode = 0;
3201  Int           iRefStart, iRefEnd;
3202 
3203  PartSize      ePartSize = pcCU->getPartitionSize( 0 );
3204
3205  Int           bestBiPRefIdxL1 = 0;
3206  Int           bestBiPMvpL1 = 0;
3207  UInt          biPDistTemp = MAX_INT;
3208
3209#if ZERO_MVD_EST
3210  Int           aiZeroMvdMvpIdx[2] = {-1, -1};
3211  Int           aiZeroMvdRefIdx[2] = {0, 0};
3212  Int           iZeroMvdDir = -1;
3213#endif
3214
3215  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
3216  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
3217  Int numValidMergeCand = 0 ;
3218
3219  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3220  {
3221    UInt          uiCost[2] = { MAX_UINT, MAX_UINT };
3222    UInt          uiCostBi  =   MAX_UINT;
3223    UInt          uiCostTemp;
3224   
3225    UInt          uiBits[3];
3226    UInt          uiBitsTemp;
3227#if ZERO_MVD_EST
3228    UInt          uiZeroMvdCost = MAX_UINT;
3229    UInt          uiZeroMvdCostTemp;
3230    UInt          uiZeroMvdBitsTemp;
3231    UInt          uiZeroMvdDistTemp = MAX_UINT;
3232    UInt          auiZeroMvdBits[3];
3233#endif
3234    UInt          bestBiPDist = MAX_INT;
3235
3236    UInt          uiCostTempL0[MAX_NUM_REF];
3237    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) uiCostTempL0[iNumRef] = MAX_UINT;
3238    UInt          uiBitsTempL0[MAX_NUM_REF];
3239
3240    TComMv        mvValidList1;
3241    Int           refIdxValidList1 = 0;
3242    UInt          bitsValidList1 = MAX_UINT;
3243    UInt          costValidList1 = MAX_UINT;
3244
3245    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
3246   
3247    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3248   
3249#if AMP_MRG
3250    Bool bTestNormalMC = true;
3251   
3252    if ( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 )
3253    {
3254      bTestNormalMC = false;
3255    }
3256   
3257    if (bTestNormalMC)
3258    {
3259#endif
3260
3261    //  Uni-directional prediction
3262    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
3263    {
3264      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3265     
3266      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
3267      {
3268#if (ENCODER_FAST_MODE)
3269        TComPic* pcPic    = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxTemp );
3270        if( pcPic->isILR(pcCU->getLayerId()) && (ePartSize == SIZE_2Nx2N) ) 
3271        {
3272          continue;
3273        }
3274#endif
3275
3276        uiBitsTemp = uiMbBits[iRefList];
3277        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3278        {
3279          uiBitsTemp += iRefIdxTemp+1;
3280          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3281        }
3282#if ZERO_MVD_EST
3283        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp, &uiZeroMvdDistTemp);
3284#else
3285        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
3286#endif
3287        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
3288        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
3289       
3290        if(pcCU->getSlice()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
3291        {
3292#if REF_IDX_ME_ZEROMV
3293          Bool bZeroMVILR = pcCU->xCheckZeroMVILRMvdL1Zero(iRefList, iRefIdxTemp, aaiMvpIdx[iRefList][iRefIdxTemp]);
3294          if(bZeroMVILR)
3295          {
3296#endif
3297          bestBiPDist = biPDistTemp;
3298          bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
3299          bestBiPRefIdxL1 = iRefIdxTemp;
3300#if REF_IDX_ME_ZEROMV
3301          }
3302#endif
3303        }
3304
3305        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3306#if ZERO_MVD_EST
3307        if ( iRefList == 0 || pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
3308        {
3309          uiZeroMvdBitsTemp = uiBitsTemp;
3310          uiZeroMvdBitsTemp += 2; //zero mvd bits
3311
3312          m_pcRdCost->getMotionCost( 1, 0 );
3313          uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost(uiZeroMvdBitsTemp);
3314
3315          if (uiZeroMvdCostTemp < uiZeroMvdCost)
3316          {
3317            uiZeroMvdCost = uiZeroMvdCostTemp;
3318            iZeroMvdDir = iRefList + 1;
3319            aiZeroMvdRefIdx[iRefList] = iRefIdxTemp;
3320            aiZeroMvdMvpIdx[iRefList] = aaiMvpIdx[iRefList][iRefIdxTemp];
3321            auiZeroMvdBits[iRefList] = uiZeroMvdBitsTemp;
3322          }         
3323        }
3324#endif
3325       
3326#if GPB_SIMPLE_UNI
3327        if ( iRefList == 1 )    // list 1
3328        {
3329          if ( pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 )
3330          {
3331            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3332            uiCostTemp = uiCostTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3333            /*first subtract the bit-rate part of the cost of the other list*/
3334            uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )] );
3335            /*correct the bit-rate part of the current ref*/
3336            m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
3337            uiBitsTemp += m_pcRdCost->getBits( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
3338            /*calculate the correct cost*/
3339            uiCostTemp += m_pcRdCost->getCost( uiBitsTemp );
3340          }
3341          else
3342          {
3343            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3344          }
3345        }
3346        else
3347        {
3348          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3349        }
3350#else
3351        xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3352#endif
3353        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
3354        xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3355
3356        if ( iRefList == 0 )
3357        {
3358          uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3359          uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
3360        }
3361        if ( uiCostTemp < uiCost[iRefList] )
3362        {
3363          uiCost[iRefList] = uiCostTemp;
3364          uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3365
3366          // set motion
3367          cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3368          iRefIdx[iRefList] = iRefIdxTemp;
3369        }
3370
3371        if ( iRefList == 1 && uiCostTemp < costValidList1 && pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
3372        {
3373          costValidList1 = uiCostTemp;
3374          bitsValidList1 = uiBitsTemp;
3375
3376          // set motion
3377          mvValidList1     = cMvTemp[iRefList][iRefIdxTemp];
3378          refIdxValidList1 = iRefIdxTemp;
3379        }
3380      }
3381    }
3382    //  Bi-directional prediction
3383#if REF_IDX_ME_ZEROMV
3384    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) && !(pcCU->getSlice()->getMvdL1ZeroFlag() && bestBiPDist == MAX_INT) )
3385#else
3386    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
3387#endif
3388    {
3389     
3390      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
3391      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
3392     
3393      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
3394      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
3395     
3396      UInt uiMotBits[2];
3397
3398      if(pcCU->getSlice()->getMvdL1ZeroFlag())
3399      {
3400        xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3401        pcCU->setMVPIdxSubParts( bestBiPMvpL1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3402        aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1;
3403        cMvPredBi[1][bestBiPRefIdxL1]   = pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()->m_acMvCand[bestBiPMvpL1];
3404
3405        cMvBi[1] = cMvPredBi[1][bestBiPRefIdxL1];
3406        iRefIdxBi[1] = bestBiPRefIdxL1;
3407        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3408        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3409        TComYuv* pcYuvPred = &m_acYuvPred[1];
3410        motionCompensation( pcCU, pcYuvPred, REF_PIC_LIST_1, iPartIdx );
3411
3412        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3413        uiMotBits[1] = uiMbBits[1];
3414
3415        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3416        {
3417          uiMotBits[1] += bestBiPRefIdxL1+1;
3418          if ( bestBiPRefIdxL1 == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiMotBits[1]--;
3419        }
3420
3421        uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS];
3422
3423        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3424
3425        cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1];
3426      }
3427      else
3428      {
3429        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3430        uiMotBits[1] = uiBits[1] - uiMbBits[1];
3431        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3432      }
3433
3434      // 4-times iteration (default)
3435      Int iNumIter = 4;
3436     
3437      // fast encoder setting: only one iteration
3438      if ( m_pcEncCfg->getUseFastEnc() || pcCU->getSlice()->getMvdL1ZeroFlag())
3439      {
3440        iNumIter = 1;
3441      }
3442     
3443      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3444      {
3445       
3446        Int         iRefList    = iIter % 2;
3447        if ( m_pcEncCfg->getUseFastEnc() )
3448        {
3449          if( uiCost[0] <= uiCost[1] )
3450          {
3451            iRefList = 1;
3452          }
3453          else
3454          {
3455            iRefList = 0;
3456          }
3457        }
3458        else if ( iIter == 0 )
3459        {
3460          iRefList = 0;
3461        }
3462        if ( iIter == 0 && !pcCU->getSlice()->getMvdL1ZeroFlag())
3463        {
3464          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllMv( cMv[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3465          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllRefIdx( iRefIdx[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3466          TComYuv*  pcYuvPred = &m_acYuvPred[1-iRefList];
3467          motionCompensation ( pcCU, pcYuvPred, RefPicList(1-iRefList), iPartIdx );
3468        }
3469        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3470
3471        if(pcCU->getSlice()->getMvdL1ZeroFlag())
3472        {
3473          iRefList = 0;
3474          eRefPicList = REF_PIC_LIST_0;
3475        }
3476
3477        Bool bChanged = false;
3478       
3479#if (ENCODER_FAST_MODE)
3480        Bool     testIter = true;
3481        TComPic* pcPic    = pcCU->getSlice()->getRefPic( RefPicList(1 - iRefList), iRefIdxBi[1 - iRefList] );
3482        if(pcPic->isILR(pcCU->getLayerId()) && (ePartSize == SIZE_2Nx2N))
3483        {
3484          testIter = false;  //the fixed part is ILR, skip this iteration       
3485        }
3486        if(testIter)
3487        {
3488#endif
3489        iRefStart = 0;
3490        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3491       
3492        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3493        {
3494#if (ENCODER_FAST_MODE)
3495          Bool testRefIdx = true;
3496          pcPic           = pcCU->getSlice()->getRefPic( RefPicList(iRefList) , iRefIdxTemp );
3497          if(pcPic->isILR(pcCU->getLayerId()) && (ePartSize == SIZE_2Nx2N))
3498          {
3499            testRefIdx = false;  //the refined part is ILR, skip this reference pic           
3500          }
3501          if(testRefIdx)
3502          {
3503#endif
3504          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3505          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3506          {
3507            uiBitsTemp += iRefIdxTemp+1;
3508            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3509          }
3510          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3511          // call ME
3512          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3513          xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3514          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3515
3516          if ( uiCostTemp < uiCostBi )
3517          {
3518            bChanged = true;
3519           
3520            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3521            iRefIdxBi[iRefList] = iRefIdxTemp;
3522           
3523            uiCostBi            = uiCostTemp;
3524            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3525            uiBits[2]           = uiBitsTemp;
3526           
3527            if(iNumIter!=1)
3528            {
3529              //  Set motion
3530              pcCU->getCUMvField( eRefPicList )->setAllMv( cMvBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3531              pcCU->getCUMvField( eRefPicList )->setAllRefIdx( iRefIdxBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3532
3533              TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3534              motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3535            }
3536          }
3537#if (ENCODER_FAST_MODE)
3538          }
3539#endif
3540        }
3541#if (ENCODER_FAST_MODE)
3542        } // for loop-iRefIdxTemp
3543#endif
3544       
3545        if ( !bChanged )
3546        {
3547          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] )
3548          {
3549            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3550            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3551            if(!pcCU->getSlice()->getMvdL1ZeroFlag())
3552            {
3553              xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3554              xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3555            }
3556          }
3557          break;
3558        }
3559      } // for loop-iter
3560    } // if (B_SLICE)
3561#if ZERO_MVD_EST
3562    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
3563    {
3564      m_pcRdCost->getMotionCost( 1, 0 );
3565
3566      for ( Int iL0RefIdxTemp = 0; iL0RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1; iL0RefIdxTemp++ )
3567      for ( Int iL1RefIdxTemp = 0; iL1RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1; iL1RefIdxTemp++ )
3568      {
3569        UInt uiRefIdxBitsTemp = 0;
3570        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 1 )
3571        {
3572          uiRefIdxBitsTemp += iL0RefIdxTemp+1;
3573          if ( iL0RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1 ) uiRefIdxBitsTemp--;
3574        }
3575        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3576        {
3577          uiRefIdxBitsTemp += iL1RefIdxTemp+1;
3578          if ( iL1RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiRefIdxBitsTemp--;
3579        }
3580
3581        Int iL0MVPIdx = 0;
3582        Int iL1MVPIdx = 0;
3583
3584        for (iL0MVPIdx = 0; iL0MVPIdx < aaiMvpNum[0][iL0RefIdxTemp]; iL0MVPIdx++)
3585        {
3586          for (iL1MVPIdx = 0; iL1MVPIdx < aaiMvpNum[1][iL1RefIdxTemp]; iL1MVPIdx++)
3587          {
3588            uiZeroMvdBitsTemp = uiRefIdxBitsTemp;
3589            uiZeroMvdBitsTemp += uiMbBits[2];
3590            uiZeroMvdBitsTemp += m_auiMVPIdxCost[iL0MVPIdx][aaiMvpNum[0][iL0RefIdxTemp]] + m_auiMVPIdxCost[iL1MVPIdx][aaiMvpNum[1][iL1RefIdxTemp]];
3591            uiZeroMvdBitsTemp += 4; //zero mvd for both directions
3592            pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( aacAMVPInfo[0][iL0RefIdxTemp].m_acMvCand[iL0MVPIdx], iL0RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3593            pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( aacAMVPInfo[1][iL1RefIdxTemp].m_acMvCand[iL1MVPIdx], iL1RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3594 
3595            xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiZeroMvdDistTemp, m_pcEncCfg->getUseHADME() );
3596            uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost( uiZeroMvdBitsTemp );
3597            if (uiZeroMvdCostTemp < uiZeroMvdCost)
3598            {
3599              uiZeroMvdCost = uiZeroMvdCostTemp;
3600              iZeroMvdDir = 3;
3601              aiZeroMvdMvpIdx[0] = iL0MVPIdx;
3602              aiZeroMvdMvpIdx[1] = iL1MVPIdx;
3603              aiZeroMvdRefIdx[0] = iL0RefIdxTemp;
3604              aiZeroMvdRefIdx[1] = iL1RefIdxTemp;
3605              auiZeroMvdBits[2] = uiZeroMvdBitsTemp;
3606            }
3607          }
3608        }
3609      }
3610    }
3611#endif
3612
3613#if AMP_MRG
3614    } //end if bTestNormalMC
3615#endif
3616    //  Clear Motion Field
3617    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3618    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3619    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3620    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3621
3622    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3623    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3624    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3625    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3626   
3627    UInt uiMEBits = 0;
3628    // Set Motion Field_
3629    cMv[1] = mvValidList1;
3630    iRefIdx[1] = refIdxValidList1;
3631    uiBits[1] = bitsValidList1;
3632    uiCost[1] = costValidList1;
3633#if AMP_MRG
3634    if (bTestNormalMC)
3635    {
3636#endif
3637#if ZERO_MVD_EST
3638    if (uiZeroMvdCost <= uiCostBi && uiZeroMvdCost <= uiCost[0] && uiZeroMvdCost <= uiCost[1])
3639    {
3640      if (iZeroMvdDir == 3)
3641      {
3642        uiLastMode = 2;
3643
3644        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3645        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3646 
3647        pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3648       
3649        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3650        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3651        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3652        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3653        uiMEBits = auiZeroMvdBits[2];
3654      }
3655      else if (iZeroMvdDir == 1)
3656      {       
3657        uiLastMode = 0;
3658
3659        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3660
3661        pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3662       
3663        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3664        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3665        uiMEBits = auiZeroMvdBits[0];
3666      }
3667      else if (iZeroMvdDir == 2)
3668      {
3669        uiLastMode = 1;
3670
3671        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3672
3673        pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3674       
3675        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3676        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3677        uiMEBits = auiZeroMvdBits[1];
3678      }
3679      else
3680      {
3681        assert(0);
3682      }
3683    }
3684    else
3685#endif
3686    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3687    {
3688      uiLastMode = 2;
3689      {
3690            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMvBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3691            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdxBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3692            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3693            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3694      }
3695      {
3696        TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3697            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3698      }
3699      {
3700        TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3701            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3702      }
3703     
3704      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3705     
3706      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3707      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3708      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3709      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3710
3711      uiMEBits = uiBits[2];
3712    }
3713    else if ( uiCost[0] <= uiCost[1] )
3714    {
3715      uiLastMode = 0;
3716          pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
3717          pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
3718      {
3719        TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3720            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3721      }
3722      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3723     
3724      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3725      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3726
3727      uiMEBits = uiBits[0];
3728    }
3729    else
3730    {
3731      uiLastMode = 1;
3732          pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
3733          pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
3734      {
3735        TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3736            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3737      }
3738      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3739     
3740      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3741      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3742
3743      uiMEBits = uiBits[1];
3744    }
3745#if AMP_MRG
3746    } // end if bTestNormalMC
3747#endif
3748
3749    if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3750    {
3751      UInt uiMRGInterDir = 0;     
3752      TComMvField cMRGMvField[2];
3753      UInt uiMRGIndex = 0;
3754
3755      UInt uiMEInterDir = 0;
3756      TComMvField cMEMvField[2];
3757
3758      m_pcRdCost->getMotionCost( 1, 0 );
3759#if AMP_MRG
3760      // calculate ME cost
3761      UInt uiMEError = MAX_UINT;
3762      UInt uiMECost = MAX_UINT;
3763
3764      if (bTestNormalMC)
3765      {
3766        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3767        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3768      }
3769#else
3770      // calculate ME cost
3771      UInt uiMEError = MAX_UINT;
3772      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3773      UInt uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3774#endif
3775      // save ME result.
3776      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3777      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3778      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3779
3780      // find Merge result
3781      UInt uiMRGCost = MAX_UINT;
3782      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand);
3783      if ( uiMRGCost < uiMECost )
3784      {
3785        // set Merge result
3786        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3787        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3788        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3789        {
3790          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3791          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3792        }
3793
3794        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3795        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3796
3797        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3798        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3799        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3800        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3801      }
3802      else
3803      {
3804        // set ME result
3805        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3806        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3807        {
3808          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3809          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3810        }
3811      }
3812    }
3813
3814    //  MC
3815    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
3816   
3817  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3818
3819  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
3820
3821  return;
3822}
3823
3824// AMVP
3825#if ZERO_MVD_EST
3826Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDistBiP, UInt* puiDist  )
3827#else
3828Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDistBiP )
3829#endif
3830{
3831  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3832 
3833  TComMv  cBestMv;
3834  Int     iBestIdx = 0;
3835  TComMv  cZeroMv;
3836  TComMv  cMvPred;
3837  UInt    uiBestCost = MAX_INT;
3838  UInt    uiPartAddr = 0;
3839  Int     iRoiWidth, iRoiHeight;
3840  Int     i;
3841 
3842  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3843  // Fill the MV Candidates
3844  if (!bFilled)
3845  {
3846    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
3847  }
3848 
3849  // initialize Mvp index & Mvp
3850  iBestIdx = 0;
3851  cBestMv  = pcAMVPInfo->m_acMvCand[0];
3852#if !ZERO_MVD_EST
3853  if (pcAMVPInfo->iN <= 1)
3854  {
3855    rcMvPred = cBestMv;
3856   
3857    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3858    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3859
3860    if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefPicList==REF_PIC_LIST_1)
3861    {
3862#if ZERO_MVD_EST
3863      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3864#else
3865      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3866#endif
3867    }
3868    return;
3869  }
3870#endif 
3871  if (bFilled)
3872  {
3873    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
3874    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
3875    return;
3876  }
3877 
3878  m_cYuvPredTemp.clear();
3879#if ZERO_MVD_EST
3880  UInt uiDist;
3881#endif
3882  //-- Check Minimum Cost.
3883  for ( i = 0 ; i < pcAMVPInfo->iN; i++)
3884  {
3885    UInt uiTmpCost;
3886#if ZERO_MVD_EST
3887    uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3888#else
3889    uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3890#endif     
3891    if ( uiBestCost > uiTmpCost )
3892    {
3893      uiBestCost = uiTmpCost;
3894      cBestMv   = pcAMVPInfo->m_acMvCand[i];
3895      iBestIdx  = i;
3896      (*puiDistBiP) = uiTmpCost;
3897#if ZERO_MVD_EST
3898      (*puiDist) = uiDist;
3899#endif
3900    }
3901  }
3902
3903  m_cYuvPredTemp.clear();
3904 
3905  // Setting Best MVP
3906  rcMvPred = cBestMv;
3907  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3908  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3909  return;
3910}
3911
3912UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
3913{
3914  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
3915 
3916  if (iNum == 1)
3917    return 0;
3918 
3919  UInt uiLength = 1;
3920  Int iTemp = iIdx;
3921  if ( iTemp == 0 )
3922  {
3923    return uiLength;
3924  }
3925 
3926  Bool bCodeLast = ( iNum-1 > iTemp );
3927 
3928  uiLength += (iTemp-1);
3929 
3930  if( bCodeLast )
3931  {
3932    uiLength++;
3933  }
3934 
3935  return uiLength;
3936}
3937
3938Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
3939{
3940  if ( eCUMode == SIZE_2Nx2N )
3941  {
3942    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3943    uiBlkBit[1] = 3;
3944    uiBlkBit[2] = 5;
3945  }
3946  else if ( (eCUMode == SIZE_2NxN || eCUMode == SIZE_2NxnU) || eCUMode == SIZE_2NxnD )
3947  {
3948    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} } };
3949    if ( bPSlice )
3950    {
3951      uiBlkBit[0] = 3;
3952      uiBlkBit[1] = 0;
3953      uiBlkBit[2] = 0;
3954    }
3955    else
3956    {
3957      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3958    }
3959  }
3960  else if ( (eCUMode == SIZE_Nx2N || eCUMode == SIZE_nLx2N) || eCUMode == SIZE_nRx2N )
3961  {
3962    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} } };
3963    if ( bPSlice )
3964    {
3965      uiBlkBit[0] = 3;
3966      uiBlkBit[1] = 0;
3967      uiBlkBit[2] = 0;
3968    }
3969    else
3970    {
3971      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3972    }
3973  }
3974  else if ( eCUMode == SIZE_NxN )
3975  {
3976    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3977    uiBlkBit[1] = 3;
3978    uiBlkBit[2] = 5;
3979  }
3980  else
3981  {
3982    printf("Wrong!\n");
3983    assert( 0 );
3984  }
3985}
3986
3987Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
3988{
3989  pDst->iN = pSrc->iN;
3990  for (Int i = 0; i < pSrc->iN; i++)
3991  {
3992    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
3993  }
3994}
3995
3996Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, UInt& ruiCost )
3997{
3998  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3999 
4000  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
4001 
4002  if (pcAMVPInfo->iN < 2) return;
4003 
4004  m_pcRdCost->getMotionCost( 1, 0 );
4005  m_pcRdCost->setCostScale ( 0    );
4006 
4007  Int iBestMVPIdx = riMVPIdx;
4008 
4009  m_pcRdCost->setPredictor( rcMvPred );
4010  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
4011  iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
4012  Int iBestMvBits = iOrgMvBits;
4013 
4014  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
4015  {
4016    if (iMVPIdx == riMVPIdx) continue;
4017   
4018    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
4019   
4020    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
4021    iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
4022   
4023    if (iMvBits < iBestMvBits)
4024    {
4025      iBestMvBits = iMvBits;
4026      iBestMVPIdx = iMVPIdx;
4027    }
4028  }
4029 
4030  if (iBestMVPIdx != riMVPIdx)  //if changed
4031  {
4032    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
4033   
4034    riMVPIdx = iBestMVPIdx;
4035    UInt uiOrgBits = ruiBits;
4036    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
4037    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
4038  }
4039}
4040
4041UInt TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
4042                                  UInt        uiPartIdx,
4043                                  UInt      uiPartAddr,
4044                                  TComYuv*    pcOrgYuv,
4045                                  TComYuv*    pcTemplateCand,
4046                                  TComMv      cMvCand,
4047                                  Int         iMVPIdx,
4048                                  Int     iMVPNum,
4049                                  RefPicList  eRefPicList,
4050                                  Int         iRefIdx,
4051                                  Int         iSizeX,
4052                                  Int         iSizeY
4053                               #if ZERO_MVD_EST
4054                                , UInt&       ruiDist
4055                               #endif
4056                                  )
4057{
4058  UInt uiCost  = MAX_INT;
4059 
4060  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
4061 
4062  pcCU->clipMv( cMvCand );
4063
4064  // prediction pattern
4065  if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType()==P_SLICE )
4066  {
4067    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, true );
4068  }
4069  else
4070  {
4071    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false );
4072  }
4073
4074  if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType()==P_SLICE )
4075  {
4076    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, iRefIdx );
4077  }
4078
4079  // calc distortion
4080#if ZERO_MVD_EST
4081  m_pcRdCost->getMotionCost( 1, 0 );
4082  DistParam cDistParam;
4083  m_pcRdCost->setDistParam( cDistParam, g_bitDepthY,
4084                            pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), 
4085                            pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), 
4086#if NS_HAD
4087                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME(), m_pcEncCfg->getUseNSQT() );
4088#else
4089                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME() );
4090#endif
4091  ruiDist = cDistParam.DistFunc( &cDistParam );
4092  uiCost = ruiDist + m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] );
4093#else
4094#if WEIGHTED_CHROMA_DISTORTION
4095  uiCost = m_pcRdCost->getDistPart(g_bitDepthY, pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, TEXT_LUMA, DF_SAD );
4096#else
4097  uiCost = m_pcRdCost->getDistPart(g_bitDepthY, pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, DF_SAD );
4098#endif
4099  uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
4100#endif
4101  return uiCost;
4102}
4103
4104Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, UInt& ruiCost, Bool bBi  )
4105{
4106  UInt          uiPartAddr;
4107  Int           iRoiWidth;
4108  Int           iRoiHeight;
4109 
4110  TComMv        cMvHalf, cMvQter;
4111  TComMv        cMvSrchRngLT;
4112  TComMv        cMvSrchRngRB;
4113 
4114  TComYuv*      pcYuv = pcYuvOrg;
4115  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
4116 
4117  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
4118  TComPattern*  pcPatternKey  = pcCU->getPattern        ();
4119 
4120  Double        fWeight       = 1.0;
4121 
4122  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
4123 
4124  if ( bBi )
4125  {
4126    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
4127    pcYuv                = &m_cYuvPredTemp;
4128   
4129    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
4130   
4131    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight );
4132   
4133    fWeight = 0.5;
4134  }
4135 
4136  //  Search key pattern initialization
4137  pcPatternKey->initPattern( pcYuv->getLumaAddr( uiPartAddr ),
4138                            pcYuv->getCbAddr  ( uiPartAddr ),
4139                            pcYuv->getCrAddr  ( uiPartAddr ),
4140                            iRoiWidth,
4141                            iRoiHeight,
4142                            pcYuv->getStride(),
4143                            0, 0 );
4144 
4145  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr );
4146  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride();
4147 
4148  TComMv      cMvPred = *pcMvPred;
4149 
4150  if ( bBi )  xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4151  else        xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4152 
4153  m_pcRdCost->getMotionCost ( 1, 0 );
4154 
4155  m_pcRdCost->setPredictor  ( *pcMvPred );
4156  m_pcRdCost->setCostScale  ( 2 );
4157
4158  setWpScalingDistParam( pcCU, iRefIdxPred, eRefPicList );
4159  //  Do integer search
4160#if REF_IDX_ME_ZEROMV
4161  if( pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->isILR(pcCU->getLayerId()))  //ILR reference pic
4162  {
4163    rcMv.setZero();  //use Mv(0, 0) for integer ME
4164  }
4165  else  //non ILR reference pic
4166  {
4167    if ( !m_iFastSearch || bBi ) 
4168    { 
4169      xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost ); 
4170    } 
4171    else 
4172    { 
4173      rcMv = *pcMvPred; 
4174      xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost ); 
4175    }
4176  }
4177#else
4178  if ( !m_iFastSearch || bBi )
4179  {
4180    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4181  }
4182  else
4183  {
4184    rcMv = *pcMvPred;
4185    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
4186  }
4187#endif
4188 
4189  m_pcRdCost->getMotionCost( 1, 0 );
4190  m_pcRdCost->setCostScale ( 1 );
4191 
4192  {
4193#if REF_IDX_ME_ZEROMV
4194    if( pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->isILR(pcCU->getLayerId()))  //ILR reference pic
4195    {
4196      xPatternSearchFracDIFMv0( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost, bBi );
4197    }
4198    else    //non ILR reference pic
4199    {
4200      xPatternSearchFracDIF( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost, bBi );
4201    }
4202#else
4203    xPatternSearchFracDIF( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost
4204                          ,bBi
4205                          );
4206#endif
4207  }
4208 
4209 
4210 
4211  m_pcRdCost->setCostScale( 0 );
4212  rcMv <<= 2;
4213  rcMv += (cMvHalf <<= 1);
4214  rcMv +=  cMvQter;
4215 
4216  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
4217 
4218  ruiBits      += uiMvBits;
4219  ruiCost       = (UInt)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
4220}
4221
4222
4223Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
4224{
4225  Int  iMvShift = 2;
4226  TComMv cTmpMvPred = cMvPred;
4227  pcCU->clipMv( cTmpMvPred );
4228
4229  rcMvSrchRngLT.setHor( cTmpMvPred.getHor() - (iSrchRng << iMvShift) );
4230  rcMvSrchRngLT.setVer( cTmpMvPred.getVer() - (iSrchRng << iMvShift) );
4231 
4232  rcMvSrchRngRB.setHor( cTmpMvPred.getHor() + (iSrchRng << iMvShift) );
4233  rcMvSrchRngRB.setVer( cTmpMvPred.getVer() + (iSrchRng << iMvShift) );
4234  pcCU->clipMv        ( rcMvSrchRngLT );
4235  pcCU->clipMv        ( rcMvSrchRngRB );
4236 
4237  rcMvSrchRngLT >>= iMvShift;
4238  rcMvSrchRngRB >>= iMvShift;
4239}
4240
4241Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4242{
4243  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4244  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4245  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4246  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4247 
4248  UInt  uiSad;
4249  UInt  uiSadBest         = MAX_UINT;
4250  Int   iBestX = 0;
4251  Int   iBestY = 0;
4252 
4253  Pel*  piRefSrch;
4254 
4255  //-- jclee for using the SAD function pointer
4256  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
4257 
4258  // fast encoder decision: use subsampled SAD for integer ME
4259  if ( m_pcEncCfg->getUseFastEnc() )
4260  {
4261    if ( m_cDistParam.iRows > 8 )
4262    {
4263      m_cDistParam.iSubShift = 1;
4264    }
4265  }
4266 
4267  piRefY += (iSrchRngVerTop * iRefStride);
4268  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4269  {
4270    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4271    {
4272      //  find min. distortion position
4273      piRefSrch = piRefY + x;
4274      m_cDistParam.pCur = piRefSrch;
4275
4276      setDistParamComp(0);
4277
4278      m_cDistParam.bitDepth = g_bitDepthY;
4279      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
4280     
4281      // motion cost
4282      uiSad += m_pcRdCost->getCost( x, y );
4283     
4284      if ( uiSad < uiSadBest )
4285      {
4286        uiSadBest = uiSad;
4287        iBestX    = x;
4288        iBestY    = y;
4289      }
4290    }
4291    piRefY += iRefStride;
4292  }
4293 
4294  rcMv.set( iBestX, iBestY );
4295 
4296  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
4297  return;
4298}
4299
4300Void TEncSearch::xPatternSearchFast( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4301{
4302  pcCU->getMvPredLeft       ( m_acMvPredictors[0] );
4303  pcCU->getMvPredAbove      ( m_acMvPredictors[1] );
4304  pcCU->getMvPredAboveRight ( m_acMvPredictors[2] );
4305 
4306  switch ( m_iFastSearch )
4307  {
4308    case 1:
4309      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD );
4310      break;
4311     
4312    default:
4313      break;
4314  }
4315}
4316
4317Void TEncSearch::xTZSearch( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4318{
4319  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4320  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4321  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4322  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4323 
4324  TZ_SEARCH_CONFIGURATION
4325 
4326  UInt uiSearchRange = m_iSearchRange;
4327  pcCU->clipMv( rcMv );
4328  rcMv >>= 2;
4329  // init TZSearchStruct
4330  IntTZSearchStruct cStruct;
4331  cStruct.iYStride    = iRefStride;
4332  cStruct.piRefY      = piRefY;
4333  cStruct.uiBestSad   = MAX_UINT;
4334 
4335  // set rcMv (Median predictor) as start point and as best point
4336  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4337 
4338  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4339  if ( bTestOtherPredictedMV )
4340  {
4341    for ( UInt index = 0; index < 3; index++ )
4342    {
4343      TComMv cMv = m_acMvPredictors[index];
4344      pcCU->clipMv( cMv );
4345      cMv >>= 2;
4346      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4347    }
4348  }
4349 
4350  // test whether zero Mv is better start point than Median predictor
4351  if ( bTestZeroVector )
4352  {
4353    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4354  }
4355 
4356  // start search
4357  Int  iDist = 0;
4358  Int  iStartX = cStruct.iBestX;
4359  Int  iStartY = cStruct.iBestY;
4360 
4361  // first search
4362  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4363  {
4364    if ( bFirstSearchDiamond == 1 )
4365    {
4366      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4367    }
4368    else
4369    {
4370      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4371    }
4372   
4373    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4374    {
4375      break;
4376    }
4377  }
4378 
4379  // test whether zero Mv is a better start point than Median predictor
4380  if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4381  {
4382    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4383    if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4384    {
4385      // test its neighborhood
4386      for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4387      {
4388        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
4389        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4390        {
4391          break;
4392        }
4393      }
4394    }
4395  }
4396 
4397  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4398  if ( cStruct.uiBestDistance == 1 )
4399  {
4400    cStruct.uiBestDistance = 0;
4401    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4402  }
4403 
4404  // raster search if distance is too big
4405  if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4406  {
4407    cStruct.uiBestDistance = iRaster;
4408    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4409    {
4410      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4411      {
4412        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4413      }
4414    }
4415  }
4416 
4417  // raster refinement
4418  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4419  {
4420    while ( cStruct.uiBestDistance > 0 )
4421    {
4422      iStartX = cStruct.iBestX;
4423      iStartY = cStruct.iBestY;
4424      if ( cStruct.uiBestDistance > 1 )
4425      {
4426        iDist = cStruct.uiBestDistance >>= 1;
4427        if ( bRasterRefinementDiamond == 1 )
4428        {
4429          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4430        }
4431        else
4432        {
4433          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4434        }
4435      }
4436     
4437      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4438      if ( cStruct.uiBestDistance == 1 )
4439      {
4440        cStruct.uiBestDistance = 0;
4441        if ( cStruct.ucPointNr != 0 )
4442        {
4443          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4444        }
4445      }
4446    }
4447  }
4448 
4449  // start refinement
4450  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4451  {
4452    while ( cStruct.uiBestDistance > 0 )
4453    {
4454      iStartX = cStruct.iBestX;
4455      iStartY = cStruct.iBestY;
4456      cStruct.uiBestDistance = 0;
4457      cStruct.ucPointNr = 0;
4458      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4459      {
4460        if ( bStarRefinementDiamond == 1 )
4461        {
4462          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4463        }
4464        else
4465        {
4466          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4467        }
4468        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4469        {
4470          break;
4471        }
4472      }
4473     
4474      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4475      if ( cStruct.uiBestDistance == 1 )
4476      {
4477        cStruct.uiBestDistance = 0;
4478        if ( cStruct.ucPointNr != 0 )
4479        {
4480          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4481        }
4482      }
4483    }
4484  }
4485 
4486  // write out best match
4487  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4488  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4489}
4490
4491Void TEncSearch::xPatternSearchFracDIF(TComDataCU* pcCU,
4492                                       TComPattern* pcPatternKey,
4493                                       Pel* piRefY,
4494                                       Int iRefStride,
4495                                       TComMv* pcMvInt,
4496                                       TComMv& rcMvHalf,
4497                                       TComMv& rcMvQter,
4498                                       UInt& ruiCost
4499                                       ,Bool biPred
4500                                       )
4501{
4502  //  Reference pattern initialization (integer scale)
4503  TComPattern cPatternRoi;
4504  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4505  cPatternRoi.initPattern( piRefY +  iOffset,
4506                          NULL,
4507                          NULL,
4508                          pcPatternKey->getROIYWidth(),
4509                          pcPatternKey->getROIYHeight(),
4510                          iRefStride,
4511                          0, 0 );
4512 
4513  //  Half-pel refinement
4514  xExtDIFUpSamplingH ( &cPatternRoi, biPred );
4515 
4516  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4517  TComMv baseRefMv(0, 0);
4518  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 2, rcMvHalf   );
4519 
4520  m_pcRdCost->setCostScale( 0 );
4521 
4522  xExtDIFUpSamplingQ ( &cPatternRoi, rcMvHalf, biPred );
4523  baseRefMv = rcMvHalf;
4524  baseRefMv <<= 1;
4525 
4526  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4527  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4528  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 1, rcMvQter );
4529}
4530
4531/** encode residual and calculate rate-distortion for a CU block
4532 * \param pcCU
4533 * \param pcYuvOrg
4534 * \param pcYuvPred
4535 * \param rpcYuvResi
4536 * \param rpcYuvResiBest
4537 * \param rpcYuvRec
4538 * \param bSkipRes
4539 * \returns Void
4540 */
4541Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred, TComYuv*& rpcYuvResi, TComYuv*& rpcYuvResiBest, TComYuv*& rpcYuvRec, Bool bSkipRes )
4542{
4543  if ( pcCU->isIntra(0) )
4544  {
4545    return;
4546  }
4547 
4548  Bool      bHighPass    = pcCU->getSlice()->getDepth() ? true : false;
4549  UInt      uiBits       = 0, uiBitsBest = 0;
4550  UInt      uiDistortion = 0, uiDistortionBest = 0;
4551 
4552  UInt      uiWidth      = pcCU->getWidth ( 0 );
4553  UInt      uiHeight     = pcCU->getHeight( 0 );
4554 
4555  //  No residual coding : SKIP mode
4556  if ( bSkipRes )
4557  {
4558    pcCU->setSkipFlagSubParts( true, 0, pcCU->getDepth(0) );
4559
4560    rpcYuvResi->clear();
4561   
4562    pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4563   
4564#if WEIGHTED_CHROMA_DISTORTION
4565    uiDistortion = m_pcRdCost->getDistPart(g_bitDepthY, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4566    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, TEXT_CHROMA_U )
4567    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, TEXT_CHROMA_V );
4568#else
4569    uiDistortion = m_pcRdCost->getDistPart(g_bitDepthY, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4570    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4571    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4572#endif
4573
4574    if( m_bUseSBACRD )
4575      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4576   
4577    m_pcEntropyCoder->resetBits();
4578    if (pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
4579    {
4580      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
4581    }
4582    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4583    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, true );
4584   
4585    uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4586    pcCU->getTotalBits()       = uiBits;
4587    pcCU->getTotalDistortion() = uiDistortion;
4588    pcCU->getTotalCost()       = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4589   
4590    if( m_bUseSBACRD )
4591      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4592   
4593    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4594    pcCU->setTrIdxSubParts( 0, 0, pcCU->getDepth(0) );
4595   
4596    return;
4597  }
4598 
4599  //  Residual coding.
4600  Int    qp, qpBest = 0, qpMin, qpMax;
4601  Double  dCost, dCostBest = MAX_DOUBLE;
4602 
4603  UInt uiTrLevel = 0;
4604  if( (pcCU->getWidth(0) > pcCU->getSlice()->getSPS()->getMaxTrSize()) )
4605  {
4606    while( pcCU->getWidth(0) > (pcCU->getSlice()->getSPS()->getMaxTrSize()<<uiTrLevel) ) uiTrLevel++;
4607  }
4608  UInt uiMaxTrMode = 1 + uiTrLevel;
4609 
4610  while((uiWidth>>uiMaxTrMode) < (g_uiMaxCUWidth>>g_uiMaxCUDepth)) uiMaxTrMode--;
4611 
4612  qpMin =  bHighPass ? Clip3( -pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, pcCU->getQP(0) - m_iMaxDeltaQP ) : pcCU->getQP( 0 );
4613  qpMax =  bHighPass ? Clip3( -pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, pcCU->getQP(0) + m_iMaxDeltaQP ) : pcCU->getQP( 0 );
4614
4615  rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4616
4617  for ( qp = qpMin; qp <= qpMax; qp++ )
4618  {
4619    dCost = 0.;
4620    uiBits = 0;
4621    uiDistortion = 0;
4622    if( m_bUseSBACRD )
4623    {
4624      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4625    }
4626   
4627    UInt uiZeroDistortion = 0;
4628    xEstimateResidualQT( pcCU, 0, 0, 0, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4629   
4630    m_pcEntropyCoder->resetBits();
4631    m_pcEntropyCoder->encodeQtRootCbfZero( pcCU );
4632    UInt zeroResiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4633    Double dZeroCost = m_pcRdCost->calcRdCost( zeroResiBits, uiZeroDistortion );
4634    if(pcCU->isLosslessCoded( 0 ))
4635    { 
4636      dZeroCost = dCost + 1;
4637    }
4638    if ( dZeroCost < dCost )
4639    {
4640      dCost        = dZeroCost;
4641      uiBits       = 0;
4642      uiDistortion = uiZeroDistortion;
4643     
4644      const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4645      ::memset( pcCU->getTransformIdx()      , 0, uiQPartNum * sizeof(UChar) );
4646      ::memset( pcCU->getCbf( TEXT_LUMA )    , 0, uiQPartNum * sizeof(UChar) );
4647      ::memset( pcCU->getCbf( TEXT_CHROMA_U ), 0, uiQPartNum * sizeof(UChar) );
4648      ::memset( pcCU->getCbf( TEXT_CHROMA_V ), 0, uiQPartNum * sizeof(UChar) );
4649      ::memset( pcCU->getCoeffY()            , 0, uiWidth * uiHeight * sizeof( TCoeff )      );
4650      ::memset( pcCU->getCoeffCb()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4651      ::memset( pcCU->getCoeffCr()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4652      pcCU->setTransformSkipSubParts ( 0, 0, 0, 0, pcCU->getDepth(0) );
4653    }
4654    else
4655    {
4656      xSetResidualQTData( pcCU, 0, 0, 0, NULL, pcCU->getDepth(0), false );
4657    }
4658   
4659    if( m_bUseSBACRD )
4660    {
4661      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4662    }
4663#if 0 // check
4664    {
4665      m_pcEntropyCoder->resetBits();
4666      m_pcEntropyCoder->encodeCoeff( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
4667      const UInt uiBitsForCoeff = m_pcEntropyCoder->getNumberOfWrittenBits();
4668      if( m_bUseSBACRD )
4669      {
4670        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4671      }
4672      if( uiBitsForCoeff != uiBits )
4673        assert( 0 );
4674    }
4675#endif
4676    uiBits = 0;
4677    {
4678      TComYuv *pDummy = NULL;
4679      xAddSymbolBitsInter( pcCU, 0, 0, uiBits, pDummy, NULL, pDummy );
4680    }
4681   
4682   
4683    Double dExactCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4684    dCost = dExactCost;
4685   
4686    if ( dCost < dCostBest )
4687    {
4688      if ( !pcCU->getQtRootCbf( 0 ) )
4689      {
4690        rpcYuvResiBest->clear();
4691      }
4692      else
4693      {
4694        xSetResidualQTData( pcCU, 0, 0, 0, rpcYuvResiBest, pcCU->getDepth(0), true );
4695      }
4696     
4697      if( qpMin != qpMax && qp != qpMax )
4698      {
4699        const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4700        ::memcpy( m_puhQTTempTrIdx, pcCU->getTransformIdx(),        uiQPartNum * sizeof(UChar) );
4701        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA ),     uiQPartNum * sizeof(UChar) );
4702        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPartNum * sizeof(UChar) );
4703        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPartNum * sizeof(UChar) );
4704        ::memcpy( m_pcQTTempCoeffY,  pcCU->getCoeffY(),  uiWidth * uiHeight * sizeof( TCoeff )      );
4705        ::memcpy( m_pcQTTempCoeffCb, pcCU->getCoeffCb(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4706        ::memcpy( m_pcQTTempCoeffCr, pcCU->getCoeffCr(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4707#if ADAPTIVE_QP_SELECTION
4708        ::memcpy( m_pcQTTempArlCoeffY,  pcCU->getArlCoeffY(),  uiWidth * uiHeight * sizeof( Int )      );
4709        ::memcpy( m_pcQTTempArlCoeffCb, pcCU->getArlCoeffCb(), uiWidth * uiHeight * sizeof( Int ) >> 2 );
4710        ::memcpy( m_pcQTTempArlCoeffCr, pcCU->getArlCoeffCr(), uiWidth * uiHeight * sizeof( Int ) >> 2 );
4711#endif
4712        ::memcpy( m_puhQTTempTransformSkipFlag[0], pcCU->getTransformSkip(TEXT_LUMA),     uiQPartNum * sizeof( UChar ) );
4713        ::memcpy( m_puhQTTempTransformSkipFlag[1], pcCU->getTransformSkip(TEXT_CHROMA_U), uiQPartNum * sizeof( UChar ) );
4714        ::memcpy( m_puhQTTempTransformSkipFlag[2], pcCU->getTransformSkip(TEXT_CHROMA_V), uiQPartNum * sizeof( UChar ) );
4715      }
4716      uiBitsBest       = uiBits;
4717      uiDistortionBest = uiDistortion;
4718      dCostBest        = dCost;
4719      qpBest           = qp;
4720      if( m_bUseSBACRD )
4721      {
4722        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4723      }
4724    }
4725  }
4726 
4727  assert ( dCostBest != MAX_DOUBLE );
4728 
4729  if( qpMin != qpMax && qpBest != qpMax )
4730  {
4731    if( m_bUseSBACRD )
4732    {
4733      assert( 0 ); // check
4734      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4735    }
4736    // copy best cbf and trIdx to pcCU
4737    const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4738    ::memcpy( pcCU->getTransformIdx(),       m_puhQTTempTrIdx,  uiQPartNum * sizeof(UChar) );
4739    ::memcpy( pcCU->getCbf( TEXT_LUMA ),     m_puhQTTempCbf[0], uiQPartNum * sizeof(UChar) );
4740    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPartNum * sizeof(UChar) );
4741    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPartNum * sizeof(UChar) );
4742    ::memcpy( pcCU->getCoeffY(),  m_pcQTTempCoeffY,  uiWidth * uiHeight * sizeof( TCoeff )      );
4743    ::memcpy( pcCU->getCoeffCb(), m_pcQTTempCoeffCb, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4744    ::memcpy( pcCU->getCoeffCr(), m_pcQTTempCoeffCr, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4745#if ADAPTIVE_QP_SELECTION
4746    ::memcpy( pcCU->getArlCoeffY(),  m_pcQTTempArlCoeffY,  uiWidth * uiHeight * sizeof( Int )      );
4747    ::memcpy( pcCU->getArlCoeffCb(), m_pcQTTempArlCoeffCb, uiWidth * uiHeight * sizeof( Int ) >> 2 );
4748    ::memcpy( pcCU->getArlCoeffCr(), m_pcQTTempArlCoeffCr, uiWidth * uiHeight * sizeof( Int ) >> 2 );
4749#endif
4750    ::memcpy( pcCU->getTransformSkip(TEXT_LUMA),     m_puhQTTempTransformSkipFlag[0], uiQPartNum * sizeof( UChar ) );
4751    ::memcpy( pcCU->getTransformSkip(TEXT_CHROMA_U), m_puhQTTempTransformSkipFlag[1], uiQPartNum * sizeof( UChar ) );
4752    ::memcpy( pcCU->getTransformSkip(TEXT_CHROMA_V), m_puhQTTempTransformSkipFlag[2], uiQPartNum * sizeof( UChar ) );
4753  }
4754  rpcYuvRec->addClip ( pcYuvPred, rpcYuvResiBest, 0, uiWidth );
4755 
4756  // update with clipped distortion and cost (qp estimation loop uses unclipped values)
4757#if WEIGHTED_CHROMA_DISTORTION
4758    uiDistortionBest = m_pcRdCost->getDistPart(g_bitDepthY, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4759    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, TEXT_CHROMA_U )
4760    + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, TEXT_CHROMA_V );
4761#else
4762  uiDistortionBest = m_pcRdCost->getDistPart(g_bitDepthY, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4763  + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4764  + m_pcRdCost->getDistPart(g_bitDepthC, rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4765#endif
4766  dCostBest = m_pcRdCost->calcRdCost( uiBitsBest, uiDistortionBest );
4767 
4768  pcCU->getTotalBits()       = uiBitsBest;
4769  pcCU->getTotalDistortion() = uiDistortionBest;
4770  pcCU->getTotalCost()       = dCostBest;
4771 
4772  if ( pcCU->isSkipped(0) )
4773  {
4774    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4775  }
4776 
4777  pcCU->setQPSubParts( qpBest, 0, pcCU->getDepth(0) );
4778}
4779
4780Void TEncSearch::xEstimateResidualQT( TComDataCU* pcCU, UInt uiQuadrant, UInt uiAbsPartIdx, UInt absTUPartIdx, TComYuv* pcResi, const UInt uiDepth, Double &rdCost, UInt &ruiBits, UInt &ruiDist, UInt *puiZeroDist )
4781{
4782  const UInt uiTrMode = uiDepth - pcCU->getDepth( 0 );
4783 
4784  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
4785  const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
4786 
4787  UInt SplitFlag = ((pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && ( pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N ));
4788  Bool bCheckFull;
4789  if ( SplitFlag && uiDepth == pcCU->getDepth(uiAbsPartIdx) && ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ) )
4790     bCheckFull = false;
4791  else
4792     bCheckFull =  ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
4793
4794  const Bool bCheckSplit  = ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
4795 
4796  assert( bCheckFull || bCheckSplit );
4797 
4798  Bool  bCodeChroma   = true;
4799  UInt  uiTrModeC     = uiTrMode;
4800  UInt  uiLog2TrSizeC = uiLog2TrSize-1;
4801  if( uiLog2TrSize == 2 )
4802  {
4803    uiLog2TrSizeC++;
4804    uiTrModeC    --;
4805    UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
4806    bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
4807  }
4808 
4809  const UInt uiSetCbf = 1 << uiTrMode;
4810  // code full block
4811  Double dSingleCost = MAX_DOUBLE;
4812  UInt uiSingleBits = 0;
4813  UInt uiSingleDist = 0;
4814  UInt uiAbsSumY = 0, uiAbsSumU = 0, uiAbsSumV = 0;
4815  UInt uiBestTransformMode[3] = {0};
4816
4817  if( m_bUseSBACRD )
4818  {
4819    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4820  }
4821 
4822  if( bCheckFull )
4823  {
4824    const UInt uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
4825    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
4826    TCoeff *pcCoeffCurrY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
4827    TCoeff *pcCoeffCurrU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4828    TCoeff *pcCoeffCurrV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4829#if ADAPTIVE_QP_SELECTION   
4830    Int *pcArlCoeffCurrY = m_ppcQTTempArlCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
4831    Int *pcArlCoeffCurrU = m_ppcQTTempArlCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4832    Int *pcArlCoeffCurrV = m_ppcQTTempArlCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);   
4833#endif
4834   
4835    Int trWidth = 0, trHeight = 0, trWidthC = 0, trHeightC = 0;
4836    UInt absTUPartIdxC = uiAbsPartIdx;
4837
4838    trWidth  = trHeight  = 1 << uiLog2TrSize;
4839    trWidthC = trHeightC = 1 <<uiLog2TrSizeC;
4840    pcCU->setTrIdxSubParts( uiDepth - pcCU->getDepth( 0 ), uiAbsPartIdx, uiDepth );
4841    Double minCostY = MAX_DOUBLE;
4842    Double minCostU = MAX_DOUBLE;
4843    Double minCostV = MAX_DOUBLE;
4844    Bool checkTransformSkipY  = pcCU->getSlice()->getPPS()->getUseTransformSkip() && trWidth == 4 && trHeight == 4;
4845    Bool checkTransformSkipUV = pcCU->getSlice()->getPPS()->getUseTransformSkip() && trWidthC == 4 && trHeightC == 4;
4846
4847    checkTransformSkipY         &= (!pcCU->isLosslessCoded(0));
4848    checkTransformSkipUV        &= (!pcCU->isLosslessCoded(0));
4849
4850    pcCU->setTransformSkipSubParts ( 0, TEXT_LUMA, uiAbsPartIdx, uiDepth ); 
4851    if( bCodeChroma )
4852    {
4853      pcCU->setTransformSkipSubParts ( 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC ); 
4854      pcCU->setTransformSkipSubParts ( 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC ); 
4855    }
4856
4857    if (m_pcEncCfg->getUseRDOQ())
4858    {
4859      m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, trWidth, trHeight, TEXT_LUMA );       
4860    }
4861
4862    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
4863
4864#if RDOQ_CHROMA_LAMBDA
4865    m_pcTrQuant->selectLambda(TEXT_LUMA); 
4866#endif
4867    m_pcTrQuant->transformNxN( pcCU, pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride (), pcCoeffCurrY, 
4868#if ADAPTIVE_QP_SELECTION
4869                                 pcArlCoeffCurrY, 
4870#endif     
4871                                 trWidth,   trHeight,    uiAbsSumY, TEXT_LUMA,     uiAbsPartIdx );
4872   
4873    pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
4874   
4875    if( bCodeChroma )
4876    {
4877      if (m_pcEncCfg->getUseRDOQ())
4878      {
4879        m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, trWidthC, trHeightC, TEXT_CHROMA );         
4880      }
4881
4882      Int curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCbQpOffset() + pcCU->getSlice()->getSliceQpDeltaCb();
4883      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
4884
4885#if RDOQ_CHROMA_LAMBDA
4886      m_pcTrQuant->selectLambda(TEXT_CHROMA); 
4887#endif
4888
4889      m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrU, 
4890#if ADAPTIVE_QP_SELECTION
4891                                 pcArlCoeffCurrU, 
4892#endif       
4893                                 trWidthC, trHeightC, uiAbsSumU, TEXT_CHROMA_U, uiAbsPartIdx );
4894
4895      curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCrQpOffset() + pcCU->getSlice()->getSliceQpDeltaCr();
4896      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
4897      m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrV, 
4898#if ADAPTIVE_QP_SELECTION
4899                                 pcArlCoeffCurrV, 
4900#endif       
4901                                 trWidthC, trHeightC, uiAbsSumV, TEXT_CHROMA_V, uiAbsPartIdx );
4902
4903      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
4904      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
4905    }
4906   
4907    m_pcEntropyCoder->resetBits();
4908   
4909    {
4910      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
4911    }
4912   
4913    m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx,  trWidth,  trHeight,    uiDepth, TEXT_LUMA );
4914    const UInt uiSingleBitsY = m_pcEntropyCoder->getNumberOfWrittenBits();
4915   
4916    UInt uiSingleBitsU = 0;
4917    UInt uiSingleBitsV = 0;
4918    if( bCodeChroma )
4919    {
4920      {
4921        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode );
4922      }
4923      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_U );
4924      uiSingleBitsU = m_pcEntropyCoder->getNumberOfWrittenBits() - uiSingleBitsY;
4925     
4926      {
4927        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode );
4928      }
4929      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_V );
4930      uiSingleBitsV = m_pcEntropyCoder->getNumberOfWrittenBits() - ( uiSingleBitsY + uiSingleBitsU );
4931    }
4932   
4933    const UInt uiNumSamplesLuma = 1 << (uiLog2TrSize<<1);
4934    const UInt uiNumSamplesChro = 1 << (uiLog2TrSizeC<<1);
4935   
4936    ::memset( m_pTempPel, 0, sizeof( Pel ) * uiNumSamplesLuma ); // not necessary needed for inside of recursion (only at the beginning)
4937   
4938    UInt uiDistY = m_pcRdCost->getDistPart(g_bitDepthY, m_pTempPel, trWidth, pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride(), trWidth, trHeight ); // initialized with zero residual destortion
4939
4940    if ( puiZeroDist )
4941    {
4942      *puiZeroDist += uiDistY;
4943    }
4944    if( uiAbsSumY )
4945    {
4946      Pel *pcResiCurrY = m_pcQTTempTComYuv[ uiQTTempAccessLayer ].getLumaAddr( absTUPartIdx );
4947
4948      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
4949
4950      Int scalingListType = 3 + g_eTTable[(Int)TEXT_LUMA];
4951      assert(scalingListType < 6);     
4952      m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_LUMA,REG_DCT, pcResiCurrY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),  pcCoeffCurrY, trWidth, trHeight, scalingListType );//this is for inter mode only
4953      const UInt uiNonzeroDistY = m_pcRdCost->getDistPart(g_bitDepthY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( absTUPartIdx ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),
4954      pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride(), trWidth,trHeight );
4955      if (pcCU->isLosslessCoded(0)) 
4956      {
4957        uiDistY = uiNonzeroDistY;
4958      }
4959      else
4960      {
4961        const Double singleCostY = m_pcRdCost->calcRdCost( uiSingleBitsY, uiNonzeroDistY );
4962        m_pcEntropyCoder->resetBits();
4963        m_pcEntropyCoder->encodeQtCbfZero( pcCU, TEXT_LUMA,     uiTrMode );
4964        const UInt uiNullBitsY   = m_pcEntropyCoder->getNumberOfWrittenBits();
4965        const Double nullCostY   = m_pcRdCost->calcRdCost( uiNullBitsY, uiDistY );
4966        if( nullCostY < singleCostY ) 
4967        {   
4968          uiAbsSumY = 0;
4969          ::memset( pcCoeffCurrY, 0, sizeof( TCoeff ) * uiNumSamplesLuma );
4970          if( checkTransformSkipY )
4971          {
4972            minCostY = nullCostY;
4973          }
4974        }
4975        else
4976        {
4977          uiDistY = uiNonzeroDistY;
4978          if( checkTransformSkipY )
4979          {
4980            minCostY = singleCostY;
4981          }
4982        }
4983      }
4984    }
4985    else if( checkTransformSkipY )
4986    {
4987      m_pcEntropyCoder->resetBits();
4988      m_pcEntropyCoder->encodeQtCbfZero( pcCU, TEXT_LUMA, uiTrMode );
4989      const UInt uiNullBitsY = m_pcEntropyCoder->getNumberOfWrittenBits();
4990      minCostY = m_pcRdCost->calcRdCost( uiNullBitsY, uiDistY );
4991    }
4992
4993    if( !uiAbsSumY )
4994    {
4995      Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( absTUPartIdx );
4996      const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride();
4997      for( UInt uiY = 0; uiY < trHeight; ++uiY )
4998      {
4999        ::memset( pcPtr, 0, sizeof( Pel ) * trWidth );
5000        pcPtr += uiStride;
5001      } 
5002    }
5003   
5004    UInt uiDistU = 0;
5005    UInt uiDistV = 0;
5006    if( bCodeChroma )
5007    {
5008      uiDistU = m_pcRdCost->getDistPart(g_bitDepthC, m_pTempPel, trWidthC, pcResi->getCbAddr( absTUPartIdxC ), pcResi->getCStride(), trWidthC, trHeightC
5009#if WEIGHTED_CHROMA_DISTORTION
5010                                        , TEXT_CHROMA_U
5011#endif
5012                                        ); // initialized with zero residual destortion
5013      if ( puiZeroDist )
5014      {
5015        *puiZeroDist += uiDistU;
5016      }
5017      if( uiAbsSumU )
5018      {
5019        Pel *pcResiCurrU = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC );
5020
5021        Int curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCbQpOffset() + pcCU->getSlice()->getSliceQpDeltaCb();
5022        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
5023
5024        Int scalingListType = 3 + g_eTTable[(Int)TEXT_CHROMA_U];
5025        assert(scalingListType < 6);
5026        m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_CHROMA,REG_DCT, pcResiCurrU, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrU, trWidthC, trHeightC, scalingListType  );
5027       
5028        const UInt uiNonzeroDistU = m_pcRdCost->getDistPart(g_bitDepthC, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC), m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(),
5029                                                            pcResi->getCbAddr( absTUPartIdxC), pcResi->getCStride(), trWidthC, trHeightC
5030#if WEIGHTED_CHROMA_DISTORTION
5031                                                            , TEXT_CHROMA_U
5032#endif
5033                                                            );
5034
5035        if(pcCU->isLosslessCoded(0)) 
5036        {
5037          uiDistU = uiNonzeroDistU;
5038        }
5039        else
5040        {
5041          const Double dSingleCostU = m_pcRdCost->calcRdCost( uiSingleBitsU, uiNonzeroDistU );
5042          m_pcEntropyCoder->resetBits();
5043          m_pcEntropyCoder->encodeQtCbfZero( pcCU, TEXT_CHROMA_U,     uiTrMode );
5044          const UInt uiNullBitsU    = m_pcEntropyCoder->getNumberOfWrittenBits();
5045          const Double dNullCostU   = m_pcRdCost->calcRdCost( uiNullBitsU, uiDistU );
5046          if( dNullCostU < dSingleCostU )
5047          {
5048            uiAbsSumU = 0;
5049            ::memset( pcCoeffCurrU, 0, sizeof( TCoeff ) * uiNumSamplesChro );
5050            if( checkTransformSkipUV )
5051            {
5052              minCostU = dNullCostU;
5053            }
5054          }
5055          else
5056          {
5057            uiDistU = uiNonzeroDistU;
5058            if( checkTransformSkipUV )
5059            {
5060              minCostU = dSingleCostU;
5061            }
5062          }
5063        }
5064      }
5065      else if( checkTransformSkipUV )
5066      {
5067        m_pcEntropyCoder->resetBits();
5068        m_pcEntropyCoder->encodeQtCbfZero( pcCU, TEXT_CHROMA_U, uiTrModeC );
5069        const UInt uiNullBitsU = m_pcEntropyCoder->getNumberOfWrittenBits();
5070        minCostU = m_pcRdCost->calcRdCost( uiNullBitsU, uiDistU );
5071      }
5072      if( !uiAbsSumU )
5073      {
5074        Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC );
5075          const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride();
5076        for( UInt uiY = 0; uiY < trHeightC; ++uiY )
5077        {
5078          ::memset( pcPtr, 0, sizeof(Pel) * trWidthC );
5079          pcPtr += uiStride;
5080        }
5081      }
5082     
5083      uiDistV = m_pcRdCost->getDistPart(g_bitDepthC, m_pTempPel, trWidthC, pcResi->getCrAddr( absTUPartIdxC), pcResi->getCStride(), trWidthC, trHeightC
5084#if WEIGHTED_CHROMA_DISTORTION
5085                                        , TEXT_CHROMA_V
5086#endif
5087                                        ); // initialized with zero residual destortion
5088      if ( puiZeroDist )
5089      {
5090        *puiZeroDist += uiDistV;
5091      }
5092      if( uiAbsSumV )
5093      {
5094        Pel *pcResiCurrV = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( absTUPartIdxC );
5095        Int curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCrQpOffset() + pcCU->getSlice()->getSliceQpDeltaCr();
5096        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
5097
5098        Int scalingListType = 3 + g_eTTable[(Int)TEXT_CHROMA_V];
5099        assert(scalingListType < 6);
5100        m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_CHROMA,REG_DCT, pcResiCurrV, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrV, trWidthC, trHeightC, scalingListType );
5101       
5102        const UInt uiNonzeroDistV = m_pcRdCost->getDistPart(g_bitDepthC, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( absTUPartIdxC ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(),
5103                                                            pcResi->getCrAddr( absTUPartIdxC ), pcResi->getCStride(), trWidthC, trHeightC
5104#if WEIGHTED_CHROMA_DISTORTION
5105                                                            , TEXT_CHROMA_V
5106#endif
5107                                                            );
5108        if (pcCU->isLosslessCoded(0)) 
5109        {
5110          uiDistV = uiNonzeroDistV;
5111        }
5112        else
5113        {
5114          const Double dSingleCostV = m_pcRdCost->calcRdCost( uiSingleBitsV, uiNonzeroDistV );
5115          m_pcEntropyCoder->resetBits();
5116          m_pcEntropyCoder->encodeQtCbfZero( pcCU, TEXT_CHROMA_V,     uiTrMode );
5117          const UInt uiNullBitsV    = m_pcEntropyCoder->getNumberOfWrittenBits();
5118          const Double dNullCostV   = m_pcRdCost->calcRdCost( uiNullBitsV, uiDistV );
5119          if( dNullCostV < dSingleCostV )
5120          {
5121            uiAbsSumV = 0;
5122            ::memset( pcCoeffCurrV, 0, sizeof( TCoeff ) * uiNumSamplesChro );
5123            if( checkTransformSkipUV )
5124            {
5125              minCostV = dNullCostV;
5126            }
5127          }
5128          else
5129          {
5130            uiDistV = uiNonzeroDistV;
5131            if( checkTransformSkipUV )
5132            {
5133              minCostV = dSingleCostV;
5134            }
5135          }
5136        }
5137      }
5138      else if( checkTransformSkipUV )
5139      {
5140        m_pcEntropyCoder->resetBits();
5141        m_pcEntropyCoder->encodeQtCbfZero( pcCU, TEXT_CHROMA_V, uiTrModeC );
5142        const UInt uiNullBitsV = m_pcEntropyCoder->getNumberOfWrittenBits();
5143        minCostV = m_pcRdCost->calcRdCost( uiNullBitsV, uiDistV );
5144      }
5145      if( !uiAbsSumV )
5146      {
5147        Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( absTUPartIdxC );
5148        const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride();
5149        for( UInt uiY = 0; uiY < trHeightC; ++uiY )
5150        {   
5151          ::memset( pcPtr, 0, sizeof(Pel) * trWidthC );
5152          pcPtr += uiStride;
5153        }
5154      }
5155    }
5156    pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5157    if( bCodeChroma )
5158    {
5159      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5160      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5161    }
5162
5163    if( checkTransformSkipY )
5164    {
5165      UInt uiNonzeroDistY, uiAbsSumTransformSkipY;
5166      Double dSingleCostY;
5167
5168      Pel *pcResiCurrY = m_pcQTTempTComYuv[ uiQTTempAccessLayer ].getLumaAddr( absTUPartIdx );
5169      UInt resiYStride = m_pcQTTempTComYuv[ uiQTTempAccessLayer ].getStride();
5170
5171      TCoeff bestCoeffY[32*32];
5172      memcpy( bestCoeffY, pcCoeffCurrY, sizeof(TCoeff) * uiNumSamplesLuma );
5173     
5174#if ADAPTIVE_QP_SELECTION
5175      TCoeff bestArlCoeffY[32*32];
5176      memcpy( bestArlCoeffY, pcArlCoeffCurrY, sizeof(TCoeff) * uiNumSamplesLuma );
5177#endif
5178
5179      Pel bestResiY[32*32];
5180      for ( Int i = 0; i < trHeight; ++i )
5181      {
5182        memcpy( &bestResiY[i*trWidth], pcResiCurrY+i*resiYStride, sizeof(Pel) * trWidth );
5183      }
5184
5185      if( m_bUseSBACRD )
5186      {
5187        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5188      }
5189
5190      pcCU->setTransformSkipSubParts ( 1, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5191
5192      if (m_pcEncCfg->getUseRDOQTS())
5193      {
5194        m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, trWidth, trHeight, TEXT_LUMA );       
5195      }
5196
5197      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
5198
5199#if RDOQ_CHROMA_LAMBDA
5200      m_pcTrQuant->selectLambda(TEXT_LUMA);
5201#endif
5202      m_pcTrQuant->transformNxN( pcCU, pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride (), pcCoeffCurrY, 
5203#if ADAPTIVE_QP_SELECTION
5204        pcArlCoeffCurrY, 
5205#endif     
5206        trWidth,   trHeight,    uiAbsSumTransformSkipY, TEXT_LUMA, uiAbsPartIdx, true );
5207      pcCU->setCbfSubParts( uiAbsSumTransformSkipY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5208
5209      if( uiAbsSumTransformSkipY != 0 )
5210      {
5211        m_pcEntropyCoder->resetBits();
5212        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, uiTrMode );
5213        m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA );
5214        const UInt uiTsSingleBitsY = m_pcEntropyCoder->getNumberOfWrittenBits();
5215
5216        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
5217
5218        Int scalingListType = 3 + g_eTTable[(Int)TEXT_LUMA];
5219        assert(scalingListType < 6);     
5220
5221        m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_LUMA,REG_DCT, pcResiCurrY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),  pcCoeffCurrY, trWidth, trHeight, scalingListType, true );
5222
5223        uiNonzeroDistY = m_pcRdCost->getDistPart(g_bitDepthY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( absTUPartIdx ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),
5224          pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride(), trWidth, trHeight );
5225
5226        dSingleCostY = m_pcRdCost->calcRdCost( uiTsSingleBitsY, uiNonzeroDistY );
5227      }
5228
5229      if( !uiAbsSumTransformSkipY || minCostY < dSingleCostY )
5230      {
5231        pcCU->setTransformSkipSubParts ( 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5232        memcpy( pcCoeffCurrY, bestCoeffY, sizeof(TCoeff) * uiNumSamplesLuma );
5233#if ADAPTIVE_QP_SELECTION
5234        memcpy( pcArlCoeffCurrY, bestArlCoeffY, sizeof(TCoeff) * uiNumSamplesLuma );
5235#endif
5236        for( Int i = 0; i < trHeight; ++i )
5237        {
5238          memcpy( pcResiCurrY+i*resiYStride, &bestResiY[i*trWidth], sizeof(Pel) * trWidth );
5239        }
5240      }
5241      else
5242      {
5243        uiDistY = uiNonzeroDistY;
5244        uiAbsSumY = uiAbsSumTransformSkipY;
5245        uiBestTransformMode[0] = 1;
5246      }
5247
5248      pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5249    }
5250
5251    if( bCodeChroma && checkTransformSkipUV  )
5252    {
5253      UInt uiNonzeroDistU, uiNonzeroDistV, uiAbsSumTransformSkipU, uiAbsSumTransformSkipV;
5254      Double dSingleCostU, dSingleCostV;
5255
5256      Pel *pcResiCurrU = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC );
5257      Pel *pcResiCurrV = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( absTUPartIdxC );
5258      UInt resiCStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride();
5259
5260      TCoeff bestCoeffU[32*32], bestCoeffV[32*32];
5261      memcpy( bestCoeffU, pcCoeffCurrU, sizeof(TCoeff) * uiNumSamplesChro );
5262      memcpy( bestCoeffV, pcCoeffCurrV, sizeof(TCoeff) * uiNumSamplesChro );
5263
5264#if ADAPTIVE_QP_SELECTION
5265      TCoeff bestArlCoeffU[32*32], bestArlCoeffV[32*32];
5266      memcpy( bestArlCoeffU, pcArlCoeffCurrU, sizeof(TCoeff) * uiNumSamplesChro );
5267      memcpy( bestArlCoeffV, pcArlCoeffCurrV, sizeof(TCoeff) * uiNumSamplesChro );
5268#endif
5269
5270      Pel bestResiU[32*32], bestResiV[32*32];
5271      for (Int i = 0; i < trHeightC; ++i )
5272      {
5273        memcpy( &bestResiU[i*trWidthC], pcResiCurrU+i*resiCStride, sizeof(Pel) * trWidthC );
5274        memcpy( &bestResiV[i*trWidthC], pcResiCurrV+i*resiCStride, sizeof(Pel) * trWidthC );
5275      }
5276
5277      if( m_bUseSBACRD )
5278      {
5279        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5280      }
5281
5282      pcCU->setTransformSkipSubParts ( 1, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC ); 
5283      pcCU->setTransformSkipSubParts ( 1, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5284
5285      if (m_pcEncCfg->getUseRDOQTS())
5286      {
5287        m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, trWidthC, trHeightC, TEXT_CHROMA );         
5288      }
5289
5290      Int curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCbQpOffset() + pcCU->getSlice()->getSliceQpDeltaCb();
5291      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
5292
5293#if RDOQ_CHROMA_LAMBDA
5294      m_pcTrQuant->selectLambda(TEXT_CHROMA); 
5295#endif
5296
5297      m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrU, 
5298#if ADAPTIVE_QP_SELECTION
5299        pcArlCoeffCurrU, 
5300#endif       
5301        trWidthC, trHeightC, uiAbsSumTransformSkipU, TEXT_CHROMA_U, uiAbsPartIdx, true );
5302      curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCrQpOffset() + pcCU->getSlice()->getSliceQpDeltaCr();
5303      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
5304      m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrV, 
5305#if ADAPTIVE_QP_SELECTION
5306        pcArlCoeffCurrV, 
5307#endif       
5308        trWidthC, trHeightC, uiAbsSumTransformSkipV, TEXT_CHROMA_V, uiAbsPartIdx, true );
5309
5310      pcCU->setCbfSubParts( uiAbsSumTransformSkipU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5311      pcCU->setCbfSubParts( uiAbsSumTransformSkipV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5312
5313      m_pcEntropyCoder->resetBits();
5314      uiSingleBitsU = 0;
5315      uiSingleBitsV = 0;
5316
5317      if( uiAbsSumTransformSkipU )
5318      {
5319        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode );
5320        m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_U );
5321        uiSingleBitsU = m_pcEntropyCoder->getNumberOfWrittenBits();   
5322
5323        curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCbQpOffset() + pcCU->getSlice()->getSliceQpDeltaCb();
5324        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
5325
5326        Int scalingListType = 3 + g_eTTable[(Int)TEXT_CHROMA_U];
5327        assert(scalingListType < 6);
5328
5329        m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_CHROMA,REG_DCT, pcResiCurrU, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrU, trWidthC, trHeightC, scalingListType, true  );
5330
5331        uiNonzeroDistU = m_pcRdCost->getDistPart(g_bitDepthC, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC), m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(),
5332                                                 pcResi->getCbAddr( absTUPartIdxC), pcResi->getCStride(), trWidthC, trHeightC
5333#if WEIGHTED_CHROMA_DISTORTION
5334                                                 , TEXT_CHROMA_U
5335#endif
5336                                                 );
5337
5338        dSingleCostU = m_pcRdCost->calcRdCost( uiSingleBitsU, uiNonzeroDistU );
5339      }
5340
5341      if( !uiAbsSumTransformSkipU || minCostU < dSingleCostU )
5342      {
5343        pcCU->setTransformSkipSubParts ( 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC ); 
5344
5345        memcpy( pcCoeffCurrU, bestCoeffU, sizeof (TCoeff) * uiNumSamplesChro );
5346#if ADAPTIVE_QP_SELECTION
5347        memcpy( pcArlCoeffCurrU, bestArlCoeffU, sizeof (TCoeff) * uiNumSamplesChro );
5348#endif
5349        for( Int i = 0; i < trHeightC; ++i )
5350        {
5351          memcpy( pcResiCurrU+i*resiCStride, &bestResiU[i*trWidthC], sizeof(Pel) * trWidthC );
5352        }
5353      }
5354      else
5355      {
5356        uiDistU = uiNonzeroDistU;
5357        uiAbsSumU = uiAbsSumTransformSkipU;
5358        uiBestTransformMode[1] = 1;
5359      }
5360
5361      if( uiAbsSumTransformSkipV )
5362      {
5363        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode );
5364        m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_V );
5365        uiSingleBitsV = m_pcEntropyCoder->getNumberOfWrittenBits() - uiSingleBitsU;
5366
5367        curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCrQpOffset() + pcCU->getSlice()->getSliceQpDeltaCr();
5368        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
5369
5370        Int scalingListType = 3 + g_eTTable[(Int)TEXT_CHROMA_V];
5371        assert(scalingListType < 6);
5372
5373        m_pcTrQuant->invtransformNxN( pcCU->getCUTransquantBypass(uiAbsPartIdx), TEXT_CHROMA,REG_DCT, pcResiCurrV, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrV, trWidthC, trHeightC, scalingListType, true );
5374
5375        uiNonzeroDistV = m_pcRdCost->getDistPart(g_bitDepthC, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( absTUPartIdxC ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(),
5376                                                 pcResi->getCrAddr( absTUPartIdxC ), pcResi->getCStride(), trWidthC, trHeightC
5377#if WEIGHTED_CHROMA_DISTORTION
5378                                                 , TEXT_CHROMA_V
5379#endif
5380                                                 );
5381
5382        dSingleCostV = m_pcRdCost->calcRdCost( uiSingleBitsV, uiNonzeroDistV );
5383      }
5384
5385      if( !uiAbsSumTransformSkipV || minCostV < dSingleCostV )
5386      {
5387        pcCU->setTransformSkipSubParts ( 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC ); 
5388
5389        memcpy( pcCoeffCurrV, bestCoeffV, sizeof(TCoeff) * uiNumSamplesChro );
5390#if ADAPTIVE_QP_SELECTION
5391        memcpy( pcArlCoeffCurrV, bestArlCoeffV, sizeof(TCoeff) * uiNumSamplesChro );
5392#endif
5393        for( Int i = 0; i < trHeightC; ++i )
5394        {
5395          memcpy( pcResiCurrV+i*resiCStride, &bestResiV[i*trWidthC], sizeof(Pel) * trWidthC );
5396        }
5397      }
5398      else
5399      {
5400        uiDistV = uiNonzeroDistV;
5401        uiAbsSumV = uiAbsSumTransformSkipV;
5402        uiBestTransformMode[2] = 1;
5403      }
5404
5405      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5406      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5407    }
5408
5409    if( m_bUseSBACRD )
5410    {
5411      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5412    }
5413
5414    m_pcEntropyCoder->resetBits();
5415
5416    {
5417      if( uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5418      {
5419        m_pcEntropyCoder->encodeTransformSubdivFlag( 0, 5 - uiLog2TrSize );
5420      }
5421    }
5422
5423    {
5424      if( bCodeChroma )
5425      {
5426        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode );
5427        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode );
5428      }
5429
5430      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
5431    }
5432
5433    m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx, trWidth, trHeight,    uiDepth, TEXT_LUMA );
5434
5435    if( bCodeChroma )
5436    {
5437      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_U );
5438      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_V );
5439    }
5440
5441    uiSingleBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5442
5443    uiSingleDist = uiDistY + uiDistU + uiDistV;
5444    dSingleCost = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDist );
5445  } 
5446 
5447  // code sub-blocks
5448  if( bCheckSplit )
5449  {
5450    if( m_bUseSBACRD && bCheckFull )
5451    {
5452      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5453      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5454    }
5455    UInt uiSubdivDist = 0;
5456    UInt uiSubdivBits = 0;
5457    Double dSubdivCost = 0.0;
5458   
5459    const UInt uiQPartNumSubdiv = pcCU->getPic()->getNumPartInCU() >> ((uiDepth + 1 ) << 1);
5460    for( UInt ui = 0; ui < 4; ++ui )
5461    {
5462      UInt nsAddr = uiAbsPartIdx + ui * uiQPartNumSubdiv;
5463      xEstimateResidualQT( pcCU, ui, uiAbsPartIdx + ui * uiQPartNumSubdiv, nsAddr, pcResi, uiDepth + 1, dSubdivCost, uiSubdivBits, uiSubdivDist, bCheckFull ? NULL : puiZeroDist );
5464    }
5465   
5466    UInt uiYCbf = 0;
5467    UInt uiUCbf = 0;
5468    UInt uiVCbf = 0;
5469    for( UInt ui = 0; ui < 4; ++ui )
5470    {
5471      uiYCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, TEXT_LUMA,     uiTrMode + 1 );
5472      uiUCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, TEXT_CHROMA_U, uiTrMode + 1 );
5473      uiVCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, TEXT_CHROMA_V, uiTrMode + 1 );
5474    }
5475    for( UInt ui = 0; ui < 4 * uiQPartNumSubdiv; ++ui )
5476    {
5477      pcCU->getCbf( TEXT_LUMA     )[uiAbsPartIdx + ui] |= uiYCbf << uiTrMode;
5478      pcCU->getCbf( TEXT_CHROMA_U )[uiAbsPartIdx + ui] |= uiUCbf << uiTrMode;
5479      pcCU->getCbf( TEXT_CHROMA_V )[uiAbsPartIdx + ui] |= uiVCbf << uiTrMode;
5480    }
5481   
5482    if( m_bUseSBACRD )
5483    {
5484      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5485    }
5486    m_pcEntropyCoder->resetBits();
5487   
5488    {
5489      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, true,  TEXT_LUMA );
5490      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, false, TEXT_LUMA );
5491      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, false, TEXT_CHROMA_U );
5492      xEncodeResidualQT( pcCU, uiAbsPartIdx, uiDepth, false, TEXT_CHROMA_V );
5493    }
5494   
5495    uiSubdivBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5496    dSubdivCost  = m_pcRdCost->calcRdCost( uiSubdivBits, uiSubdivDist );
5497   
5498    if( uiYCbf || uiUCbf || uiVCbf || !bCheckFull )
5499    {
5500      if( dSubdivCost < dSingleCost )
5501      {
5502        rdCost += dSubdivCost;
5503        ruiBits += uiSubdivBits;
5504        ruiDist += uiSubdivDist;
5505        return;
5506      }
5507    }
5508    pcCU->setTransformSkipSubParts ( uiBestTransformMode[0], TEXT_LUMA, uiAbsPartIdx, uiDepth ); 
5509    if(bCodeChroma)
5510    {
5511      pcCU->setTransformSkipSubParts ( uiBestTransformMode[1], TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC ); 
5512      pcCU->setTransformSkipSubParts ( uiBestTransformMode[2], TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC ); 
5513    }
5514    assert( bCheckFull );
5515    if( m_bUseSBACRD )
5516    {
5517      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5518    }
5519  }
5520  rdCost += dSingleCost;
5521  ruiBits += uiSingleBits;
5522  ruiDist += uiSingleDist;
5523 
5524  pcCU->setTrIdxSubParts( uiTrMode, uiAbsPartIdx, uiDepth );
5525 
5526  pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
5527  if( bCodeChroma )
5528  {
5529    pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5530    pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
5531  }
5532}
5533
5534Void TEncSearch::xEncodeResidualQT( TComDataCU* pcCU, UInt uiAbsPartIdx, const UInt uiDepth, Bool bSubdivAndCbf, TextType eType )
5535{
5536  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5537  const UInt uiCurrTrMode = uiDepth - pcCU->getDepth( 0 );
5538  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5539 
5540  const Bool bSubdiv = uiCurrTrMode != uiTrMode;
5541 
5542  const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
5543
5544  {
5545    if( bSubdivAndCbf && uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() && uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5546    {
5547      m_pcEntropyCoder->encodeTransformSubdivFlag( bSubdiv, 5 - uiLog2TrSize );
5548    }
5549  }
5550
5551  {
5552    assert( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA );
5553    if( bSubdivAndCbf )
5554    {
5555      const Bool bFirstCbfOfCU = uiCurrTrMode == 0;
5556      if( bFirstCbfOfCU || uiLog2TrSize > 2 )
5557      {
5558        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode - 1 ) )
5559        {
5560          m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode );
5561        }
5562        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode - 1 ) )
5563        {
5564          m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode );
5565        }
5566      }
5567      else if( uiLog2TrSize == 2 )
5568      {
5569        assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiCurrTrMode - 1 ) );
5570        assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiCurrTrMode - 1 ) );
5571      }
5572    }
5573  }
5574 
5575  if( !bSubdiv )
5576  {
5577    const UInt uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
5578    //assert( 16 == uiNumCoeffPerAbsPartIdxIncrement ); // check
5579    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5580    TCoeff *pcCoeffCurrY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5581    TCoeff *pcCoeffCurrU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5582    TCoeff *pcCoeffCurrV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5583   
5584    Bool  bCodeChroma   = true;
5585    UInt  uiTrModeC     = uiTrMode;
5586    UInt  uiLog2TrSizeC = uiLog2TrSize-1;
5587    if( uiLog2TrSize == 2 )
5588    {
5589      uiLog2TrSizeC++;
5590      uiTrModeC    --;
5591      UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
5592      bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
5593    }
5594   
5595    if( bSubdivAndCbf )
5596    {
5597      {
5598        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
5599      }
5600    }
5601    else
5602    {
5603      if( eType == TEXT_LUMA     && pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA,     uiTrMode ) )
5604      {
5605        Int trWidth  = 1 << uiLog2TrSize;
5606        Int trHeight = 1 << uiLog2TrSize;
5607        m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx, trWidth, trHeight,    uiDepth, TEXT_LUMA );
5608      }
5609      if( bCodeChroma )
5610      {
5611        Int trWidth  = 1 << uiLog2TrSizeC;
5612        Int trHeight = 1 << uiLog2TrSizeC;
5613        if( eType == TEXT_CHROMA_U && pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode ) )
5614        {
5615          m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
5616        }
5617        if( eType == TEXT_CHROMA_V && pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode ) )
5618        {
5619          m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
5620        }
5621      }
5622    }
5623  }
5624  else
5625  {
5626    if( bSubdivAndCbf || pcCU->getCbf( uiAbsPartIdx, eType, uiCurrTrMode ) )
5627    {
5628      const UInt uiQPartNumSubdiv = pcCU->getPic()->getNumPartInCU() >> ((uiDepth + 1 ) << 1);
5629      for( UInt ui = 0; ui < 4; ++ui )
5630      {
5631        xEncodeResidualQT( pcCU, uiAbsPartIdx + ui * uiQPartNumSubdiv, uiDepth + 1, bSubdivAndCbf, eType );
5632      }
5633    }
5634  }
5635}
5636
5637Void TEncSearch::xSetResidualQTData( TComDataCU* pcCU, UInt uiQuadrant, UInt uiAbsPartIdx, UInt absTUPartIdx, TComYuv* pcResi, UInt uiDepth, Bool bSpatial )
5638{
5639  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5640  const UInt uiCurrTrMode = uiDepth - pcCU->getDepth( 0 );
5641  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5642
5643  if( uiCurrTrMode == uiTrMode )
5644  {
5645    const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
5646    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5647
5648    Bool  bCodeChroma   = true;
5649    UInt  uiTrModeC     = uiTrMode;
5650    UInt  uiLog2TrSizeC = uiLog2TrSize-1;
5651    if( uiLog2TrSize == 2 )
5652    {
5653      uiLog2TrSizeC++;
5654      uiTrModeC    --;
5655      UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
5656      bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
5657    }
5658
5659    if( bSpatial )
5660    {     
5661      Int trWidth  = 1 << uiLog2TrSize;
5662      Int trHeight = 1 << uiLog2TrSize;
5663      m_pcQTTempTComYuv[uiQTTempAccessLayer].copyPartToPartLuma    ( pcResi, absTUPartIdx, trWidth , trHeight );
5664
5665      if( bCodeChroma )
5666      {
5667        {
5668          m_pcQTTempTComYuv[uiQTTempAccessLayer].copyPartToPartChroma( pcResi, uiAbsPartIdx, 1 << uiLog2TrSizeC, 1 << uiLog2TrSizeC );
5669        }
5670      }
5671    }
5672    else
5673    {
5674      UInt    uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
5675      UInt    uiNumCoeffY = ( 1 << ( uiLog2TrSize << 1 ) );
5676      TCoeff* pcCoeffSrcY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5677      TCoeff* pcCoeffDstY = pcCU->getCoeffY() + uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5678      ::memcpy( pcCoeffDstY, pcCoeffSrcY, sizeof( TCoeff ) * uiNumCoeffY );
5679#if ADAPTIVE_QP_SELECTION
5680      Int* pcArlCoeffSrcY = m_ppcQTTempArlCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5681      Int* pcArlCoeffDstY = pcCU->getArlCoeffY() + uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
5682      ::memcpy( pcArlCoeffDstY, pcArlCoeffSrcY, sizeof( Int ) * uiNumCoeffY );
5683#endif
5684      if( bCodeChroma )
5685      {
5686        UInt    uiNumCoeffC = ( 1 << ( uiLog2TrSizeC << 1 ) );
5687        TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5688        TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5689        TCoeff* pcCoeffDstU = pcCU->getCoeffCb() + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5690        TCoeff* pcCoeffDstV = pcCU->getCoeffCr() + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5691        ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
5692        ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
5693#if ADAPTIVE_QP_SELECTION
5694        Int* pcArlCoeffSrcU = m_ppcQTTempArlCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5695        Int* pcArlCoeffSrcV = m_ppcQTTempArlCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5696        Int* pcArlCoeffDstU = pcCU->getArlCoeffCb() + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5697        Int* pcArlCoeffDstV = pcCU->getArlCoeffCr() + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
5698        ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
5699        ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
5700#endif
5701      }
5702    }
5703  }
5704  else
5705  {
5706    const UInt uiQPartNumSubdiv = pcCU->getPic()->getNumPartInCU() >> ((uiDepth + 1 ) << 1);
5707    for( UInt ui = 0; ui < 4; ++ui )
5708    {
5709      UInt nsAddr = uiAbsPartIdx + ui * uiQPartNumSubdiv;
5710      xSetResidualQTData( pcCU, ui, uiAbsPartIdx + ui * uiQPartNumSubdiv, nsAddr, pcResi, uiDepth + 1, bSpatial );
5711    }
5712  }
5713}
5714
5715UInt TEncSearch::xModeBitsIntra( TComDataCU* pcCU, UInt uiMode, UInt uiPU, UInt uiPartOffset, UInt uiDepth, UInt uiInitTrDepth )
5716{
5717  if( m_bUseSBACRD )
5718  {
5719    // Reload only contexts required for coding intra mode information
5720    m_pcRDGoOnSbacCoder->loadIntraDirModeLuma( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
5721  }
5722 
5723  pcCU->setLumaIntraDirSubParts ( uiMode, uiPartOffset, uiDepth + uiInitTrDepth );
5724 
5725  m_pcEntropyCoder->resetBits();
5726  m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPartOffset);
5727 
5728  return m_pcEntropyCoder->getNumberOfWrittenBits();
5729}
5730
5731UInt TEncSearch::xUpdateCandList( UInt uiMode, Double uiCost, UInt uiFastCandNum, UInt * CandModeList, Double * CandCostList )
5732{
5733  UInt i;
5734  UInt shift=0;
5735 
5736  while ( shift<uiFastCandNum && uiCost<CandCostList[ uiFastCandNum-1-shift ] ) shift++;
5737 
5738  if( shift!=0 )
5739  {
5740    for(i=1; i<shift; i++)
5741    {
5742      CandModeList[ uiFastCandNum-i ] = CandModeList[ uiFastCandNum-1-i ];
5743      CandCostList[ uiFastCandNum-i ] = CandCostList[ uiFastCandNum-1-i ];
5744    }
5745    CandModeList[ uiFastCandNum-shift ] = uiMode;
5746    CandCostList[ uiFastCandNum-shift ] = uiCost;
5747    return 1;
5748  }
5749 
5750  return 0;
5751}
5752
5753/** add inter-prediction syntax elements for a CU block
5754 * \param pcCU
5755 * \param uiQp
5756 * \param uiTrMode
5757 * \param ruiBits
5758 * \param rpcYuvRec
5759 * \param pcYuvPred
5760 * \param rpcYuvResi
5761 * \returns Void
5762 */
5763Void  TEncSearch::xAddSymbolBitsInter( TComDataCU* pcCU, UInt uiQp, UInt uiTrMode, UInt& ruiBits, TComYuv*& rpcYuvRec, TComYuv*pcYuvPred, TComYuv*& rpcYuvResi )
5764{
5765  if(pcCU->getMergeFlag( 0 ) && pcCU->getPartitionSize( 0 ) == SIZE_2Nx2N && !pcCU->getQtRootCbf( 0 ))
5766  {
5767    pcCU->setSkipFlagSubParts( true, 0, pcCU->getDepth(0) );
5768
5769    m_pcEntropyCoder->resetBits();
5770    if(pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
5771    {
5772      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
5773    }
5774    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
5775    m_pcEntropyCoder->encodeMergeIndex(pcCU, 0, true);
5776    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5777  }
5778  else
5779  {
5780    m_pcEntropyCoder->resetBits();
5781    if(pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
5782    {
5783      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
5784    }
5785    m_pcEntropyCoder->encodeSkipFlag ( pcCU, 0, true );
5786    m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
5787    m_pcEntropyCoder->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
5788    m_pcEntropyCoder->encodePredInfo( pcCU, 0, true );
5789
5790    Bool bDummy = false;
5791    m_pcEntropyCoder->encodeCoeff   ( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0), bDummy );
5792   
5793    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5794  }
5795}
5796
5797/**
5798 * \brief Generate half-sample interpolated block
5799 *
5800 * \param pattern Reference picture ROI
5801 * \param biPred    Flag indicating whether block is for biprediction
5802 */
5803Void TEncSearch::xExtDIFUpSamplingH( TComPattern* pattern, Bool biPred )
5804{
5805  Int width      = pattern->getROIYWidth();
5806  Int height     = pattern->getROIYHeight();
5807  Int srcStride  = pattern->getPatternLStride();
5808 
5809  Int intStride = m_filteredBlockTmp[0].getStride();
5810  Int dstStride = m_filteredBlock[0][0].getStride();
5811  Short *intPtr;
5812  Short *dstPtr;
5813  Int filterSize = NTAPS_LUMA;
5814  Int halfFilterSize = (filterSize>>1);
5815  Pel *srcPtr = pattern->getROIY() - halfFilterSize*srcStride - 1;
5816 
5817  m_if.filterHorLuma(srcPtr, srcStride, m_filteredBlockTmp[0].getLumaAddr(), intStride, width+1, height+filterSize, 0, false);
5818  m_if.filterHorLuma(srcPtr, srcStride, m_filteredBlockTmp[2].getLumaAddr(), intStride, width+1, height+filterSize, 2, false);
5819 
5820  intPtr = m_filteredBlockTmp[0].getLumaAddr() + halfFilterSize * intStride + 1; 
5821  dstPtr = m_filteredBlock[0][0].getLumaAddr();
5822  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width+0, height+0, 0, false, true);
5823 
5824  intPtr = m_filteredBlockTmp[0].getLumaAddr() + (halfFilterSize-1) * intStride + 1; 
5825  dstPtr = m_filteredBlock[2][0].getLumaAddr();
5826  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width+0, height+1, 2, false, true);
5827 
5828  intPtr = m_filteredBlockTmp[2].getLumaAddr() + halfFilterSize * intStride;
5829  dstPtr = m_filteredBlock[0][2].getLumaAddr();
5830  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width+1, height+0, 0, false, true);
5831 
5832  intPtr = m_filteredBlockTmp[2].getLumaAddr() + (halfFilterSize-1) * intStride;
5833  dstPtr = m_filteredBlock[2][2].getLumaAddr();
5834  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width+1, height+1, 2, false, true);
5835}
5836
5837/**
5838 * \brief Generate quarter-sample interpolated blocks
5839 *
5840 * \param pattern    Reference picture ROI
5841 * \param halfPelRef Half-pel mv
5842 * \param biPred     Flag indicating whether block is for biprediction
5843 */
5844Void TEncSearch::xExtDIFUpSamplingQ( TComPattern* pattern, TComMv halfPelRef, Bool biPred )
5845{
5846  Int width      = pattern->getROIYWidth();
5847  Int height     = pattern->getROIYHeight();
5848  Int srcStride  = pattern->getPatternLStride();
5849 
5850  Pel *srcPtr;
5851  Int intStride = m_filteredBlockTmp[0].getStride();
5852  Int dstStride = m_filteredBlock[0][0].getStride();
5853  Short *intPtr;
5854  Short *dstPtr;
5855  Int filterSize = NTAPS_LUMA;
5856 
5857  Int halfFilterSize = (filterSize>>1);
5858
5859  Int extHeight = (halfPelRef.getVer() == 0) ? height + filterSize : height + filterSize-1;
5860 
5861  // Horizontal filter 1/4
5862  srcPtr = pattern->getROIY() - halfFilterSize * srcStride - 1;
5863  intPtr = m_filteredBlockTmp[1].getLumaAddr();
5864  if (halfPelRef.getVer() > 0)
5865  {
5866    srcPtr += srcStride;
5867  }
5868  if (halfPelRef.getHor() >= 0)
5869  {
5870    srcPtr += 1;
5871  }
5872  m_if.filterHorLuma(srcPtr, srcStride, intPtr, intStride, width, extHeight, 1, false);
5873 
5874  // Horizontal filter 3/4
5875  srcPtr = pattern->getROIY() - halfFilterSize*srcStride - 1;
5876  intPtr = m_filteredBlockTmp[3].getLumaAddr();
5877  if (halfPelRef.getVer() > 0)
5878  {
5879    srcPtr += srcStride;
5880  }
5881  if (halfPelRef.getHor() > 0)
5882  {
5883    srcPtr += 1;
5884  }
5885  m_if.filterHorLuma(srcPtr, srcStride, intPtr, intStride, width, extHeight, 3, false);       
5886 
5887  // Generate @ 1,1
5888  intPtr = m_filteredBlockTmp[1].getLumaAddr() + (halfFilterSize-1) * intStride;
5889  dstPtr = m_filteredBlock[1][1].getLumaAddr();
5890  if (halfPelRef.getVer() == 0)
5891  {
5892    intPtr += intStride;
5893  }
5894  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true);
5895 
5896  // Generate @ 3,1
5897  intPtr = m_filteredBlockTmp[1].getLumaAddr() + (halfFilterSize-1) * intStride;
5898  dstPtr = m_filteredBlock[3][1].getLumaAddr();
5899  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true);
5900 
5901  if (halfPelRef.getVer() != 0)
5902  {
5903    // Generate @ 2,1
5904    intPtr = m_filteredBlockTmp[1].getLumaAddr() + (halfFilterSize-1) * intStride;
5905    dstPtr = m_filteredBlock[2][1].getLumaAddr();
5906    if (halfPelRef.getVer() == 0)
5907    {
5908      intPtr += intStride;
5909    }
5910    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true);
5911   
5912    // Generate @ 2,3
5913    intPtr = m_filteredBlockTmp[3].getLumaAddr() + (halfFilterSize-1) * intStride;
5914    dstPtr = m_filteredBlock[2][3].getLumaAddr();
5915    if (halfPelRef.getVer() == 0)
5916    {
5917      intPtr += intStride;
5918    }
5919    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true);
5920  }
5921  else
5922  {
5923    // Generate @ 0,1
5924    intPtr = m_filteredBlockTmp[1].getLumaAddr() + halfFilterSize * intStride;
5925    dstPtr = m_filteredBlock[0][1].getLumaAddr();
5926    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true);
5927   
5928    // Generate @ 0,3
5929    intPtr = m_filteredBlockTmp[3].getLumaAddr() + halfFilterSize * intStride;
5930    dstPtr = m_filteredBlock[0][3].getLumaAddr();
5931    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true);
5932  }
5933 
5934  if (halfPelRef.getHor() != 0)
5935  {
5936    // Generate @ 1,2
5937    intPtr = m_filteredBlockTmp[2].getLumaAddr() + (halfFilterSize-1) * intStride;
5938    dstPtr = m_filteredBlock[1][2].getLumaAddr();
5939    if (halfPelRef.getHor() > 0)
5940    {
5941      intPtr += 1;
5942    }
5943    if (halfPelRef.getVer() >= 0)
5944    {
5945      intPtr += intStride;
5946    }
5947    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true);
5948   
5949    // Generate @ 3,2
5950    intPtr = m_filteredBlockTmp[2].getLumaAddr() + (halfFilterSize-1) * intStride;
5951    dstPtr = m_filteredBlock[3][2].getLumaAddr();
5952    if (halfPelRef.getHor() > 0)
5953    {
5954      intPtr += 1;
5955    }
5956    if (halfPelRef.getVer() > 0)
5957    {
5958      intPtr += intStride;
5959    }
5960    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true); 
5961  }
5962  else
5963  {
5964    // Generate @ 1,0
5965    intPtr = m_filteredBlockTmp[0].getLumaAddr() + (halfFilterSize-1) * intStride + 1;
5966    dstPtr = m_filteredBlock[1][0].getLumaAddr();
5967    if (halfPelRef.getVer() >= 0)
5968    {
5969      intPtr += intStride;
5970    }
5971    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true);
5972   
5973    // Generate @ 3,0
5974    intPtr = m_filteredBlockTmp[0].getLumaAddr() + (halfFilterSize-1) * intStride + 1;
5975    dstPtr = m_filteredBlock[3][0].getLumaAddr();
5976    if (halfPelRef.getVer() > 0)
5977    {
5978      intPtr += intStride;
5979    }
5980    m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true);
5981  }
5982 
5983  // Generate @ 1,3
5984  intPtr = m_filteredBlockTmp[3].getLumaAddr() + (halfFilterSize-1) * intStride;
5985  dstPtr = m_filteredBlock[1][3].getLumaAddr();
5986  if (halfPelRef.getVer() == 0)
5987  {
5988    intPtr += intStride;
5989  }
5990  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true);
5991 
5992  // Generate @ 3,3
5993  intPtr = m_filteredBlockTmp[3].getLumaAddr() + (halfFilterSize-1) * intStride;
5994  dstPtr = m_filteredBlock[3][3].getLumaAddr();
5995  m_if.filterVerLuma(intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true);
5996}
5997
5998/** set wp tables
5999 * \param TComDataCU* pcCU
6000 * \param iRefIdx
6001 * \param eRefPicListCur
6002 * \returns Void
6003 */
6004Void  TEncSearch::setWpScalingDistParam( TComDataCU* pcCU, Int iRefIdx, RefPicList eRefPicListCur )
6005{
6006  if ( iRefIdx<0 )
6007  {
6008    m_cDistParam.bApplyWeight = false;
6009    return;
6010  }
6011
6012  TComSlice       *pcSlice  = pcCU->getSlice();
6013  TComPPS         *pps      = pcCU->getSlice()->getPPS();
6014  wpScalingParam  *wp0 , *wp1;
6015  m_cDistParam.bApplyWeight = ( pcSlice->getSliceType()==P_SLICE && pps->getUseWP() ) || ( pcSlice->getSliceType()==B_SLICE && pps->getWPBiPred() ) ;
6016  if ( !m_cDistParam.bApplyWeight ) return;
6017
6018  Int iRefIdx0 = ( eRefPicListCur == REF_PIC_LIST_0 ) ? iRefIdx : (-1);
6019  Int iRefIdx1 = ( eRefPicListCur == REF_PIC_LIST_1 ) ? iRefIdx : (-1);
6020
6021  getWpScaling( pcCU, iRefIdx0, iRefIdx1, wp0 , wp1 );
6022
6023  if ( iRefIdx0 < 0 ) wp0 = NULL;
6024  if ( iRefIdx1 < 0 ) wp1 = NULL;
6025
6026  m_cDistParam.wpCur  = NULL;
6027
6028  if ( eRefPicListCur == REF_PIC_LIST_0 )
6029  {
6030    m_cDistParam.wpCur = wp0;
6031  }
6032  else
6033  {
6034    m_cDistParam.wpCur = wp1;
6035  }
6036}
6037
6038#if REF_IDX_ME_ZEROMV
6039Void TEncSearch::xPatternSearchFracDIFMv0(TComDataCU* pcCU,
6040                                          TComPattern* pcPatternKey,
6041                                          Pel* piRefY,
6042                                          Int iRefStride,
6043                                          TComMv* pcMvInt,
6044                                          TComMv& rcMvHalf,
6045                                          TComMv& rcMvQter,
6046                                          UInt& ruiCost,
6047                                          Bool biPred
6048                                          )
6049{
6050  assert(pcMvInt->getHor() == 0 && pcMvInt->getVer() == 0);
6051  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
6052  m_pcRdCost->setDistParam( pcPatternKey, piRefY + iOffset, iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME() );
6053  m_pcRdCost->setCostScale ( 2 );
6054  setDistParamComp(0);
6055  ruiCost = m_cDistParam.DistFunc( &m_cDistParam );  //SATD
6056  ruiCost += m_pcRdCost->getCost( pcMvInt->getHor(), pcMvInt->getVer() );  //SATD rdCost
6057  rcMvHalf.setZero();
6058  rcMvQter.setZero();
6059}
6060#endif
6061
6062#if ENCODER_FAST_MODE
6063Bool TEncSearch::predInterSearchILRUni( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, UInt refLayerId )
6064{
6065    rpcPredYuv->clear();
6066    rpcRecoYuv->clear();
6067
6068    Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
6069
6070    TComMv        cMv[2];
6071    TComMv        cMvPred[2][33];
6072    TComMv        cMvTemp[2][33];
6073    TComMv        TempMv;
6074
6075    Int           iRefIdx[2]={0,0};
6076
6077    Int           aaiMvpIdx[2][33];
6078    Int           aaiMvpNum[2][33];
6079
6080    UInt          uiMbBits[3] = {1, 1, 0};
6081    UInt          uiLastMode = 0;
6082
6083    UInt          uiCost[2]   = { MAX_UINT, MAX_UINT };     //uni, rdCost
6084    UInt          uiCostTemp;
6085    UInt          biPDistTemp = MAX_INT;
6086    UInt          uiBitsTemp;
6087
6088    PartSize      ePartSize = pcCU->getPartitionSize( 0 );  //2Nx2N
6089    Int           iPartIdx  = 0;                            //one PU in CU
6090    UInt          uiPartAddr;
6091    Int           iRoiWidth, iRoiHeight;
6092    Bool          bILRSearched = false;
6093
6094    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
6095    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
6096
6097    for( Int iRefList = 0; iRefList < iNumPredDir; iRefList++)  //list
6098    {
6099        if(bILRSearched)
6100           continue;
6101
6102        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
6103
6104        Int  iRefIdxTemp = -1;
6105        Bool foundILR    = false;
6106
6107        for( Int refIdx = 0; refIdx < pcCU->getSlice()->getNumRefIdx(eRefPicList); refIdx++ )
6108        {
6109            if( pcCU->getSlice()->getRefPic(eRefPicList, refIdx)->isILR(pcCU->getLayerId()) && pcCU->getSlice()->getRefPic(eRefPicList, refIdx)->getLayerId() == refLayerId )
6110            {
6111                iRefIdxTemp = refIdx;
6112                foundILR    = true;
6113                bILRSearched = true;
6114                break;
6115            }
6116        }
6117
6118        if(!foundILR)  //no ILR in eRefPiclist
6119        {
6120            continue; 
6121        }
6122
6123        uiBitsTemp = uiMbBits[iRefList];
6124        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 ) 
6125        { 
6126            uiBitsTemp += iRefIdxTemp+1; 
6127            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--; 
6128        }
6129
6130        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
6131        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
6132        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
6133
6134        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
6135
6136        xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
6137        xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
6138
6139        if( uiCostTemp < uiCost[iRefList] )
6140        {
6141            uiCost[iRefList] = uiCostTemp;
6142
6143            cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
6144            iRefIdx[iRefList] = iRefIdxTemp;
6145
6146            pcCU->getCUMvField(eRefPicList)->setAllMv( cMv[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
6147            pcCU->getCUMvField(eRefPicList)->setAllRefIdx( iRefIdx[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
6148        }
6149    }
6150
6151    if( uiCost[0] == MAX_UINT && uiCost[1] == MAX_UINT )  //no ILR in both list0 and list1
6152    {
6153        return false;
6154    }
6155
6156    //  Clear Motion Field
6157    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
6158    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
6159    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx ); 
6160    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx );
6161
6162    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6163    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6164    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6165    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
6166
6167    if( uiCost[0] <= uiCost[1] )  //list0 ILR
6168    {
6169        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv    ( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
6170        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
6171
6172        TempMv = cMv[0] - cMvPred[0][iRefIdx[0]]; 
6173        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
6174
6175        pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
6176
6177        pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6178        pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
6179    }
6180    else if( uiCost[1] < uiCost[0] )  //list1 ILR
6181    {
6182        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv    ( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
6183        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
6184
6185        TempMv = cMv[1] - cMvPred[1][iRefIdx[1]]; 
6186        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
6187
6188        pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
6189
6190        pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6191        pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
6192    }
6193    else
6194    {
6195        assert(0);
6196    }
6197
6198    pcCU->setMergeFlagSubParts( false, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
6199
6200    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
6201    setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
6202
6203    return true;
6204}
6205#endif
6206
6207//! \}
Note: See TracBrowser for help on using the repository browser.