source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSearch.cpp @ 468

Last change on this file since 468 was 468, checked in by lg, 12 years ago

1.IC and full pel depth coding are integrated and is guarded by Macro H_3D_IC.

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