source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncSearch.cpp @ 462

Last change on this file since 462 was 442, checked in by seregin, 11 years ago

reintegrate SHM-3.1-dev branch

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