source: SHVCSoftware/branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncSearch.cpp @ 460

Last change on this file since 460 was 302, checked in by seregin, 11 years ago

update to HM11.0

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