source: SHVCSoftware/branches/SHM-6-dev/source/Lib/TLibEncoder/TEncSearch.cpp @ 794

Last change on this file since 794 was 726, checked in by seregin, 11 years ago

checks for ILRP prediction type

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