source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibEncoder/TEncSearch.cpp @ 1263

Last change on this file since 1263 was 9, checked in by seregin, 12 years ago

Bug fix for IntraBL 4x4 transform using inverse DCT. Patch was provided by Patrice Onno <Patrice.Onno@…>

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