source: SHVCSoftware/branches/HM-10.0-dev-SHM/source/Lib/TLibEncoder/TEncSearch.cpp @ 577

Last change on this file since 577 was 106, checked in by interdigital, 12 years ago

remove the bug fix in HM8.1 based SHM code since the same bug fix is included in HM10.0 code.

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