source: 3DVCSoftware/branches/HTM-DEV-0.1-dev/source/Lib/TLibEncoder/TEncSearch.cpp @ 551

Last change on this file since 551 was 362, checked in by tech, 12 years ago

Update to HM-10.1.

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