source: SHVCSoftware/branches/SHM-2.0avc-dev/source/Lib/TLibEncoder/TEncSearch.cpp @ 601

Last change on this file since 601 was 191, checked in by seregin, 12 years ago

unix2dos for *.cpp and *.h

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