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

Last change on this file since 483 was 483, checked in by tech, 11 years ago

Merged fixes from other dev-branches.

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