source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncSearch.cpp @ 77

Last change on this file since 77 was 77, checked in by tech, 12 years ago

Merged with branch/HTM-3.0Samsung REV74 including:

  • restricted residual prediction m24766
  • Inter-view residual prediction m24938
  • VPS concept m24714,m24878, m24945,m24896, m2491
  • reference list modification, restriction on IDR m24876, m24874
  • depth based motion parameter prediction m24829

Fixed bugs:

  • interview prediction
  • VSO

Added:

  • xcode project
  • Property svn:eol-style set to native
File size: 229.4 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-2012, 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 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 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 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
103  setWpScalingDistParam( NULL, -1, REF_PIC_LIST_X );
104}
105
106TEncSearch::~TEncSearch()
107{
108  if ( m_pTempPel )
109  {
110    delete [] m_pTempPel;
111    m_pTempPel = NULL;
112  }
113 
114  if ( m_pcEncCfg )
115  {
116    const UInt uiNumLayersAllocated = m_pcEncCfg->getQuadtreeTULog2MaxSize()-m_pcEncCfg->getQuadtreeTULog2MinSize()+1;
117    for( UInt ui = 0; ui < uiNumLayersAllocated; ++ui )
118    {
119      delete[] m_ppcQTTempCoeffY[ui];
120      delete[] m_ppcQTTempCoeffCb[ui];
121      delete[] m_ppcQTTempCoeffCr[ui];
122#if ADAPTIVE_QP_SELECTION
123      delete[] m_ppcQTTempArlCoeffY[ui];
124      delete[] m_ppcQTTempArlCoeffCb[ui];
125      delete[] m_ppcQTTempArlCoeffCr[ui];
126#endif
127      m_pcQTTempTComYuv[ui].destroy();
128    }
129  }
130  delete[] m_ppcQTTempCoeffY;
131  delete[] m_ppcQTTempCoeffCb;
132  delete[] m_ppcQTTempCoeffCr;
133  delete[] m_pcQTTempCoeffY;
134  delete[] m_pcQTTempCoeffCb;
135  delete[] m_pcQTTempCoeffCr;
136#if ADAPTIVE_QP_SELECTION
137  delete[] m_ppcQTTempArlCoeffY;
138  delete[] m_ppcQTTempArlCoeffCb;
139  delete[] m_ppcQTTempArlCoeffCr;
140  delete[] m_pcQTTempArlCoeffY;
141  delete[] m_pcQTTempArlCoeffCb;
142  delete[] m_pcQTTempArlCoeffCr;
143#endif
144  delete[] m_puhQTTempTrIdx;
145  delete[] m_puhQTTempCbf[0];
146  delete[] m_puhQTTempCbf[1];
147  delete[] m_puhQTTempCbf[2];
148  delete[] m_pcQTTempTComYuv;
149 
150  m_tmpYuvPred.destroy();
151}
152
153void TEncSearch::init(TEncCfg*      pcEncCfg,
154                      TComTrQuant*  pcTrQuant,
155                      Int           iSearchRange,
156                      Int           bipredSearchRange,
157                      Int           iFastSearch,
158                      Int           iMaxDeltaQP,
159                      TEncEntropy*  pcEntropyCoder,
160                      TComRdCost*   pcRdCost,
161                      TEncSbac*** pppcRDSbacCoder,
162                      TEncSbac*   pcRDGoOnSbacCoder
163                      )
164{
165  m_pcEncCfg             = pcEncCfg;
166  m_pcTrQuant            = pcTrQuant;
167  m_iSearchRange         = iSearchRange;
168  m_bipredSearchRange    = bipredSearchRange;
169  m_iFastSearch          = iFastSearch;
170  m_iMaxDeltaQP          = iMaxDeltaQP;
171  m_pcEntropyCoder       = pcEntropyCoder;
172  m_pcRdCost             = pcRdCost;
173 
174  m_pppcRDSbacCoder     = pppcRDSbacCoder;
175  m_pcRDGoOnSbacCoder   = pcRDGoOnSbacCoder;
176 
177  m_bUseSBACRD          = pppcRDSbacCoder ? true : false;
178 
179  for (Int iDir = 0; iDir < 2; iDir++)
180  {
181    for (Int iRefIdx = 0; iRefIdx < 33; iRefIdx++)
182    {
183      m_aaiAdaptSR[iDir][iRefIdx] = iSearchRange;
184    }
185  }
186 
187  m_puiDFilter = s_auiDFilter + 4;
188 
189  // initialize motion cost
190#if !FIX203
191  m_pcRdCost->initRateDistortionModel( m_iSearchRange << 2 );
192#endif
193 
194#if HHI_INTER_VIEW_MOTION_PRED
195  const Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + 1;
196  for( Int iNum = 0; iNum < iNumAMVPCands+1; iNum++)
197  {
198    for( Int iIdx = 0; iIdx < iNumAMVPCands; iIdx++)
199#else
200  for( Int iNum = 0; iNum < AMVP_MAX_NUM_CANDS+1; iNum++)
201  {
202    for( Int iIdx = 0; iIdx < AMVP_MAX_NUM_CANDS; iIdx++)
203#endif
204    {
205      if (iIdx < iNum)
206        m_auiMVPIdxCost[iIdx][iNum] = xGetMvpIdxBits(iIdx, iNum);
207      else
208        m_auiMVPIdxCost[iIdx][iNum] = MAX_INT;
209    }
210  }
211 
212  initTempBuff();
213 
214  m_pTempPel = new Pel[g_uiMaxCUWidth*g_uiMaxCUHeight];
215 
216  const UInt uiNumLayersToAllocate = pcEncCfg->getQuadtreeTULog2MaxSize()-pcEncCfg->getQuadtreeTULog2MinSize()+1;
217  m_ppcQTTempCoeffY  = new TCoeff*[uiNumLayersToAllocate];
218  m_ppcQTTempCoeffCb = new TCoeff*[uiNumLayersToAllocate];
219  m_ppcQTTempCoeffCr = new TCoeff*[uiNumLayersToAllocate];
220  m_pcQTTempCoeffY   = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight   ];
221  m_pcQTTempCoeffCb  = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
222  m_pcQTTempCoeffCr  = new TCoeff [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
223#if ADAPTIVE_QP_SELECTION
224  m_ppcQTTempArlCoeffY  = new Int*[uiNumLayersToAllocate];
225  m_ppcQTTempArlCoeffCb = new Int*[uiNumLayersToAllocate];
226  m_ppcQTTempArlCoeffCr = new Int*[uiNumLayersToAllocate];
227  m_pcQTTempArlCoeffY   = new Int [g_uiMaxCUWidth*g_uiMaxCUHeight   ];
228  m_pcQTTempArlCoeffCb  = new Int [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
229  m_pcQTTempArlCoeffCr  = new Int [g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
230#endif
231 
232  const UInt uiNumPartitions = 1<<(g_uiMaxCUDepth<<1);
233  m_puhQTTempTrIdx   = new UChar  [uiNumPartitions];
234  m_puhQTTempCbf[0]  = new UChar  [uiNumPartitions];
235  m_puhQTTempCbf[1]  = new UChar  [uiNumPartitions];
236  m_puhQTTempCbf[2]  = new UChar  [uiNumPartitions];
237  m_pcQTTempTComYuv  = new TComYuv[uiNumLayersToAllocate];
238  for( UInt ui = 0; ui < uiNumLayersToAllocate; ++ui )
239  {
240    m_ppcQTTempCoeffY[ui]  = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight   ];
241    m_ppcQTTempCoeffCb[ui] = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
242    m_ppcQTTempCoeffCr[ui] = new TCoeff[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
243#if ADAPTIVE_QP_SELECTION
244    m_ppcQTTempArlCoeffY[ui]  = new Int[g_uiMaxCUWidth*g_uiMaxCUHeight   ];
245    m_ppcQTTempArlCoeffCb[ui] = new Int[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
246    m_ppcQTTempArlCoeffCr[ui] = new Int[g_uiMaxCUWidth*g_uiMaxCUHeight>>2];
247#endif
248    m_pcQTTempTComYuv[ui].create( g_uiMaxCUWidth, g_uiMaxCUHeight );
249  }
250 
251  m_tmpYuvPred.create(MAX_CU_SIZE, MAX_CU_SIZE);
252}
253
254#if FASTME_SMOOTHER_MV
255#define FIRSTSEARCHSTOP     1
256#else
257#define FIRSTSEARCHSTOP     0
258#endif
259
260#define TZ_SEARCH_CONFIGURATION                                                                                 \
261const Int  iRaster                  = 5;  /* TZ soll von aussen ?ergeben werden */                            \
262const Bool bTestOtherPredictedMV    = 0;                                                                      \
263const Bool bTestZeroVector          = 1;                                                                      \
264const Bool bTestZeroVectorStart     = 0;                                                                      \
265const Bool bTestZeroVectorStop      = 0;                                                                      \
266const Bool bFirstSearchDiamond      = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
267const Bool bFirstSearchStop         = FIRSTSEARCHSTOP;                                                        \
268const UInt uiFirstSearchRounds      = 3;  /* first search stop X rounds after best match (must be >=1) */     \
269const Bool bEnableRasterSearch      = 1;                                                                      \
270const Bool bAlwaysRasterSearch      = 0;  /* ===== 1: BETTER but factor 2 slower ===== */                     \
271const Bool bRasterRefinementEnable  = 0;  /* enable either raster refinement or star refinement */            \
272const Bool bRasterRefinementDiamond = 0;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
273const Bool bStarRefinementEnable    = 1;  /* enable either star refinement or raster refinement */            \
274const Bool bStarRefinementDiamond   = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
275const Bool bStarRefinementStop      = 0;                                                                      \
276const UInt uiStarRefinementRounds   = 2;  /* star refinement stop X rounds after best match (must be >=1) */  \
277
278
279__inline Void TEncSearch::xTZSearchHelp( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance )
280{
281  UInt  uiSad;
282 
283  Pel*  piRefSrch;
284 
285  piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;
286 
287  //-- jclee for using the SAD function pointer
288  m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );
289 
290  // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
291  if ( m_pcEncCfg->getUseFastEnc() )
292  {
293    if ( m_cDistParam.iRows > 8 )
294    {
295      m_cDistParam.iSubShift = 1;
296    }
297  }
298
299  setDistParamComp(0);  // Y component
300
301  // distortion
302  uiSad = m_cDistParam.DistFunc( &m_cDistParam );
303 
304  // motion cost
305  uiSad += m_pcRdCost->getCost( iSearchX, iSearchY );
306 
307  if( uiSad < rcStruct.uiBestSad )
308  {
309    rcStruct.uiBestSad      = uiSad;
310    rcStruct.iBestX         = iSearchX;
311    rcStruct.iBestY         = iSearchY;
312    rcStruct.uiBestDistance = uiDistance;
313    rcStruct.uiBestRound    = 0;
314    rcStruct.ucPointNr      = ucPointNr;
315  }
316}
317
318__inline Void TEncSearch::xTZ2PointSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB )
319{
320  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
321  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
322  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
323  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
324 
325  // 2 point search,                   //   1 2 3
326  // check only the 2 untested points  //   4 0 5
327  // around the start point            //   6 7 8
328  Int iStartX = rcStruct.iBestX;
329  Int iStartY = rcStruct.iBestY;
330  switch( rcStruct.ucPointNr )
331  {
332    case 1:
333    {
334      if ( (iStartX - 1) >= iSrchRngHorLeft )
335      {
336        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY, 0, 2 );
337      }
338      if ( (iStartY - 1) >= iSrchRngVerTop )
339      {
340        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
341      }
342    }
343      break;
344    case 2:
345    {
346      if ( (iStartY - 1) >= iSrchRngVerTop )
347      {
348        if ( (iStartX - 1) >= iSrchRngHorLeft )
349        {
350          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
351        }
352        if ( (iStartX + 1) <= iSrchRngHorRight )
353        {
354          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
355        }
356      }
357    }
358      break;
359    case 3:
360    {
361      if ( (iStartY - 1) >= iSrchRngVerTop )
362      {
363        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY - 1, 0, 2 );
364      }
365      if ( (iStartX + 1) <= iSrchRngHorRight )
366      {
367        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
368      }
369    }
370      break;
371    case 4:
372    {
373      if ( (iStartX - 1) >= iSrchRngHorLeft )
374      {
375        if ( (iStartY + 1) <= iSrchRngVerBottom )
376        {
377          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
378        }
379        if ( (iStartY - 1) >= iSrchRngVerTop )
380        {
381          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY - 1, 0, 2 );
382        }
383      }
384    }
385      break;
386    case 5:
387    {
388      if ( (iStartX + 1) <= iSrchRngHorRight )
389      {
390        if ( (iStartY - 1) >= iSrchRngVerTop )
391        {
392          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY - 1, 0, 2 );
393        }
394        if ( (iStartY + 1) <= iSrchRngVerBottom )
395        {
396          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
397        }
398      }
399    }
400      break;
401    case 6:
402    {
403      if ( (iStartX - 1) >= iSrchRngHorLeft )
404      {
405        xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY , 0, 2 );
406      }
407      if ( (iStartY + 1) <= iSrchRngVerBottom )
408      {
409        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
410      }
411    }
412      break;
413    case 7:
414    {
415      if ( (iStartY + 1) <= iSrchRngVerBottom )
416      {
417        if ( (iStartX - 1) >= iSrchRngHorLeft )
418        {
419          xTZSearchHelp( pcPatternKey, rcStruct, iStartX - 1, iStartY + 1, 0, 2 );
420        }
421        if ( (iStartX + 1) <= iSrchRngHorRight )
422        {
423          xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY + 1, 0, 2 );
424        }
425      }
426    }
427      break;
428    case 8:
429    {
430      if ( (iStartX + 1) <= iSrchRngHorRight )
431      {
432        xTZSearchHelp( pcPatternKey, rcStruct, iStartX + 1, iStartY, 0, 2 );
433      }
434      if ( (iStartY + 1) <= iSrchRngVerBottom )
435      {
436        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iStartY + 1, 0, 2 );
437      }
438    }
439      break;
440    default:
441    {
442      assert( false );
443    }
444      break;
445  } // switch( rcStruct.ucPointNr )
446}
447
448__inline Void TEncSearch::xTZ8PointSquareSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
449{
450  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
451  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
452  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
453  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
454 
455  // 8 point search,                   //   1 2 3
456  // search around the start point     //   4 0 5
457  // with the required  distance       //   6 7 8
458  assert( iDist != 0 );
459  const Int iTop        = iStartY - iDist;
460  const Int iBottom     = iStartY + iDist;
461  const Int iLeft       = iStartX - iDist;
462  const Int iRight      = iStartX + iDist;
463  rcStruct.uiBestRound += 1;
464 
465  if ( iTop >= iSrchRngVerTop ) // check top
466  {
467    if ( iLeft >= iSrchRngHorLeft ) // check top left
468    {
469      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iTop, 1, iDist );
470    }
471    // top middle
472    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
473   
474    if ( iRight <= iSrchRngHorRight ) // check top right
475    {
476      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iTop, 3, iDist );
477    }
478  } // check top
479  if ( iLeft >= iSrchRngHorLeft ) // check middle left
480  {
481    xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
482  }
483  if ( iRight <= iSrchRngHorRight ) // check middle right
484  {
485    xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
486  }
487  if ( iBottom <= iSrchRngVerBottom ) // check bottom
488  {
489    if ( iLeft >= iSrchRngHorLeft ) // check bottom left
490    {
491      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iBottom, 6, iDist );
492    }
493    // check bottom middle
494    xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
495   
496    if ( iRight <= iSrchRngHorRight ) // check bottom right
497    {
498      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iBottom, 8, iDist );
499    }
500  } // check bottom
501}
502
503__inline Void TEncSearch::xTZ8PointDiamondSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
504{
505  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
506  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
507  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
508  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
509 
510  // 8 point search,                   //   1 2 3
511  // search around the start point     //   4 0 5
512  // with the required  distance       //   6 7 8
513  assert ( iDist != 0 );
514  const Int iTop        = iStartY - iDist;
515  const Int iBottom     = iStartY + iDist;
516  const Int iLeft       = iStartX - iDist;
517  const Int iRight      = iStartX + iDist;
518  rcStruct.uiBestRound += 1;
519 
520  if ( iDist == 1 ) // iDist == 1
521  {
522    if ( iTop >= iSrchRngVerTop ) // check top
523    {
524      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
525    }
526    if ( iLeft >= iSrchRngHorLeft ) // check middle left
527    {
528      xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
529    }
530    if ( iRight <= iSrchRngHorRight ) // check middle right
531    {
532      xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
533    }
534    if ( iBottom <= iSrchRngVerBottom ) // check bottom
535    {
536      xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
537    }
538  }
539  else // if (iDist != 1)
540  {
541    if ( iDist <= 8 )
542    {
543      const Int iTop_2      = iStartY - (iDist>>1);
544      const Int iBottom_2   = iStartY + (iDist>>1);
545      const Int iLeft_2     = iStartX - (iDist>>1);
546      const Int iRight_2    = iStartX + (iDist>>1);
547     
548      if (  iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
549          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
550      {
551        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iTop,      2, iDist    );
552        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iTop_2,    1, iDist>>1 );
553        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2,    3, iDist>>1 );
554        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,    iStartY,   4, iDist    );
555        xTZSearchHelp( pcPatternKey, rcStruct, iRight,   iStartY,   5, iDist    );
556        xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2,  iBottom_2, 6, iDist>>1 );
557        xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, iDist>>1 );
558        xTZSearchHelp( pcPatternKey, rcStruct, iStartX,  iBottom,   7, iDist    );
559      }
560      else // check border
561      {
562        if ( iTop >= iSrchRngVerTop ) // check top
563        {
564          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
565        }
566        if ( iTop_2 >= iSrchRngVerTop ) // check half top
567        {
568          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
569          {
570            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iTop_2, 1, (iDist>>1) );
571          }
572          if ( iRight_2 <= iSrchRngHorRight ) // check half right
573          {
574            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iTop_2, 3, (iDist>>1) );
575          }
576        } // check half top
577        if ( iLeft >= iSrchRngHorLeft ) // check left
578        {
579          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 4, iDist );
580        }
581        if ( iRight <= iSrchRngHorRight ) // check right
582        {
583          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 5, iDist );
584        }
585        if ( iBottom_2 <= iSrchRngVerBottom ) // check half bottom
586        {
587          if ( iLeft_2 >= iSrchRngHorLeft ) // check half left
588          {
589            xTZSearchHelp( pcPatternKey, rcStruct, iLeft_2, iBottom_2, 6, (iDist>>1) );
590          }
591          if ( iRight_2 <= iSrchRngHorRight ) // check half right
592          {
593            xTZSearchHelp( pcPatternKey, rcStruct, iRight_2, iBottom_2, 8, (iDist>>1) );
594          }
595        } // check half bottom
596        if ( iBottom <= iSrchRngVerBottom ) // check bottom
597        {
598          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
599        }
600      } // check border
601    }
602    else // iDist > 8
603    {
604      if ( iTop >= iSrchRngVerTop && iLeft >= iSrchRngHorLeft &&
605          iRight <= iSrchRngHorRight && iBottom <= iSrchRngVerBottom ) // check border
606      {
607        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop,    0, iDist );
608        xTZSearchHelp( pcPatternKey, rcStruct, iLeft,   iStartY, 0, iDist );
609        xTZSearchHelp( pcPatternKey, rcStruct, iRight,  iStartY, 0, iDist );
610        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
611        for ( Int index = 1; index < 4; index++ )
612        {
613          Int iPosYT = iTop    + ((iDist>>2) * index);
614          Int iPosYB = iBottom - ((iDist>>2) * index);
615          Int iPosXL = iStartX - ((iDist>>2) * index);
616          Int iPosXR = iStartX + ((iDist>>2) * index);
617          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
618          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
619          xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
620          xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
621        }
622      }
623      else // check border
624      {
625        if ( iTop >= iSrchRngVerTop ) // check top
626        {
627          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 0, iDist );
628        }
629        if ( iLeft >= iSrchRngHorLeft ) // check left
630        {
631          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iStartY, 0, iDist );
632        }
633        if ( iRight <= iSrchRngHorRight ) // check right
634        {
635          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iStartY, 0, iDist );
636        }
637        if ( iBottom <= iSrchRngVerBottom ) // check bottom
638        {
639          xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 0, iDist );
640        }
641        for ( Int index = 1; index < 4; index++ )
642        {
643          Int iPosYT = iTop    + ((iDist>>2) * index);
644          Int iPosYB = iBottom - ((iDist>>2) * index);
645          Int iPosXL = iStartX - ((iDist>>2) * index);
646          Int iPosXR = iStartX + ((iDist>>2) * index);
647         
648          if ( iPosYT >= iSrchRngVerTop ) // check top
649          {
650            if ( iPosXL >= iSrchRngHorLeft ) // check left
651            {
652              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
653            }
654            if ( iPosXR <= iSrchRngHorRight ) // check right
655            {
656              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
657            }
658          } // check top
659          if ( iPosYB <= iSrchRngVerBottom ) // check bottom
660          {
661            if ( iPosXL >= iSrchRngHorLeft ) // check left
662            {
663              xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYB, 0, iDist );
664            }
665            if ( iPosXR <= iSrchRngHorRight ) // check right
666            {
667              xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYB, 0, iDist );
668            }
669          } // check bottom
670        } // for ...
671      } // check border
672    } // iDist <= 8
673  } // iDist == 1
674}
675
676//<--
677
678UInt TEncSearch::xPatternRefinement( TComPattern* pcPatternKey,
679                                    TComMv baseRefMv,
680                                    Int iFrac, TComMv& rcMvFrac )
681{
682  UInt  uiDist;
683  UInt  uiDistBest  = MAX_UINT;
684  UInt  uiDirecBest = 0;
685 
686  Pel*  piRefPos;
687  Int iRefStride = m_filteredBlock[0][0].getStride();
688#if NS_HAD
689  m_pcRdCost->setDistParam( pcPatternKey, m_filteredBlock[0][0].getLumaAddr(), iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME(), m_pcEncCfg->getUseNSQT() );
690#else
691  m_pcRdCost->setDistParam( pcPatternKey, m_filteredBlock[0][0].getLumaAddr(), iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME() );
692#endif
693 
694  TComMv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ);
695 
696  for (UInt i = 0; i < 9; i++)
697  {
698    TComMv cMvTest = pcMvRefine[i];
699    cMvTest += baseRefMv;
700   
701    Int horVal = cMvTest.getHor() * iFrac;
702    Int verVal = cMvTest.getVer() * iFrac;
703    piRefPos = m_filteredBlock[ verVal & 3 ][ horVal & 3 ].getLumaAddr();
704    if ( horVal == 2 && ( verVal & 1 ) == 0 )
705      piRefPos += 1;
706    if ( ( horVal & 1 ) == 0 && verVal == 2 )
707      piRefPos += iRefStride;
708    cMvTest = pcMvRefine[i];
709    cMvTest += rcMvFrac;
710
711    setDistParamComp(0);  // Y component
712
713    m_cDistParam.pCur = piRefPos;
714    uiDist = m_cDistParam.DistFunc( &m_cDistParam );
715    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
716   
717    if ( uiDist < uiDistBest )
718    {
719      uiDistBest  = uiDist;
720      uiDirecBest = i;
721    }
722  }
723 
724  rcMvFrac = pcMvRefine[uiDirecBest];
725 
726  return uiDistBest;
727}
728
729Void
730TEncSearch::xEncSubdivCbfQT( TComDataCU*  pcCU,
731                            UInt         uiTrDepth,
732                            UInt         uiAbsPartIdx,
733                            Bool         bLuma,
734                            Bool         bChroma )
735{
736  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
737  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
738  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
739  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
740
741  {
742    if( pcCU->getPredictionMode(0) == MODE_INTRA && pcCU->getPartitionSize(0) == SIZE_NxN && uiTrDepth == 0 )
743    {
744      assert( uiSubdiv );
745    }
746    else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
747    {
748      assert( uiSubdiv );
749    }
750    else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
751    {
752      assert( !uiSubdiv );
753    }
754    else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
755    {
756      assert( !uiSubdiv );
757    }
758    else
759    {
760      assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
761      if( bLuma )
762      {
763        m_pcEntropyCoder->encodeTransformSubdivFlag( uiSubdiv, uiFullDepth );
764      }
765    }
766  }
767 
768  if ( bChroma )
769  {
770    if( uiLog2TrafoSize > 2 )
771    {
772      if( uiTrDepth==0 || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth-1 ) )
773        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
774      if( uiTrDepth==0 || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth-1 ) )
775        m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
776    }
777  }
778
779  if( uiSubdiv )
780  {
781    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
782    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
783    {
784      xEncSubdivCbfQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, bLuma, bChroma );
785    }
786    return;
787  }
788 
789  {
790    //===== Cbfs =====
791    if( bLuma )
792    {
793      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
794    }
795  }
796}
797
798
799Void
800TEncSearch::xEncCoeffQT( TComDataCU*  pcCU,
801                        UInt         uiTrDepth,
802                        UInt         uiAbsPartIdx,
803                        TextType     eTextType,
804                        Bool         bRealCoeff )
805{
806  UInt  uiFullDepth     = pcCU->getDepth(0) + uiTrDepth;
807  UInt  uiTrMode        = pcCU->getTransformIdx( uiAbsPartIdx );
808  UInt  uiSubdiv        = ( uiTrMode > uiTrDepth ? 1 : 0 );
809  UInt  uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - uiFullDepth;
810  UInt  uiChroma        = ( eTextType != TEXT_LUMA ? 1 : 0 );
811 
812  if( uiSubdiv )
813  {
814    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
815      for( UInt uiPart = 0; uiPart < 4; uiPart++ )
816      {
817        xEncCoeffQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiQPartNum, eTextType, bRealCoeff );
818      }
819    return;
820  }
821 
822  if( eTextType != TEXT_LUMA && uiLog2TrafoSize == 2 )
823  {
824    assert( uiTrDepth > 0 );
825    uiTrDepth--;
826    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
827    Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
828    if( !bFirstQ )
829    {
830      return;
831    }
832  }
833 
834  //===== coefficients =====
835  UInt    uiWidth         = pcCU->getWidth  ( 0 ) >> ( uiTrDepth + uiChroma );
836  UInt    uiHeight        = pcCU->getHeight ( 0 ) >> ( uiTrDepth + uiChroma );
837  UInt    uiCoeffOffset   = ( pcCU->getPic()->getMinCUWidth() * pcCU->getPic()->getMinCUHeight() * uiAbsPartIdx ) >> ( uiChroma << 1 );
838  UInt    uiQTLayer       = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrafoSize;
839  TCoeff* pcCoeff         = 0;
840  switch( eTextType )
841  {
842    case TEXT_LUMA:     pcCoeff = ( bRealCoeff ? pcCU->getCoeffY () : m_ppcQTTempCoeffY [uiQTLayer] );  break;
843    case TEXT_CHROMA_U: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCb() : m_ppcQTTempCoeffCb[uiQTLayer] );  break;
844    case TEXT_CHROMA_V: pcCoeff = ( bRealCoeff ? pcCU->getCoeffCr() : m_ppcQTTempCoeffCr[uiQTLayer] );  break;
845    default:            assert(0);
846  }
847  pcCoeff += uiCoeffOffset;
848 
849  m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiWidth, uiHeight, uiFullDepth, eTextType );
850}
851
852
853Void
854TEncSearch::xEncIntraHeader( TComDataCU*  pcCU,
855                            UInt         uiTrDepth,
856                            UInt         uiAbsPartIdx,
857                            Bool         bLuma,
858                            Bool         bChroma )
859{
860  if( bLuma )
861  {
862    // CU header
863    if( uiAbsPartIdx == 0 )
864    {
865      if( !pcCU->getSlice()->isIntra() )
866      {
867        m_pcEntropyCoder->encodeSkipFlag( pcCU, 0, true );
868        m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
869      }
870     
871      m_pcEntropyCoder  ->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
872
873      if (pcCU->isIntra(0) && pcCU->getPartitionSize(0) == SIZE_2Nx2N )
874      {
875        m_pcEntropyCoder->encodeIPCMInfo( pcCU, 0, true );
876
877        if ( pcCU->getIPCMFlag (0))
878        {
879          return;
880        }
881      }
882    }
883    // luma prediction mode
884    if( pcCU->getPartitionSize(0) == SIZE_2Nx2N )
885    {
886      if( uiAbsPartIdx == 0 )
887      {
888        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, 0 );
889      }
890    }
891    else
892    {
893      UInt uiQNumParts = pcCU->getTotalNumPart() >> 2;
894      if( uiTrDepth == 0 )
895      {
896        assert( uiAbsPartIdx == 0 );
897        for( UInt uiPart = 0; uiPart < 4; uiPart++ )
898        {
899          m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPart * uiQNumParts );
900        }
901      }
902      else if( ( uiAbsPartIdx % uiQNumParts ) == 0 )
903      {
904        m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiAbsPartIdx );
905      }
906    }
907  }
908  if( bChroma )
909  {
910    // chroma prediction mode
911    if( uiAbsPartIdx == 0 )
912    {
913      m_pcEntropyCoder->encodeIntraDirModeChroma( pcCU, 0, true );
914    }
915  }
916}
917
918
919UInt
920TEncSearch::xGetIntraBitsQT( TComDataCU*  pcCU,
921                            UInt         uiTrDepth,
922                            UInt         uiAbsPartIdx,
923                            Bool         bLuma,
924                            Bool         bChroma,
925                            Bool         bRealCoeff /* just for test */ )
926{
927  m_pcEntropyCoder->resetBits();
928  xEncIntraHeader ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
929  xEncSubdivCbfQT ( pcCU, uiTrDepth, uiAbsPartIdx, bLuma, bChroma );
930 
931  if( bLuma )
932  {
933    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_LUMA,      bRealCoeff );
934  }
935  if( bChroma )
936  {
937    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_U,  bRealCoeff );
938    xEncCoeffQT   ( pcCU, uiTrDepth, uiAbsPartIdx, TEXT_CHROMA_V,  bRealCoeff );
939  }
940  UInt   uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
941  return uiBits;
942}
943
944
945
946Void
947TEncSearch::xIntraCodingLumaBlk( TComDataCU* pcCU,
948                                UInt        uiTrDepth,
949                                UInt        uiAbsPartIdx,
950                                TComYuv*    pcOrgYuv, 
951                                TComYuv*    pcPredYuv, 
952                                TComYuv*    pcResiYuv, 
953                                Dist&       ruiDist )
954{
955  UInt    uiLumaPredMode    = pcCU     ->getLumaIntraDir     ( uiAbsPartIdx );
956  UInt    uiFullDepth       = pcCU     ->getDepth   ( 0 )  + uiTrDepth;
957  UInt    uiWidth           = pcCU     ->getWidth   ( 0 ) >> uiTrDepth;
958  UInt    uiHeight          = pcCU     ->getHeight  ( 0 ) >> uiTrDepth;
959  UInt    uiStride          = pcOrgYuv ->getStride  ();
960  Pel*    piOrg             = pcOrgYuv ->getLumaAddr( uiAbsPartIdx );
961  Pel*    piPred            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
962  Pel*    piResi            = pcResiYuv->getLumaAddr( uiAbsPartIdx );
963  Pel*    piReco            = pcPredYuv->getLumaAddr( uiAbsPartIdx );
964 
965  UInt    uiLog2TrSize      = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
966  UInt    uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
967  UInt    uiNumCoeffPerInc  = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
968  TCoeff* pcCoeff           = m_ppcQTTempCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;
969#if ADAPTIVE_QP_SELECTION
970  Int*    pcArlCoeff        = m_ppcQTTempArlCoeffY[ uiQTLayer ] + uiNumCoeffPerInc * uiAbsPartIdx;
971#endif
972  Pel*    piRecQt           = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
973  UInt    uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
974 
975  UInt    uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
976  Pel*    piRecIPred        = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
977  UInt    uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getStride  ();
978 
979  //===== init availability pattern =====
980  Bool  bAboveAvail = false;
981  Bool  bLeftAvail  = false;
982  pcCU->getPattern()->initPattern   ( pcCU, uiTrDepth, uiAbsPartIdx );
983  pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
984 
985  //===== get prediction signal =====
986#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
987  if( uiLumaPredMode >= NUM_INTRA_MODE )
988  {
989    predIntraLumaDMM( pcCU, uiAbsPartIdx, uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail, true );
990  }
991  else
992  {
993#endif
994  predIntraLumaAng( pcCU->getPattern(), uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
995#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
996  }
997#endif
998 
999  //===== get residual signal =====
1000  {
1001    // get residual
1002    Pel*  pOrg    = piOrg;
1003    Pel*  pPred   = piPred;
1004    Pel*  pResi   = piResi;
1005    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1006    {
1007      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1008      {
1009        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1010      }
1011      pOrg  += uiStride;
1012      pResi += uiStride;
1013      pPred += uiStride;
1014    }
1015  }
1016 
1017  //===== transform and quantization =====
1018  //--- init rate estimation arrays for RDOQ ---
1019  if( m_pcEncCfg->getUseRDOQ() )
1020  {
1021    m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, uiWidth, TEXT_LUMA );
1022  }
1023  //--- transform and quantization ---
1024  UInt uiAbsSum = 0;
1025  pcCU       ->setTrIdxSubParts ( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1026
1027#if H0736_AVC_STYLE_QP_RANGE
1028  m_pcTrQuant->setQPforQuant    ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
1029#else
1030  m_pcTrQuant->setQPforQuant    ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_LUMA, 0 );
1031#endif
1032
1033#if RDOQ_CHROMA_LAMBDA
1034  m_pcTrQuant->selectLambda     (TEXT_LUMA); 
1035#endif
1036  m_pcTrQuant->transformNxN     ( pcCU, piResi, uiStride, pcCoeff, 
1037#if ADAPTIVE_QP_SELECTION
1038                                 pcArlCoeff, 
1039#endif
1040                                 uiWidth, uiHeight, uiAbsSum, TEXT_LUMA, uiAbsPartIdx );
1041 
1042  //--- set coded block flag ---
1043  pcCU->setCbfSubParts          ( ( uiAbsSum ? 1 : 0 ) << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );
1044  //--- inverse transform ---
1045  if( uiAbsSum )
1046  {
1047    Int scalingListType = 0 + g_eTTable[(Int)TEXT_LUMA];
1048    assert(scalingListType < 6);
1049#if LOSSLESS_CODING
1050    m_pcTrQuant->invtransformNxN( pcCU, TEXT_LUMA,pcCU->getLumaIntraDir( uiAbsPartIdx ), piResi, uiStride, pcCoeff, uiWidth, uiHeight, scalingListType );
1051#else
1052    m_pcTrQuant->invtransformNxN( TEXT_LUMA,pcCU->getLumaIntraDir( uiAbsPartIdx ), piResi, uiStride, pcCoeff, uiWidth, uiHeight, scalingListType );
1053#endif
1054  }
1055  else
1056  {
1057    Pel* pResi = piResi;
1058    memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );
1059    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1060    {
1061      memset( pResi, 0, sizeof( Pel ) * uiWidth );
1062      pResi += uiStride;
1063    }
1064  }
1065 
1066  //===== reconstruction =====
1067  {
1068    Pel* pPred      = piPred;
1069    Pel* pResi      = piResi;
1070    Pel* pReco      = piReco;
1071    Pel* pRecQt     = piRecQt;
1072    Pel* pRecIPred  = piRecIPred;
1073    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1074    {
1075      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1076      {
1077        pReco    [ uiX ] = Clip( pPred[ uiX ] + pResi[ uiX ] );
1078        pRecQt   [ uiX ] = pReco[ uiX ];
1079        pRecIPred[ uiX ] = pReco[ uiX ];
1080      }
1081      pPred     += uiStride;
1082      pResi     += uiStride;
1083      pReco     += uiStride;
1084      pRecQt    += uiRecQtStride;
1085      pRecIPred += uiRecIPredStride;
1086    }
1087  }
1088 
1089  //===== update distortion =====
1090#if HHI_VSO
1091  if ( m_pcRdCost->getUseVSO() )
1092  {
1093    ruiDist += m_pcRdCost->getDistVS  ( pcCU, uiAbsPartIdx, piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight, false, 0 );
1094  }
1095  else
1096#endif
1097  {
1098  ruiDist += m_pcRdCost->getDistPart( piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight );
1099}
1100}
1101
1102
1103Void
1104TEncSearch::xIntraCodingChromaBlk( TComDataCU* pcCU,
1105                                  UInt        uiTrDepth,
1106                                  UInt        uiAbsPartIdx,
1107                                  TComYuv*    pcOrgYuv, 
1108                                  TComYuv*    pcPredYuv, 
1109                                  TComYuv*    pcResiYuv, 
1110                                  Dist&       ruiDist,
1111                                  UInt        uiChromaId )
1112{
1113  UInt uiOrgTrDepth = uiTrDepth;
1114  UInt uiFullDepth  = pcCU->getDepth( 0 ) + uiTrDepth;
1115  UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1116  if( uiLog2TrSize == 2 )
1117  {
1118    assert( uiTrDepth > 0 );
1119    uiTrDepth--;
1120    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth ) << 1 );
1121    Bool bFirstQ = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
1122    if( !bFirstQ )
1123    {
1124      return;
1125    }
1126  }
1127 
1128  TextType  eText             = ( uiChromaId > 0 ? TEXT_CHROMA_V : TEXT_CHROMA_U );
1129  UInt      uiChromaPredMode  = pcCU     ->getChromaIntraDir( uiAbsPartIdx );
1130  UInt      uiWidth           = pcCU     ->getWidth   ( 0 ) >> ( uiTrDepth + 1 );
1131  UInt      uiHeight          = pcCU     ->getHeight  ( 0 ) >> ( uiTrDepth + 1 );
1132  UInt      uiStride          = pcOrgYuv ->getCStride ();
1133  Pel*      piOrg             = ( uiChromaId > 0 ? pcOrgYuv ->getCrAddr( uiAbsPartIdx ) : pcOrgYuv ->getCbAddr( uiAbsPartIdx ) );
1134  Pel*      piPred            = ( uiChromaId > 0 ? pcPredYuv->getCrAddr( uiAbsPartIdx ) : pcPredYuv->getCbAddr( uiAbsPartIdx ) );
1135  Pel*      piResi            = ( uiChromaId > 0 ? pcResiYuv->getCrAddr( uiAbsPartIdx ) : pcResiYuv->getCbAddr( uiAbsPartIdx ) );
1136  Pel*      piReco            = ( uiChromaId > 0 ? pcPredYuv->getCrAddr( uiAbsPartIdx ) : pcPredYuv->getCbAddr( uiAbsPartIdx ) );
1137 
1138  UInt      uiQTLayer         = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1139  UInt      uiNumCoeffPerInc  = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) ) >> 2;
1140  TCoeff*   pcCoeff           = ( uiChromaId > 0 ? m_ppcQTTempCoeffCr[ uiQTLayer ] : m_ppcQTTempCoeffCb[ uiQTLayer ] ) + uiNumCoeffPerInc * uiAbsPartIdx;
1141#if ADAPTIVE_QP_SELECTION
1142  Int*      pcArlCoeff        = ( uiChromaId > 0 ? m_ppcQTTempArlCoeffCr[ uiQTLayer ] : m_ppcQTTempArlCoeffCb[ uiQTLayer ] ) + uiNumCoeffPerInc * uiAbsPartIdx;
1143#endif
1144  Pel*      piRecQt           = ( uiChromaId > 0 ? m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr( uiAbsPartIdx ) : m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr( uiAbsPartIdx ) );
1145  UInt      uiRecQtStride     = m_pcQTTempTComYuv[ uiQTLayer ].getCStride();
1146 
1147  UInt      uiZOrder          = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1148  Pel*      piRecIPred        = ( uiChromaId > 0 ? pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder ) : pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder ) );
1149  UInt      uiRecIPredStride  = pcCU->getPic()->getPicYuvRec()->getCStride();
1150 
1151  //===== update chroma mode =====
1152  if( uiChromaPredMode == DM_CHROMA_IDX )
1153  {
1154    uiChromaPredMode          = pcCU->getLumaIntraDir( 0 );
1155#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1156    mapDMMtoIntraMode( uiChromaPredMode );
1157#endif
1158  }
1159 
1160  //===== init availability pattern =====
1161  Bool  bAboveAvail = false;
1162  Bool  bLeftAvail  = false;
1163  pcCU->getPattern()->initPattern         ( pcCU, uiTrDepth, uiAbsPartIdx );
1164
1165  if( uiChromaPredMode == LM_CHROMA_IDX && uiChromaId == 0 )
1166  {
1167    pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail, true );
1168    getLumaRecPixels( pcCU->getPattern(), uiWidth, uiHeight );
1169  }
1170 
1171  pcCU->getPattern()->initAdiPatternChroma( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1172  Int*  pPatChroma  = ( uiChromaId > 0 ? pcCU->getPattern()->getAdiCrBuf( uiWidth, uiHeight, m_piYuvExt ) : pcCU->getPattern()->getAdiCbBuf( uiWidth, uiHeight, m_piYuvExt ) );
1173 
1174  //===== get prediction signal =====
1175  if( uiChromaPredMode == LM_CHROMA_IDX )
1176  {
1177    predLMIntraChroma( pcCU->getPattern(), pPatChroma, piPred, uiStride, uiWidth, uiHeight, uiChromaId );
1178  }
1179  else
1180  {
1181    predIntraChromaAng( pcCU->getPattern(), pPatChroma, uiChromaPredMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail ); 
1182  }
1183 
1184  //===== get residual signal =====
1185  {
1186    // get residual
1187    Pel*  pOrg    = piOrg;
1188    Pel*  pPred   = piPred;
1189    Pel*  pResi   = piResi;
1190    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1191    {
1192      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1193      {
1194        pResi[ uiX ] = pOrg[ uiX ] - pPred[ uiX ];
1195      }
1196      pOrg  += uiStride;
1197      pResi += uiStride;
1198      pPred += uiStride;
1199    }
1200  }
1201 
1202  //===== transform and quantization =====
1203  {
1204    //--- init rate estimation arrays for RDOQ ---
1205    if( m_pcEncCfg->getUseRDOQ() )
1206    {
1207      m_pcEntropyCoder->estimateBit( m_pcTrQuant->m_pcEstBitsSbac, uiWidth, uiWidth, eText );
1208    }
1209    //--- transform and quantization ---
1210    UInt uiAbsSum = 0;
1211
1212#if H0736_AVC_STYLE_QP_RANGE
1213    if(eText == TEXT_CHROMA_U)
1214    {
1215      m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), pcCU->getSlice()->getPPS()->getChromaQpOffset() );
1216    }
1217    else
1218    {
1219      m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), pcCU->getSlice()->getPPS()->getChromaQpOffset2nd() );
1220    }
1221#else
1222    if(eText == TEXT_CHROMA_U)
1223      m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getPPS()->getChromaQpOffset() );
1224    else
1225      m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), !pcCU->getSlice()->getDepth(), pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getPPS()->getChromaQpOffset2nd() );
1226#endif
1227
1228#if RDOQ_CHROMA_LAMBDA
1229    m_pcTrQuant->selectLambda      (TEXT_CHROMA); 
1230#endif
1231    m_pcTrQuant->transformNxN      ( pcCU, piResi, uiStride, pcCoeff, 
1232#if ADAPTIVE_QP_SELECTION
1233                                     pcArlCoeff, 
1234#endif
1235                                     uiWidth, uiHeight, uiAbsSum, eText, uiAbsPartIdx );
1236    //--- set coded block flag ---
1237    pcCU->setCbfSubParts           ( ( uiAbsSum ? 1 : 0 ) << uiOrgTrDepth, eText, uiAbsPartIdx, pcCU->getDepth(0) + uiTrDepth );
1238    //--- inverse transform ---
1239    if( uiAbsSum )
1240    {
1241      Int scalingListType = 0 + g_eTTable[(Int)eText];
1242      assert(scalingListType < 6);
1243#if LOSSLESS_CODING
1244      m_pcTrQuant->invtransformNxN( pcCU, TEXT_CHROMA, REG_DCT, piResi, uiStride, pcCoeff, uiWidth, uiHeight, scalingListType );
1245#else
1246      m_pcTrQuant->invtransformNxN( TEXT_CHROMA, REG_DCT, piResi, uiStride, pcCoeff, uiWidth, uiHeight, scalingListType );
1247#endif
1248    }
1249    else
1250    {
1251      Pel* pResi = piResi;
1252      memset( pcCoeff, 0, sizeof( TCoeff ) * uiWidth * uiHeight );
1253      for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1254      {
1255        memset( pResi, 0, sizeof( Pel ) * uiWidth );
1256        pResi += uiStride;
1257      }
1258    }
1259  }
1260 
1261  //===== reconstruction =====
1262  {
1263    Pel* pPred      = piPred;
1264    Pel* pResi      = piResi;
1265    Pel* pReco      = piReco;
1266    Pel* pRecQt     = piRecQt;
1267    Pel* pRecIPred  = piRecIPred;
1268    for( UInt uiY = 0; uiY < uiHeight; uiY++ )
1269    {
1270      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1271      {
1272        pReco    [ uiX ] = Clip( pPred[ uiX ] + pResi[ uiX ] );
1273        pRecQt   [ uiX ] = pReco[ uiX ];
1274        pRecIPred[ uiX ] = pReco[ uiX ];
1275      }
1276      pPred     += uiStride;
1277      pResi     += uiStride;
1278      pReco     += uiStride;
1279      pRecQt    += uiRecQtStride;
1280      pRecIPred += uiRecIPredStride;
1281    }
1282  }
1283 
1284  //===== update distortion =====
1285#if WEIGHTED_CHROMA_DISTORTION
1286  ruiDist += m_pcRdCost->getDistPart( piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight, true );
1287#else
1288  ruiDist += m_pcRdCost->getDistPart( piReco, uiStride, piOrg, uiStride, uiWidth, uiHeight );
1289#endif
1290}
1291
1292
1293
1294Void
1295TEncSearch::xRecurIntraCodingQT( TComDataCU*  pcCU, 
1296                                UInt         uiTrDepth,
1297                                UInt         uiAbsPartIdx, 
1298                                Bool         bLumaOnly,
1299                                TComYuv*     pcOrgYuv, 
1300                                TComYuv*     pcPredYuv, 
1301                                TComYuv*     pcResiYuv, 
1302                                Dist&        ruiDistY,
1303                                Dist&        ruiDistC,
1304#if HHI_RQT_INTRA_SPEEDUP
1305                                Bool         bCheckFirst,
1306#endif
1307                                Double&      dRDCost )
1308{
1309  UInt    uiFullDepth   = pcCU->getDepth( 0 ) +  uiTrDepth;
1310  UInt    uiLog2TrSize  = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1311  Bool    bCheckFull    = ( uiLog2TrSize  <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
1312  Bool    bCheckSplit   = ( uiLog2TrSize  >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
1313 
1314#if HHI_RQT_INTRA_SPEEDUP
1315  if( bCheckFirst && bCheckFull )
1316  {
1317    bCheckSplit = false;
1318  }
1319#endif
1320#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1321  if( pcCU->getLumaIntraDir( uiAbsPartIdx ) >= NUM_INTRA_MODE )
1322  {
1323    bCheckSplit = false;
1324  }
1325#endif
1326  Double  dSingleCost   = MAX_DOUBLE;
1327  Dist    uiSingleDistY = 0;
1328  Dist    uiSingleDistC = 0;
1329  UInt    uiSingleCbfY  = 0;
1330  UInt    uiSingleCbfU  = 0;
1331  UInt    uiSingleCbfV  = 0;
1332 
1333  if( bCheckFull )
1334  {
1335    //----- store original entropy coding status -----
1336    if( m_bUseSBACRD && bCheckSplit )
1337    {
1338      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1339    }
1340    //----- code luma block with given intra prediction mode and store Cbf-----
1341    dSingleCost   = 0.0;
1342    xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistY ); 
1343    if( bCheckSplit )
1344    {
1345      uiSingleCbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrDepth );
1346    }
1347    //----- code chroma blocks with given intra prediction mode and store Cbf-----
1348    if( !bLumaOnly )
1349    {
1350      xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 0 ); 
1351      xIntraCodingChromaBlk ( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistC, 1 ); 
1352      if( bCheckSplit )
1353      {
1354        uiSingleCbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth );
1355        uiSingleCbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth );
1356      }
1357    }
1358    //----- determine rate and r-d cost -----
1359    UInt uiSingleBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );
1360
1361#if HHI_VSO
1362    if ( m_pcRdCost->getUseLambdaScaleVSO())
1363    {
1364      dSingleCost = m_pcRdCost->calcRdCostVSO( uiSingleBits, uiSingleDistY + uiSingleDistC );
1365    }
1366    else
1367#endif
1368    {
1369    dSingleCost       = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDistY + uiSingleDistC );
1370  }
1371  }
1372 
1373  if( bCheckSplit )
1374  {
1375    //----- store full entropy coding status, load original entropy coding status -----
1376    if( m_bUseSBACRD )
1377    {
1378      if( bCheckFull )
1379      {
1380        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1381        m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1382      }
1383      else
1384      {
1385        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1386      }
1387    }
1388    //----- code splitted block -----
1389    Double  dSplitCost      = 0.0;
1390    Dist    uiSplitDistY    = 0;
1391    Dist    uiSplitDistC    = 0;
1392    UInt    uiQPartsDiv     = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1393    UInt    uiAbsPartIdxSub = uiAbsPartIdx;
1394
1395    UInt    uiSplitCbfY = 0;
1396    UInt    uiSplitCbfU = 0;
1397    UInt    uiSplitCbfV = 0;
1398
1399    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiAbsPartIdxSub += uiQPartsDiv )
1400    {
1401#if HHI_RQT_INTRA_SPEEDUP
1402      xRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, bCheckFirst, dSplitCost );
1403#else
1404      xRecurIntraCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiSplitDistY, uiSplitDistC, dSplitCost );
1405#endif
1406
1407      uiSplitCbfY |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_LUMA, uiTrDepth + 1 );
1408      if(!bLumaOnly)
1409      {
1410        uiSplitCbfU |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_U, uiTrDepth + 1 );
1411        uiSplitCbfV |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_V, uiTrDepth + 1 );
1412      }
1413    }
1414
1415    for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1416    {
1417      pcCU->getCbf( TEXT_LUMA )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfY << uiTrDepth );
1418    }
1419    if( !bLumaOnly )
1420    {
1421      for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1422      {
1423        pcCU->getCbf( TEXT_CHROMA_U )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfU << uiTrDepth );
1424        pcCU->getCbf( TEXT_CHROMA_V )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfV << uiTrDepth );
1425      }
1426    }
1427    //----- restore context states -----
1428    if( m_bUseSBACRD )
1429    {
1430      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_ROOT ] );
1431    }
1432    //----- determine rate and r-d cost -----
1433    UInt uiSplitBits = xGetIntraBitsQT( pcCU, uiTrDepth, uiAbsPartIdx, true, !bLumaOnly, false );
1434#if HHI_VSO
1435    if( m_pcRdCost->getUseLambdaScaleVSO() )
1436    {
1437      dSplitCost = m_pcRdCost->calcRdCostVSO( uiSplitBits, uiSplitDistY + uiSplitDistC );
1438    }
1439    else
1440#endif
1441    {
1442    dSplitCost       = m_pcRdCost->calcRdCost( uiSplitBits, uiSplitDistY + uiSplitDistC );
1443    }
1444   
1445    //===== compare and set best =====
1446    if( dSplitCost < dSingleCost )
1447    {
1448      //--- update cost ---
1449      ruiDistY += uiSplitDistY;
1450      ruiDistC += uiSplitDistC;
1451      dRDCost  += dSplitCost;
1452      return;
1453    }
1454    //----- set entropy coding status -----
1455    if( m_bUseSBACRD )
1456    {
1457      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiFullDepth ][ CI_QT_TRAFO_TEST ] );
1458    }
1459   
1460    //--- set transform index and Cbf values ---
1461    pcCU->setTrIdxSubParts( uiTrDepth, uiAbsPartIdx, uiFullDepth );
1462    pcCU->setCbfSubParts  ( uiSingleCbfY << uiTrDepth, TEXT_LUMA, uiAbsPartIdx, uiFullDepth );
1463    if( !bLumaOnly )
1464    {
1465      pcCU->setCbfSubParts( uiSingleCbfU << uiTrDepth, TEXT_CHROMA_U, uiAbsPartIdx, uiFullDepth );
1466      pcCU->setCbfSubParts( uiSingleCbfV << uiTrDepth, TEXT_CHROMA_V, uiAbsPartIdx, uiFullDepth );
1467    }
1468   
1469    //--- set reconstruction for next intra prediction blocks ---
1470    UInt  uiWidth     = pcCU->getWidth ( 0 ) >> uiTrDepth;
1471    UInt  uiHeight    = pcCU->getHeight( 0 ) >> uiTrDepth;
1472    UInt  uiQTLayer   = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1473    UInt  uiZOrder    = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1474    Pel*  piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
1475    UInt  uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
1476    Pel*  piDes       = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
1477    UInt  uiDesStride = pcCU->getPic()->getPicYuvRec()->getStride  ();
1478    for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1479    {
1480      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1481      {
1482        piDes[ uiX ] = piSrc[ uiX ];
1483      }
1484    }
1485    if( !bLumaOnly )
1486    {
1487      uiWidth   >>= 1;
1488      uiHeight  >>= 1;
1489      piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getCbAddr  ( uiAbsPartIdx );
1490      uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getCStride ();
1491      piDes       = pcCU->getPic()->getPicYuvRec()->getCbAddr ( pcCU->getAddr(), uiZOrder );
1492      uiDesStride = pcCU->getPic()->getPicYuvRec()->getCStride();
1493      for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1494      {
1495        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1496        {
1497          piDes[ uiX ] = piSrc[ uiX ];
1498        }
1499      }
1500      piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getCrAddr  ( uiAbsPartIdx );
1501      piDes       = pcCU->getPic()->getPicYuvRec()->getCrAddr ( pcCU->getAddr(), uiZOrder );
1502      for( UInt uiY = 0; uiY < uiHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
1503      {
1504        for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1505        {
1506          piDes[ uiX ] = piSrc[ uiX ];
1507        }
1508      }
1509    }
1510  }
1511
1512#if HHI_VSO
1513  if ( m_pcRdCost->getUseRenModel() && bCheckFull )
1514  {
1515    UInt  uiWidth     = pcCU->getWidth ( 0 ) >> uiTrDepth;
1516    UInt  uiHeight    = pcCU->getHeight( 0 ) >> uiTrDepth;
1517    UInt  uiQTLayer   = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1518    Pel*  piSrc       = m_pcQTTempTComYuv[ uiQTLayer ].getLumaAddr( uiAbsPartIdx );
1519    UInt  uiSrcStride = m_pcQTTempTComYuv[ uiQTLayer ].getStride  ();
1520
1521    m_pcRdCost->setRenModelData( pcCU, uiAbsPartIdx, piSrc, (Int) uiSrcStride, (Int) uiWidth, (Int) uiHeight );
1522  }
1523#endif
1524
1525  ruiDistY += uiSingleDistY;
1526  ruiDistC += uiSingleDistC;
1527  dRDCost  += dSingleCost;
1528}
1529
1530
1531Void
1532TEncSearch::xSetIntraResultQT( TComDataCU* pcCU,
1533                              UInt        uiTrDepth,
1534                              UInt        uiAbsPartIdx,
1535                              Bool        bLumaOnly,
1536                              TComYuv*    pcRecoYuv )
1537{
1538  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
1539  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1540  if(  uiTrMode == uiTrDepth )
1541  {
1542    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1543    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1544   
1545    Bool bSkipChroma  = false;
1546    Bool bChromaSame  = false;
1547    if( !bLumaOnly && uiLog2TrSize == 2 )
1548    {
1549      assert( uiTrDepth > 0 );
1550      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
1551      bSkipChroma  = ( ( uiAbsPartIdx % uiQPDiv ) != 0 );
1552      bChromaSame  = true;
1553    }
1554   
1555    //===== copy transform coefficients =====
1556    UInt uiNumCoeffY    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
1557    UInt uiNumCoeffIncY = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
1558    TCoeff* pcCoeffSrcY = m_ppcQTTempCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1559    TCoeff* pcCoeffDstY = pcCU->getCoeffY ()              + ( uiNumCoeffIncY * uiAbsPartIdx );
1560    ::memcpy( pcCoeffDstY, pcCoeffSrcY, sizeof( TCoeff ) * uiNumCoeffY );
1561#if ADAPTIVE_QP_SELECTION
1562    Int* pcArlCoeffSrcY = m_ppcQTTempArlCoeffY [ uiQTLayer ] + ( uiNumCoeffIncY * uiAbsPartIdx );
1563    Int* pcArlCoeffDstY = pcCU->getArlCoeffY ()              + ( uiNumCoeffIncY * uiAbsPartIdx );
1564    ::memcpy( pcArlCoeffDstY, pcArlCoeffSrcY, sizeof( Int ) * uiNumCoeffY );
1565#endif
1566    if( !bLumaOnly && !bSkipChroma )
1567    {
1568      UInt uiNumCoeffC    = ( bChromaSame ? uiNumCoeffY    : uiNumCoeffY    >> 2 );
1569      UInt uiNumCoeffIncC = uiNumCoeffIncY >> 2;
1570      TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1571      TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1572      TCoeff* pcCoeffDstU = pcCU->getCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1573      TCoeff* pcCoeffDstV = pcCU->getCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1574      ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
1575      ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
1576#if ADAPTIVE_QP_SELECTION
1577      Int* pcArlCoeffSrcU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1578      Int* pcArlCoeffSrcV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1579      Int* pcArlCoeffDstU = pcCU->getArlCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1580      Int* pcArlCoeffDstV = pcCU->getArlCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1581      ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
1582      ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
1583#endif
1584    }
1585   
1586    //===== copy reconstruction =====
1587    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartLuma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSize, 1 << uiLog2TrSize );
1588    if( !bLumaOnly && !bSkipChroma )
1589    {
1590      UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
1591      m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
1592    }
1593  }
1594  else
1595  {
1596    UInt uiNumQPart  = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1597    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
1598    {
1599      xSetIntraResultQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiNumQPart, bLumaOnly, pcRecoYuv );
1600    }
1601  }
1602}
1603
1604
1605
1606Void
1607TEncSearch::xRecurIntraChromaCodingQT( TComDataCU*  pcCU, 
1608                                      UInt         uiTrDepth,
1609                                      UInt         uiAbsPartIdx, 
1610                                      TComYuv*     pcOrgYuv, 
1611                                      TComYuv*     pcPredYuv, 
1612                                      TComYuv*     pcResiYuv, 
1613                                      Dist&        ruiDist )
1614{
1615  UInt uiFullDepth = pcCU->getDepth( 0 ) +  uiTrDepth;
1616  UInt uiTrMode    = pcCU->getTransformIdx( uiAbsPartIdx );
1617  if(  uiTrMode == uiTrDepth )
1618  {
1619    xIntraCodingChromaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist, 0 ); 
1620    xIntraCodingChromaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist, 1 ); 
1621  }
1622  else
1623  {
1624    UInt uiSplitCbfU     = 0;
1625    UInt uiSplitCbfV     = 0;
1626    UInt uiQPartsDiv     = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1627    UInt uiAbsPartIdxSub = uiAbsPartIdx;
1628    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiAbsPartIdxSub += uiQPartsDiv )
1629    {
1630      xRecurIntraChromaCodingQT( pcCU, uiTrDepth + 1, uiAbsPartIdxSub, pcOrgYuv, pcPredYuv, pcResiYuv, ruiDist );
1631      uiSplitCbfU |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_U, uiTrDepth + 1 );
1632      uiSplitCbfV |= pcCU->getCbf( uiAbsPartIdxSub, TEXT_CHROMA_V, uiTrDepth + 1 );
1633    }
1634    for( UInt uiOffs = 0; uiOffs < 4 * uiQPartsDiv; uiOffs++ )
1635    {
1636      pcCU->getCbf( TEXT_CHROMA_U )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfU << uiTrDepth );
1637      pcCU->getCbf( TEXT_CHROMA_V )[ uiAbsPartIdx + uiOffs ] |= ( uiSplitCbfV << uiTrDepth );
1638    }
1639  }
1640}
1641
1642Void
1643TEncSearch::xSetIntraResultChromaQT( TComDataCU* pcCU,
1644                                    UInt        uiTrDepth,
1645                                    UInt        uiAbsPartIdx,
1646                                    TComYuv*    pcRecoYuv )
1647{
1648  UInt uiFullDepth  = pcCU->getDepth(0) + uiTrDepth;
1649  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
1650  if(  uiTrMode == uiTrDepth )
1651  {
1652    UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiFullDepth ] + 2;
1653    UInt uiQTLayer    = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
1654   
1655    Bool bChromaSame  = false;
1656    if( uiLog2TrSize == 2 )
1657    {
1658      assert( uiTrDepth > 0 );
1659      UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrDepth - 1 ) << 1 );
1660      if( ( uiAbsPartIdx % uiQPDiv ) != 0 )
1661      {
1662        return;
1663      }
1664      bChromaSame     = true;
1665    }
1666   
1667    //===== copy transform coefficients =====
1668    UInt uiNumCoeffC    = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( uiFullDepth << 1 );
1669    if( !bChromaSame )
1670    {
1671      uiNumCoeffC     >>= 2;
1672    }
1673    UInt uiNumCoeffIncC = ( pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() ) >> ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 ) + 2 );
1674    TCoeff* pcCoeffSrcU = m_ppcQTTempCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1675    TCoeff* pcCoeffSrcV = m_ppcQTTempCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1676    TCoeff* pcCoeffDstU = pcCU->getCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1677    TCoeff* pcCoeffDstV = pcCU->getCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1678    ::memcpy( pcCoeffDstU, pcCoeffSrcU, sizeof( TCoeff ) * uiNumCoeffC );
1679    ::memcpy( pcCoeffDstV, pcCoeffSrcV, sizeof( TCoeff ) * uiNumCoeffC );
1680#if ADAPTIVE_QP_SELECTION   
1681    Int* pcArlCoeffSrcU = m_ppcQTTempArlCoeffCb[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1682    Int* pcArlCoeffSrcV = m_ppcQTTempArlCoeffCr[ uiQTLayer ] + ( uiNumCoeffIncC * uiAbsPartIdx );
1683    Int* pcArlCoeffDstU = pcCU->getArlCoeffCb()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1684    Int* pcArlCoeffDstV = pcCU->getArlCoeffCr()              + ( uiNumCoeffIncC * uiAbsPartIdx );
1685    ::memcpy( pcArlCoeffDstU, pcArlCoeffSrcU, sizeof( Int ) * uiNumCoeffC );
1686    ::memcpy( pcArlCoeffDstV, pcArlCoeffSrcV, sizeof( Int ) * uiNumCoeffC );
1687#endif
1688   
1689    //===== copy reconstruction =====
1690    UInt uiLog2TrSizeChroma = ( bChromaSame ? uiLog2TrSize : uiLog2TrSize - 1 );
1691    m_pcQTTempTComYuv[ uiQTLayer ].copyPartToPartChroma( pcRecoYuv, uiAbsPartIdx, 1 << uiLog2TrSizeChroma, 1 << uiLog2TrSizeChroma );
1692  }
1693  else
1694  {
1695    UInt uiNumQPart  = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1696    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
1697    {
1698      xSetIntraResultChromaQT( pcCU, uiTrDepth + 1, uiAbsPartIdx + uiPart * uiNumQPart, pcRecoYuv );
1699    }
1700  }
1701}
1702
1703
1704Void
1705TEncSearch::preestChromaPredMode( TComDataCU* pcCU, 
1706                                 TComYuv*    pcOrgYuv, 
1707                                 TComYuv*    pcPredYuv )
1708{
1709  UInt  uiWidth     = pcCU->getWidth ( 0 ) >> 1;
1710  UInt  uiHeight    = pcCU->getHeight( 0 ) >> 1;
1711  UInt  uiStride    = pcOrgYuv ->getCStride();
1712  Pel*  piOrgU      = pcOrgYuv ->getCbAddr ( 0 );
1713  Pel*  piOrgV      = pcOrgYuv ->getCrAddr ( 0 );
1714  Pel*  piPredU     = pcPredYuv->getCbAddr ( 0 );
1715  Pel*  piPredV     = pcPredYuv->getCrAddr ( 0 );
1716 
1717  //===== init pattern =====
1718  Bool  bAboveAvail = false;
1719  Bool  bLeftAvail  = false;
1720  pcCU->getPattern()->initPattern         ( pcCU, 0, 0 );
1721  pcCU->getPattern()->initAdiPatternChroma( pcCU, 0, 0, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1722  Int*  pPatChromaU = pcCU->getPattern()->getAdiCbBuf( uiWidth, uiHeight, m_piYuvExt );
1723  Int*  pPatChromaV = pcCU->getPattern()->getAdiCrBuf( uiWidth, uiHeight, m_piYuvExt );
1724 
1725  //===== get best prediction modes (using SAD) =====
1726  UInt  uiMinMode   = 0;
1727  UInt  uiMaxMode   = 4;
1728  UInt  uiBestMode  = MAX_UINT;
1729  UInt  uiMinSAD    = MAX_UINT;
1730  for( UInt uiMode  = uiMinMode; uiMode < uiMaxMode; uiMode++ )
1731  {
1732    //--- get prediction ---
1733    predIntraChromaAng( pcCU->getPattern(), pPatChromaU, uiMode, piPredU, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1734    predIntraChromaAng( pcCU->getPattern(), pPatChromaV, uiMode, piPredV, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1735   
1736    //--- get SAD ---
1737    UInt  uiSAD  = m_pcRdCost->calcHAD( piOrgU, uiStride, piPredU, uiStride, uiWidth, uiHeight );
1738    uiSAD       += m_pcRdCost->calcHAD( piOrgV, uiStride, piPredV, uiStride, uiWidth, uiHeight );
1739    //--- check ---
1740    if( uiSAD < uiMinSAD )
1741    {
1742      uiMinSAD   = uiSAD;
1743      uiBestMode = uiMode;
1744    }
1745  }
1746 
1747  //===== set chroma pred mode =====
1748  pcCU->setChromIntraDirSubParts( uiBestMode, 0, pcCU->getDepth( 0 ) );
1749}
1750
1751Void
1752TEncSearch::estIntraPredQT( TComDataCU* pcCU, 
1753                           TComYuv*    pcOrgYuv, 
1754                           TComYuv*    pcPredYuv, 
1755                           TComYuv*    pcResiYuv, 
1756                           TComYuv*    pcRecoYuv,
1757                           Dist&       ruiDistC,
1758                           Bool        bLumaOnly )
1759{
1760  UInt    uiDepth        = pcCU->getDepth(0);
1761  UInt    uiNumPU        = pcCU->getNumPartInter();
1762  UInt    uiInitTrDepth  = pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1;
1763  UInt    uiWidth        = pcCU->getWidth (0) >> uiInitTrDepth;
1764  UInt    uiHeight       = pcCU->getHeight(0) >> uiInitTrDepth;
1765  UInt    uiQNumParts    = pcCU->getTotalNumPart() >> 2;
1766  UInt    uiWidthBit     = pcCU->getIntraSizeIdx(0);
1767  UInt    uiOverallDistY = 0;
1768  UInt    uiOverallDistC = 0;
1769  UInt    CandNum;
1770  Double  CandCostList[ FAST_UDI_MAX_RDMODE_NUM ];
1771 
1772  //===== set QP and clear Cbf =====
1773  if ( pcCU->getSlice()->getPPS()->getUseDQP() == true)
1774  {
1775    pcCU->setQPSubParts( pcCU->getQP(0), 0, uiDepth );
1776  }
1777  else
1778  {
1779    pcCU->setQPSubParts( pcCU->getSlice()->getSliceQp(), 0, uiDepth );
1780  }
1781 
1782  //===== loop over partitions =====
1783  UInt uiPartOffset = 0;
1784  for( UInt uiPU = 0; uiPU < uiNumPU; uiPU++, uiPartOffset += uiQNumParts )
1785  {
1786    //===== init pattern for luma prediction =====
1787    Bool bAboveAvail = false;
1788    Bool bLeftAvail  = false;
1789    pcCU->getPattern()->initPattern   ( pcCU, uiInitTrDepth, uiPartOffset );
1790    pcCU->getPattern()->initAdiPattern( pcCU, uiPartOffset, uiInitTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
1791   
1792    //===== determine set of modes to be tested (using prediction signal only) =====
1793#if LOGI_INTRA_NAME_3MPM
1794    Int numModesAvailable     = 35; //total number of Intra modes
1795#else
1796    Int numModesAvailable     = g_aucIntraModeNumAng[uiWidthBit];
1797#endif
1798    Pel* piOrg         = pcOrgYuv ->getLumaAddr( uiPU, uiWidth );
1799    Pel* piPred        = pcPredYuv->getLumaAddr( uiPU, uiWidth );
1800    UInt uiStride      = pcPredYuv->getStride();
1801    UInt uiRdModeList[FAST_UDI_MAX_RDMODE_NUM];
1802    Int numModesForFullRD = g_aucIntraModeNumFast[ uiWidthBit ];
1803   
1804#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1805    Bool bTestDmm = ( m_pcEncCfg->getUseDMM() );
1806#endif
1807
1808    Bool doFastSearch = (numModesForFullRD != numModesAvailable);
1809    if (doFastSearch)
1810    {
1811      assert(numModesForFullRD < numModesAvailable);
1812
1813      for( Int i=0; i < numModesForFullRD; i++ ) 
1814      {
1815        CandCostList[ i ] = MAX_DOUBLE;
1816      }
1817      CandNum = 0;
1818     
1819      for( Int modeIdx = 0; modeIdx < numModesAvailable; modeIdx++ )
1820      {
1821        UInt uiMode = modeIdx;
1822
1823        predIntraLumaAng( pcCU->getPattern(), uiMode, piPred, uiStride, uiWidth, uiHeight, pcCU, bAboveAvail, bLeftAvail );
1824       
1825        // use hadamard transform here
1826      Dist uiSad;
1827#if HHI_VSO
1828      if ( m_pcRdCost->getUseVSO() )
1829      {
1830        Bool bSad = !m_pcRdCost->getUseRenModel();
1831        uiSad = m_pcRdCost->getDistVS(pcCU, uiPartOffset, piPred, uiStride, piOrg, uiStride, uiWidth, uiHeight, bSad, 0 );
1832      }
1833      else
1834#endif
1835      {
1836        uiSad = (Dist) m_pcRdCost->calcHAD( piOrg, uiStride, piPred, uiStride, uiWidth, uiHeight );
1837      }
1838       
1839        UInt   iModeBits = xModeBitsIntra( pcCU, uiMode, uiPU, uiPartOffset, uiDepth, uiInitTrDepth );
1840
1841      Double dLambda;
1842#if HHI_VSO
1843      if ( m_pcRdCost->getUseLambdaScaleVSO() )
1844      {
1845        dLambda = m_pcRdCost->getUseRenModel() ? m_pcRdCost->getLambdaVSO() : m_pcRdCost->getSqrtLambdaVSO();
1846        //GT: Sad is SSE for VSO4
1847      }
1848      else
1849      {
1850        dLambda = m_pcRdCost->getSqrtLambda();
1851      }
1852#else
1853      dLambda = m_pcRdCost->getSqrtLambda();
1854#endif
1855
1856      Double cost = (Double)uiSad + (Double)iModeBits *  dLambda;
1857       
1858        CandNum += xUpdateCandList( uiMode, cost, numModesForFullRD, uiRdModeList, CandCostList );
1859
1860#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1861        if( bTestDmm ) bTestDmm = uiSad ? true : false;
1862#endif
1863      }
1864   
1865#if FAST_UDI_USE_MPM
1866#if LOGI_INTRA_NAME_3MPM
1867      Int uiPreds[3] = {-1, -1, -1};
1868#else
1869      Int uiPreds[2] = {-1, -1};
1870#endif
1871      Int iMode = -1;
1872      Int numCand = pcCU->getIntraDirLumaPredictor( uiPartOffset, uiPreds, &iMode );
1873#if LOGI_INTRA_NAME_3MPM
1874      if( iMode >= 0 )
1875      {
1876        numCand = iMode;
1877      }
1878#else
1879      if( iMode >= 0 )
1880      {
1881        numCand = 1;
1882        uiPreds[0] = iMode;
1883      }
1884#endif
1885     
1886      for( Int j=0; j < numCand; j++)
1887
1888      {
1889        Bool mostProbableModeIncluded = false;
1890        Int mostProbableMode = uiPreds[j];
1891       
1892        for( Int i=0; i < numModesForFullRD; i++)
1893        {
1894          mostProbableModeIncluded |= (mostProbableMode == uiRdModeList[i]);
1895        }
1896        if (!mostProbableModeIncluded)
1897        {
1898          uiRdModeList[numModesForFullRD++] = mostProbableMode;
1899        }
1900      }
1901#endif // FAST_UDI_USE_MPM
1902    }
1903    else
1904    {
1905      for( Int i=0; i < numModesForFullRD; i++)
1906      {
1907        uiRdModeList[i] = i;
1908      }
1909    }
1910   
1911#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1912    if( m_pcEncCfg->getUseDMM() && bTestDmm && uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE && uiWidth == uiHeight )
1913    {
1914#if HHI_DMM_WEDGE_INTRA
1915      UInt uiTabIdx  = 0;
1916      Int  iDeltaDC1 = 0;
1917      Int  iDeltaDC2 = 0;
1918      findWedgeFullMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTabIdx, iDeltaDC1, iDeltaDC2, bAboveAvail, bLeftAvail );
1919      pcCU->setWedgeFullTabIdxSubParts  ( uiTabIdx,  uiPartOffset, uiDepth + uiInitTrDepth );
1920      pcCU->setWedgeFullDeltaDC1SubParts( iDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1921      pcCU->setWedgeFullDeltaDC2SubParts( iDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1922
1923      uiRdModeList[ numModesForFullRD++ ] = DMM_WEDGE_FULL_IDX;
1924      uiRdModeList[ numModesForFullRD++ ] = DMM_WEDGE_FULL_D_IDX;
1925
1926      if ( uiWidth > 4 )
1927      {
1928        Int  iWedgeDeltaEnd = 0;
1929
1930        iDeltaDC1 = 0;
1931        iDeltaDC2 = 0;
1932
1933        findWedgePredDirMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTabIdx, iWedgeDeltaEnd, iDeltaDC1, iDeltaDC2, bAboveAvail, bLeftAvail );
1934        pcCU->setWedgePredDirTabIdxSubParts  ( uiTabIdx,       uiPartOffset, uiDepth + uiInitTrDepth );
1935        pcCU->setWedgePredDirDeltaEndSubParts( iWedgeDeltaEnd, uiPartOffset, uiDepth + uiInitTrDepth );
1936        pcCU->setWedgePredDirDeltaDC1SubParts( iDeltaDC1,      uiPartOffset, uiDepth + uiInitTrDepth );
1937        pcCU->setWedgePredDirDeltaDC2SubParts( iDeltaDC2,      uiPartOffset, uiDepth + uiInitTrDepth );
1938
1939        uiRdModeList[ numModesForFullRD++ ] = DMM_WEDGE_PREDDIR_IDX;
1940        uiRdModeList[ numModesForFullRD++ ] = DMM_WEDGE_PREDDIR_D_IDX;
1941      }
1942#endif
1943#if HHI_DMM_PRED_TEX
1944      UInt uiTexTabIdx  = 0;
1945      Int  iTexDeltaDC1 = 0;
1946      Int  iTexDeltaDC2 = 0;
1947      findWedgeTexMinDist( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, uiTexTabIdx, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail ); 
1948      pcCU->setWedgePredTexTabIdxSubParts  ( uiTexTabIdx,  uiPartOffset, uiDepth + uiInitTrDepth );
1949      pcCU->setWedgePredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1950      pcCU->setWedgePredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1951
1952      uiRdModeList[ numModesForFullRD++ ] = DMM_WEDGE_PREDTEX_IDX;
1953      uiRdModeList[ numModesForFullRD++ ] = DMM_WEDGE_PREDTEX_D_IDX;
1954
1955      if ( uiWidth > 4 )
1956      {
1957        iTexDeltaDC1 = 0;
1958        iTexDeltaDC2 = 0;
1959
1960        findContourPredTex( pcCU, uiPartOffset, piOrg, piPred, uiStride, uiWidth, uiHeight, iTexDeltaDC1, iTexDeltaDC2, bAboveAvail, bLeftAvail );
1961        pcCU->setContourPredTexDeltaDC1SubParts( iTexDeltaDC1, uiPartOffset, uiDepth + uiInitTrDepth );
1962        pcCU->setContourPredTexDeltaDC2SubParts( iTexDeltaDC2, uiPartOffset, uiDepth + uiInitTrDepth );
1963
1964        uiRdModeList[ numModesForFullRD++ ] = DMM_CONTOUR_PREDTEX_IDX;
1965        uiRdModeList[ numModesForFullRD++ ] = DMM_CONTOUR_PREDTEX_D_IDX;
1966      }
1967#endif
1968    }
1969#endif
1970
1971    //===== check modes (using r-d costs) =====
1972#if HHI_RQT_INTRA_SPEEDUP_MOD
1973    UInt   uiSecondBestMode  = MAX_UINT;
1974    Double dSecondBestPUCost = MAX_DOUBLE;
1975#endif
1976   
1977    UInt    uiBestPUMode  = 0;
1978    UInt    uiBestPUDistY = 0;
1979    UInt    uiBestPUDistC = 0;
1980    Double  dBestPUCost   = MAX_DOUBLE;
1981    for( UInt uiMode = 0; uiMode < numModesForFullRD; uiMode++ )
1982    {
1983      // set luma prediction mode
1984      UInt uiOrgMode = uiRdModeList[uiMode];
1985     
1986#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
1987      if( m_pcEncCfg->getIsDepth() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
1988      {
1989        continue;
1990      }
1991#endif
1992
1993      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
1994     
1995      // set context models
1996      if( m_bUseSBACRD )
1997      {
1998        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
1999      }
2000     
2001      // determine residual for partition
2002      Dist   uiPUDistY = 0;
2003      Dist   uiPUDistC = 0;
2004      Double dPUCost   = 0.0;
2005
2006
2007      // reset Model
2008#if HHI_VSO
2009      if( m_pcRdCost->getUseRenModel() )
2010      {
2011        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2012      }
2013#endif
2014
2015#if HHI_RQT_INTRA_SPEEDUP
2016      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );
2017#else
2018      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
2019#endif
2020     
2021      // check r-d cost
2022      if( dPUCost < dBestPUCost )
2023      {
2024#if HHI_RQT_INTRA_SPEEDUP_MOD
2025        uiSecondBestMode  = uiBestPUMode;
2026        dSecondBestPUCost = dBestPUCost;
2027#endif
2028        uiBestPUMode  = uiOrgMode;
2029        uiBestPUDistY = uiPUDistY;
2030        uiBestPUDistC = uiPUDistC;
2031        dBestPUCost   = dPUCost;
2032       
2033        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2034       
2035        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2036        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2037        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2038        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2039        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2040       
2041      }
2042#if HHI_RQT_INTRA_SPEEDUP_MOD
2043      else if( dPUCost < dSecondBestPUCost )
2044      {
2045        uiSecondBestMode  = uiOrgMode;
2046        dSecondBestPUCost = dPUCost;
2047      }
2048#endif
2049    } // Mode loop
2050   
2051#if HHI_RQT_INTRA_SPEEDUP
2052#if HHI_RQT_INTRA_SPEEDUP_MOD
2053    for( UInt ui =0; ui < 2; ++ui )
2054#endif
2055    {
2056#if HHI_RQT_INTRA_SPEEDUP_MOD
2057      UInt uiOrgMode   = ui ? uiSecondBestMode  : uiBestPUMode;
2058      if( uiOrgMode == MAX_UINT )
2059      {
2060        break;
2061      }
2062#else
2063      UInt uiOrgMode = uiBestPUMode;
2064#endif
2065     
2066      pcCU->setLumaIntraDirSubParts ( uiOrgMode, uiPartOffset, uiDepth + uiInitTrDepth );
2067     
2068      // set context models
2069      if( m_bUseSBACRD )
2070      {
2071        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2072      }
2073     
2074      // determine residual for partition
2075      Dist   uiPUDistY = 0;
2076      Dist   uiPUDistC = 0;
2077      Double dPUCost   = 0.0;
2078
2079#if HHI_VSO
2080      // reset Model
2081      if( m_pcRdCost->getUseRenModel() )
2082      {
2083        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight );
2084      }
2085#endif
2086
2087      xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, false, dPUCost );
2088     
2089      // check r-d cost
2090      if( dPUCost < dBestPUCost )
2091      {
2092        uiBestPUMode  = uiOrgMode;
2093        uiBestPUDistY = uiPUDistY;
2094        uiBestPUDistC = uiPUDistC;
2095        dBestPUCost   = dPUCost;
2096       
2097        xSetIntraResultQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcRecoYuv );
2098       
2099        UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2100        ::memcpy( m_puhQTTempTrIdx,  pcCU->getTransformIdx()       + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2101        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2102        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2103        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, uiQPartNum * sizeof( UChar ) );
2104       
2105      }
2106    } // Mode loop
2107#endif
2108   
2109    //--- update overall distortion ---
2110    uiOverallDistY += uiBestPUDistY;
2111    uiOverallDistC += uiBestPUDistC;
2112   
2113    //--- update transform index and cbf ---
2114    UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth(0) + uiInitTrDepth ) << 1 );
2115    ::memcpy( pcCU->getTransformIdx()       + uiPartOffset, m_puhQTTempTrIdx,  uiQPartNum * sizeof( UChar ) );
2116    ::memcpy( pcCU->getCbf( TEXT_LUMA     ) + uiPartOffset, m_puhQTTempCbf[0], uiQPartNum * sizeof( UChar ) );
2117    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ) + uiPartOffset, m_puhQTTempCbf[1], uiQPartNum * sizeof( UChar ) );
2118    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ) + uiPartOffset, m_puhQTTempCbf[2], uiQPartNum * sizeof( UChar ) );
2119   
2120    //--- set reconstruction for next intra prediction blocks ---
2121    if( uiPU != uiNumPU - 1 )
2122    {
2123      Bool bSkipChroma  = false;
2124      Bool bChromaSame  = false;
2125      UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> ( pcCU->getDepth(0) + uiInitTrDepth ) ] + 2;
2126      if( !bLumaOnly && uiLog2TrSize == 2 )
2127      {
2128        assert( uiInitTrDepth  > 0 );
2129        bSkipChroma  = ( uiPU != 0 );
2130        bChromaSame  = true;
2131      }
2132     
2133      UInt    uiCompWidth   = pcCU->getWidth ( 0 ) >> uiInitTrDepth;
2134      UInt    uiCompHeight  = pcCU->getHeight( 0 ) >> uiInitTrDepth;
2135      UInt    uiZOrder      = pcCU->getZorderIdxInCU() + uiPartOffset;
2136      Pel*    piDes         = pcCU->getPic()->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), uiZOrder );
2137      UInt    uiDesStride   = pcCU->getPic()->getPicYuvRec()->getStride();
2138      Pel*    piSrc         = pcRecoYuv->getLumaAddr( uiPartOffset );
2139      UInt    uiSrcStride   = pcRecoYuv->getStride();
2140      for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2141      {
2142        for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2143        {
2144          piDes[ uiX ] = piSrc[ uiX ];
2145        }
2146      }
2147
2148#if HHI_VSO
2149      // set model
2150      if( m_pcRdCost->getUseRenModel() )
2151      {
2152        piSrc = pcRecoYuv->getLumaAddr( uiPartOffset );
2153        m_pcRdCost->setRenModelData( pcCU, uiPartOffset, piSrc, uiSrcStride, uiCompWidth, uiCompHeight);
2154      }
2155#endif
2156
2157      if( !bLumaOnly && !bSkipChroma )
2158      {
2159        if( !bChromaSame )
2160        {
2161          uiCompWidth   >>= 1;
2162          uiCompHeight  >>= 1;
2163        }
2164        piDes         = pcCU->getPic()->getPicYuvRec()->getCbAddr( pcCU->getAddr(), uiZOrder );
2165        uiDesStride   = pcCU->getPic()->getPicYuvRec()->getCStride();
2166        piSrc         = pcRecoYuv->getCbAddr( uiPartOffset );
2167        uiSrcStride   = pcRecoYuv->getCStride();
2168        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2169        {
2170          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2171          {
2172            piDes[ uiX ] = piSrc[ uiX ];
2173          }
2174        }
2175        piDes         = pcCU->getPic()->getPicYuvRec()->getCrAddr( pcCU->getAddr(), uiZOrder );
2176        piSrc         = pcRecoYuv->getCrAddr( uiPartOffset );
2177        for( UInt uiY = 0; uiY < uiCompHeight; uiY++, piSrc += uiSrcStride, piDes += uiDesStride )
2178        {
2179          for( UInt uiX = 0; uiX < uiCompWidth; uiX++ )
2180          {
2181            piDes[ uiX ] = piSrc[ uiX ];
2182          }
2183        }
2184      }
2185    }
2186   
2187    //=== update PU data ====
2188    pcCU->setLumaIntraDirSubParts     ( uiBestPUMode, uiPartOffset, uiDepth + uiInitTrDepth );
2189    pcCU->copyToPic                   ( uiDepth, uiPU, uiInitTrDepth );
2190  } // PU loop
2191 
2192 
2193  if( uiNumPU > 1 )
2194  { // set Cbf for all blocks
2195    UInt uiCombCbfY = 0;
2196    UInt uiCombCbfU = 0;
2197    UInt uiCombCbfV = 0;
2198    UInt uiPartIdx  = 0;
2199    for( UInt uiPart = 0; uiPart < 4; uiPart++, uiPartIdx += uiQNumParts )
2200    {
2201      uiCombCbfY |= pcCU->getCbf( uiPartIdx, TEXT_LUMA,     1 );
2202      uiCombCbfU |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_U, 1 );
2203      uiCombCbfV |= pcCU->getCbf( uiPartIdx, TEXT_CHROMA_V, 1 );
2204    }
2205    for( UInt uiOffs = 0; uiOffs < 4 * uiQNumParts; uiOffs++ )
2206    {
2207      pcCU->getCbf( TEXT_LUMA     )[ uiOffs ] |= uiCombCbfY;
2208      pcCU->getCbf( TEXT_CHROMA_U )[ uiOffs ] |= uiCombCbfU;
2209      pcCU->getCbf( TEXT_CHROMA_V )[ uiOffs ] |= uiCombCbfV;
2210    }
2211  }
2212 
2213  //===== reset context models =====
2214  if(m_bUseSBACRD)
2215  {
2216    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2217  }
2218 
2219  //===== set distortion (rate and r-d costs are determined later) =====
2220  ruiDistC                   = uiOverallDistC;
2221  pcCU->getTotalDistortion() = uiOverallDistY + uiOverallDistC;
2222}
2223
2224
2225
2226Void
2227TEncSearch::estIntraPredChromaQT( TComDataCU* pcCU, 
2228                                 TComYuv*    pcOrgYuv, 
2229                                 TComYuv*    pcPredYuv, 
2230                                 TComYuv*    pcResiYuv, 
2231                                 TComYuv*    pcRecoYuv,
2232                                 Dist        uiPreCalcDistC )
2233{
2234  UInt    uiDepth     = pcCU->getDepth(0);
2235  UInt    uiBestMode  = 0;
2236  Dist    uiBestDist  = 0;
2237  Double  dBestCost   = MAX_DOUBLE;
2238 
2239  //----- init mode list -----
2240  UInt  uiMinMode = 0;
2241  UInt  uiModeList[ NUM_CHROMA_MODE ];
2242  pcCU->getAllowedChromaDir( 0, uiModeList );
2243  UInt  uiMaxMode = NUM_CHROMA_MODE;
2244
2245  //----- check chroma modes -----
2246  for( UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++ )
2247  {
2248    if ( !pcCU->getSlice()->getSPS()->getUseLMChroma() && uiModeList[uiMode] == LM_CHROMA_IDX )
2249    {
2250      continue;
2251    }
2252    //----- restore context models -----
2253    if( m_bUseSBACRD )
2254    {
2255      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2256    }
2257   
2258    //----- chroma coding -----
2259    Dist    uiDist = 0;
2260    pcCU->setChromIntraDirSubParts  ( uiModeList[uiMode], 0, uiDepth );
2261    xRecurIntraChromaCodingQT       ( pcCU,   0, 0, pcOrgYuv, pcPredYuv, pcResiYuv, uiDist );
2262    UInt    uiBits = xGetIntraBitsQT( pcCU,   0, 0, false, true, false );
2263    Double  dCost  = m_pcRdCost->calcRdCost( uiBits, uiDist );
2264   
2265    //----- compare -----
2266    if( dCost < dBestCost )
2267    {
2268      dBestCost   = dCost;
2269      uiBestDist  = uiDist;
2270      uiBestMode  = uiModeList[uiMode];
2271      UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2272      xSetIntraResultChromaQT( pcCU, 0, 0, pcRecoYuv );
2273      ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPN * sizeof( UChar ) );
2274      ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPN * sizeof( UChar ) );
2275    }
2276  }
2277 
2278  //----- set data -----
2279  UInt  uiQPN = pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 );
2280  ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPN * sizeof( UChar ) );
2281  ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPN * sizeof( UChar ) );
2282  pcCU->setChromIntraDirSubParts( uiBestMode, 0, uiDepth );
2283  pcCU->getTotalDistortion      () += uiBestDist - uiPreCalcDistC;
2284 
2285  //----- restore context models -----
2286  if( m_bUseSBACRD )
2287  {
2288    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
2289  }
2290}
2291
2292/** Function for encoding and reconstructing luma/chroma samples of a PCM mode CU.
2293 * \param pcCU pointer to current CU
2294 * \param uiAbsPartIdx part index
2295 * \param piOrg pointer to original sample arrays
2296 * \param piPCM pointer to PCM code arrays
2297 * \param piPred pointer to prediction signal arrays
2298 * \param piResi pointer to residual signal arrays
2299 * \param piReco pointer to reconstructed sample arrays
2300 * \param uiStride stride of the original/prediction/residual sample arrays
2301 * \param uiWidth block width
2302 * \param uiHeight block height
2303 * \param ttText texture component type
2304 * \returns Void
2305 */
2306Void TEncSearch::xEncPCM (TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piOrg, Pel* piPCM, Pel* piPred, Pel* piResi, Pel* piReco, UInt uiStride, UInt uiWidth, UInt uiHeight, TextType eText )
2307{
2308  UInt uiX, uiY;
2309  UInt uiReconStride;
2310  Pel* pOrg  = piOrg;
2311  Pel* pPCM  = piPCM;
2312  Pel* pPred = piPred;
2313  Pel* pResi = piResi;
2314  Pel* pReco = piReco;
2315  Pel* pRecoPic;
2316  UInt uiInternalBitDepth = g_uiBitDepth + g_uiBitIncrement;
2317  UInt uiPCMBitDepth;
2318
2319  if( eText == TEXT_LUMA)
2320  {
2321    uiReconStride = pcCU->getPic()->getPicYuvRec()->getStride();
2322    pRecoPic      = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiAbsPartIdx);
2323    uiPCMBitDepth = pcCU->getSlice()->getSPS()->getPCMBitDepthLuma();
2324  }
2325  else
2326  {
2327    uiReconStride = pcCU->getPic()->getPicYuvRec()->getCStride();
2328
2329    if( eText == TEXT_CHROMA_U )
2330    {
2331      pRecoPic = pcCU->getPic()->getPicYuvRec()->getCbAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiAbsPartIdx);
2332    }
2333    else
2334    {
2335      pRecoPic = pcCU->getPic()->getPicYuvRec()->getCrAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiAbsPartIdx);
2336    }
2337    uiPCMBitDepth = pcCU->getSlice()->getSPS()->getPCMBitDepthChroma();
2338  }
2339
2340  // Reset pred and residual
2341  for( uiY = 0; uiY < uiHeight; uiY++ )
2342  {
2343    for( uiX = 0; uiX < uiWidth; uiX++ )
2344    {
2345      pPred[uiX] = 0;
2346      pResi[uiX] = 0;
2347    }
2348    pPred += uiStride;
2349    pResi += uiStride;
2350  }
2351
2352  // Encode
2353  for( uiY = 0; uiY < uiHeight; uiY++ )
2354  {
2355    for( uiX = 0; uiX < uiWidth; uiX++ )
2356    {
2357      pPCM[uiX] = (pOrg[uiX]>>(uiInternalBitDepth - uiPCMBitDepth));
2358    }
2359    pPCM += uiWidth;
2360    pOrg += uiStride;
2361  }
2362
2363  pPCM  = piPCM;
2364
2365  // Reconstruction
2366  for( uiY = 0; uiY < uiHeight; uiY++ )
2367  {
2368    for( uiX = 0; uiX < uiWidth; uiX++ )
2369    {
2370      pReco   [uiX] = (pPCM[uiX]<<(uiInternalBitDepth - uiPCMBitDepth));
2371      pRecoPic[uiX] = pReco[uiX];
2372    }
2373    pPCM += uiWidth;
2374    pReco += uiStride;
2375    pRecoPic += uiReconStride;
2376  }
2377}
2378
2379/**  Function for PCM mode estimation.
2380 * \param pcCU
2381 * \param pcOrgYuv
2382 * \param rpcPredYuv
2383 * \param rpcResiYuv
2384 * \param rpcRecoYuv
2385 * \returns Void
2386 */
2387Void TEncSearch::IPCMSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv )
2388{
2389  UInt   uiDepth        = pcCU->getDepth(0);
2390  UInt   uiWidth        = pcCU->getWidth(0);
2391  UInt   uiHeight       = pcCU->getHeight(0);
2392  UInt   uiStride       = rpcPredYuv->getStride();
2393  UInt   uiStrideC      = rpcPredYuv->getCStride();
2394  UInt   uiWidthC       = uiWidth  >> 1;
2395  UInt   uiHeightC      = uiHeight >> 1;
2396  Dist   uiDistortion = 0;
2397  UInt   uiBits;
2398
2399  Double dCost;
2400
2401  Pel*    pOrig;
2402  Pel*    pResi;
2403  Pel*    pReco;
2404  Pel*    pPred;
2405  Pel*    pPCM;
2406
2407  UInt uiAbsPartIdx = 0;
2408
2409  UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
2410  UInt uiLumaOffset   = uiMinCoeffSize*uiAbsPartIdx;
2411  UInt uiChromaOffset = uiLumaOffset>>2;
2412
2413  // Luminance
2414  pOrig    = pcOrgYuv->getLumaAddr(0, uiWidth);
2415  pResi    = rpcResiYuv->getLumaAddr(0, uiWidth);
2416  pPred    = rpcPredYuv->getLumaAddr(0, uiWidth);
2417  pReco    = rpcRecoYuv->getLumaAddr(0, uiWidth);
2418  pPCM     = pcCU->getPCMSampleY() + uiLumaOffset;
2419
2420  xEncPCM ( pcCU, 0, pOrig, pPCM, pPred, pResi, pReco, uiStride, uiWidth, uiHeight, TEXT_LUMA );
2421
2422  // Chroma U
2423  pOrig    = pcOrgYuv->getCbAddr();
2424  pResi    = rpcResiYuv->getCbAddr();
2425  pPred    = rpcPredYuv->getCbAddr();
2426  pReco    = rpcRecoYuv->getCbAddr();
2427  pPCM     = pcCU->getPCMSampleCb() + uiChromaOffset;
2428
2429  xEncPCM ( pcCU, 0, pOrig, pPCM, pPred, pResi, pReco, uiStrideC, uiWidthC, uiHeightC, TEXT_CHROMA_U );
2430
2431  // Chroma V
2432  pOrig    = pcOrgYuv->getCrAddr();
2433  pResi    = rpcResiYuv->getCrAddr();
2434  pPred    = rpcPredYuv->getCrAddr();
2435  pReco    = rpcRecoYuv->getCrAddr();
2436  pPCM     = pcCU->getPCMSampleCr() + uiChromaOffset;
2437
2438  xEncPCM ( pcCU, 0, pOrig, pPCM, pPred, pResi, pReco, uiStrideC, uiWidthC, uiHeightC, TEXT_CHROMA_V );
2439
2440  m_pcEntropyCoder->resetBits();
2441  xEncIntraHeader ( pcCU, uiDepth, uiAbsPartIdx, true, false);
2442  uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
2443
2444#if HHI_VSO
2445  if( m_pcRdCost->getUseLambdaScaleVSO() )
2446  {
2447    dCost =  m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );
2448  }
2449  else
2450#endif
2451  {
2452  dCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
2453  }
2454
2455  if(m_bUseSBACRD)
2456  {
2457    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
2458  }
2459
2460  pcCU->getTotalBits()       = uiBits;
2461  pcCU->getTotalCost()       = dCost;
2462  pcCU->getTotalDistortion() = uiDistortion;
2463
2464  pcCU->copyToPic(uiDepth, 0, 0);
2465}
2466
2467Void TEncSearch::xGetInterPredictionError( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, UInt& ruiErr, Bool bHadamard )
2468{
2469  motionCompensation( pcCU, &m_tmpYuvPred, REF_PIC_LIST_X, iPartIdx );
2470
2471  UInt uiAbsPartIdx = 0;
2472  Int iWidth = 0;
2473  Int iHeight = 0;
2474  pcCU->getPartIndexAndSize( iPartIdx, uiAbsPartIdx, iWidth, iHeight );
2475
2476  DistParam cDistParam;
2477
2478  cDistParam.bApplyWeight = false;
2479
2480  m_pcRdCost->setDistParam( cDistParam, 
2481                            pcYuvOrg->getLumaAddr( uiAbsPartIdx ), pcYuvOrg->getStride(), 
2482                            m_tmpYuvPred .getLumaAddr( uiAbsPartIdx ), m_tmpYuvPred .getStride(), 
2483#if NS_HAD
2484                            iWidth, iHeight, m_pcEncCfg->getUseHADME(), m_pcEncCfg->getUseNSQT() );
2485#else
2486                            iWidth, iHeight, m_pcEncCfg->getUseHADME() );
2487#endif
2488  ruiErr = cDistParam.DistFunc( &cDistParam );
2489}
2490
2491/** estimation of best merge coding
2492 * \param pcCU
2493 * \param pcYuvOrg
2494 * \param iPUIdx
2495 * \param uiInterDir
2496 * \param pacMvField
2497 * \param uiMergeIndex
2498 * \param ruiCost
2499 * \param ruiBits
2500 * \param puhNeighCands
2501 * \param bValid
2502 * \returns Void
2503 */
2504#if CU_BASED_MRG_CAND_LIST
2505Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost, TComMvField* cMvFieldNeighbours, UChar* uhInterDirNeighbours, Int& numValidMergeCand )
2506#else
2507#if LG_RESTRICTEDRESPRED_M24766
2508Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* rpcResiPredYuv, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost )
2509#else
2510Void TEncSearch::xMergeEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPUIdx, UInt& uiInterDir, TComMvField* pacMvField, UInt& uiMergeIndex, UInt& ruiCost )
2511#endif
2512#endif
2513{
2514#if !CU_BASED_MRG_CAND_LIST
2515#if HHI_INTER_VIEW_MOTION_PRED
2516  TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS_MEM << 1]; // double length for mv of both lists
2517  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS_MEM];
2518  Int numValidMergeCand = 0;
2519  for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS_MEM; ++ui )
2520#else
2521  TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
2522  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
2523  Int numValidMergeCand = 0;
2524  for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ++ui )
2525#endif
2526  {
2527    uhInterDirNeighbours[ui] = 0;
2528  }
2529#endif
2530
2531  UInt uiAbsPartIdx = 0;
2532  Int iWidth = 0;
2533  Int iHeight = 0; 
2534
2535  pcCU->getPartIndexAndSize( iPUIdx, uiAbsPartIdx, iWidth, iHeight );
2536  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
2537#if CU_BASED_MRG_CAND_LIST
2538  PartSize partSize = pcCU->getPartitionSize( 0 );
2539  if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && partSize != SIZE_2Nx2N && pcCU->getWidth( 0 ) <= 8 )
2540  {
2541    pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
2542    if ( iPUIdx == 0 )
2543    {
2544      pcCU->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
2545    }
2546    pcCU->setPartSizeSubParts( partSize, 0, uiDepth );
2547  }
2548  else
2549  {
2550    pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand );
2551  }
2552#else
2553  pcCU->getInterMergeCandidates( uiAbsPartIdx, iPUIdx, uiDepth, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
2554#endif
2555
2556#if HHI_INTER_VIEW_MOTION_PRED
2557  const int maxNumMergeCand = MRG_MAX_NUM_CANDS_SIGNALED + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
2558#endif
2559#if LG_RESTRICTEDRESPRED_M24766
2560  Int iPUResiPredShift[4];
2561  Int iLastAddResiShift = -1000;
2562#endif
2563  ruiCost = MAX_UINT;
2564  for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
2565  {
2566    {
2567      UInt uiCostCand = MAX_UINT;
2568      UInt uiBitsCand = 0;
2569     
2570      PartSize ePartSize = pcCU->getPartitionSize( 0 );
2571
2572      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
2573      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
2574#if LG_RESTRICTEDRESPRED_M24766
2575          Int iAddResiShift;
2576          UInt uiPartAddr;
2577          Int iRoiWidth, iRoiHeight;
2578
2579          pcCU->getPartIndexAndSize( iPUIdx, uiPartAddr, iRoiWidth, iRoiHeight );
2580          iAddResiShift = pcCU->getResiPredMode(uiPartAddr);
2581          iAddResiShift = (pcCU->getSlice()->getPPS()->getUseWP() || pcCU->getInterDir(uiPartAddr) != 3) ? (iAddResiShift >= 0 ? 0 : -1) : (iAddResiShift >= 0 ? 1 - iAddResiShift : -1);
2582
2583          if( pcCU->getResPredFlag( 0 ))
2584          { // subtract residual prediction from original in motion search
2585                  if(iLastAddResiShift != iAddResiShift)
2586                  {
2587                          //add subtracted residual last time
2588                          if(iLastAddResiShift >= 0)
2589                          {
2590                                  iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = iLastAddResiShift;
2591                                  pcYuvOrg->add(iPUResiPredShift, ePartSize, rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ));
2592                          }
2593                          //subtract residual
2594                          if(iAddResiShift >= 0)
2595                          {
2596                                  iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = iAddResiShift;
2597                                  pcYuvOrg->add(iPUResiPredShift, ePartSize, rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ), true );
2598                          }
2599                          iLastAddResiShift = iAddResiShift;
2600                  }
2601          }
2602#endif
2603      xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2604      uiBitsCand = uiMergeCand + 1;
2605#if HHI_INTER_VIEW_MOTION_PRED
2606      if (uiMergeCand == maxNumMergeCand - 1 )
2607#else
2608      if (uiMergeCand == MRG_MAX_NUM_CANDS_SIGNALED -1)
2609#endif
2610      {
2611         uiBitsCand--;
2612      }
2613      uiCostCand = uiCostCand + m_pcRdCost->getCost( uiBitsCand );
2614      if ( uiCostCand < ruiCost )
2615      {
2616        ruiCost = uiCostCand;
2617        pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
2618        pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
2619        uiInterDir = uhInterDirNeighbours[uiMergeCand];
2620        uiMergeIndex = uiMergeCand;
2621      }
2622    }
2623  }
2624#if LG_RESTRICTEDRESPRED_M24766
2625  if( pcCU->getResPredFlag( 0 ) && iLastAddResiShift >= 0)
2626  {
2627          iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = iLastAddResiShift;
2628          pcYuvOrg->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ));
2629  }
2630#endif
2631}
2632
2633/** search of the best candidate for inter prediction
2634 * \param pcCU
2635 * \param pcOrgYuv
2636 * \param rpcPredYuv
2637 * \param rpcResiYuv
2638 * \param rpcRecoYuv
2639 * \param bUseRes
2640 * \returns Void
2641 */
2642#if AMP_MRG
2643#if LG_RESTRICTEDRESPRED_M24766
2644Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* rpcResiPredYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes, Bool bUseMRG )
2645#else
2646Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes, Bool bUseMRG )
2647#endif
2648#else
2649Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, Bool bUseRes )
2650#endif
2651{
2652  m_acYuvPred[0].clear();
2653  m_acYuvPred[1].clear();
2654  m_cYuvPredTemp.clear();
2655  rpcPredYuv->clear();
2656 
2657  if ( !bUseRes )
2658  {
2659    rpcResiYuv->clear();
2660  }
2661 
2662  rpcRecoYuv->clear();
2663 
2664  TComMv        cMvSrchRngLT;
2665  TComMv        cMvSrchRngRB;
2666 
2667  TComMv        cMvZero;
2668  TComMv        TempMv; //kolya
2669 
2670  TComMv        cMv[2];
2671  TComMv        cMvBi[2];
2672  TComMv        cMvTemp[2][33];
2673 
2674  Int           iNumPart    = pcCU->getNumPartInter();
2675  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
2676 
2677  TComMv        cMvPred[2][33];
2678 
2679  TComMv        cMvPredBi[2][33];
2680  Int           aaiMvpIdxBi[2][33];
2681 
2682  Int           aaiMvpIdx[2][33];
2683  Int           aaiMvpNum[2][33];
2684 
2685  AMVPInfo aacAMVPInfo[2][33];
2686 
2687  Int           iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
2688  Int           iRefIdxBi[2];
2689 
2690  UInt          uiPartAddr;
2691  Int           iRoiWidth, iRoiHeight;
2692 
2693  UInt          uiMbBits[3] = {1, 1, 0};
2694 
2695  UInt          uiLastMode = 0;
2696  Int           iRefStart, iRefEnd;
2697 
2698  PartSize      ePartSize = pcCU->getPartitionSize( 0 );
2699
2700#if H0111_MVD_L1_ZERO
2701  Int           bestBiPRefIdxL1 = 0;
2702  Int           bestBiPMvpL1 = 0;
2703  UInt          biPDistTemp = MAX_INT;
2704#endif
2705
2706#if ZERO_MVD_EST
2707  Int           aiZeroMvdMvpIdx[2] = {-1, -1};
2708  Int           aiZeroMvdRefIdx[2] = {0, 0};
2709  Int           iZeroMvdDir = -1;
2710#endif
2711
2712#if CU_BASED_MRG_CAND_LIST
2713#if HHI_INTER_VIEW_MOTION_PRED
2714  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS_MEM << 1]; // double length for mv of both lists
2715  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS_MEM];
2716  Int numValidMergeCand = 0 ;
2717#else
2718  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
2719  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
2720  Int numValidMergeCand = 0 ;
2721#endif
2722#endif
2723
2724#if HHI_INTER_VIEW_MOTION_PRED
2725  Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
2726#endif
2727
2728  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
2729  {
2730    UInt          uiCost[2] = { MAX_UINT, MAX_UINT };
2731    UInt          uiCostBi  =   MAX_UINT;
2732    UInt          uiCostTemp;
2733   
2734    UInt          uiBits[3];
2735    UInt          uiBitsTemp;
2736#if ZERO_MVD_EST
2737    UInt          uiZeroMvdCost = MAX_UINT;
2738    UInt          uiZeroMvdCostTemp;
2739    UInt          uiZeroMvdBitsTemp;
2740    UInt          uiZeroMvdDistTemp = MAX_UINT;
2741    UInt          auiZeroMvdBits[3];
2742#endif
2743#if H0111_MVD_L1_ZERO
2744    UInt          bestBiPDist = MAX_INT;
2745#endif
2746
2747    UInt          uiCostTempL0[MAX_NUM_REF];
2748    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) uiCostTempL0[iNumRef] = MAX_UINT;
2749    UInt          uiBitsTempL0[MAX_NUM_REF];
2750#if LG_RESTRICTEDRESPRED_M24766
2751        Int iPUResiPredShift[4] = {0, 0, 0, 0};
2752#endif
2753    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
2754   
2755    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
2756   
2757#if AMP_MRG
2758    Bool bTestNormalMC = true;
2759   
2760    if ( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 )
2761    {
2762      bTestNormalMC = false;
2763    }
2764   
2765    if (bTestNormalMC)
2766    {
2767#endif
2768#if LG_RESTRICTEDRESPRED_M24766
2769                Bool bLastResiFlag = false;
2770#endif
2771    //  Uni-directional prediction
2772    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
2773    {
2774      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
2775     
2776      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
2777      {
2778#if LG_RESTRICTEDRESPRED_M24766
2779                  if( pcCU->getResPredFlag( 0 ))
2780                  {
2781                          if(pcCU->getSlice()->getViewId() == pcCU->getSlice()->getRefViewId(eRefPicList, iRefIdxTemp))
2782                          { // subtract residual prediction from original in motion search
2783                                  if(!bLastResiFlag)
2784                                          pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ), true );
2785                                  bLastResiFlag = true;
2786                          }
2787                          else
2788                          {
2789                                  if(bLastResiFlag)
2790                                          pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ));
2791                                  bLastResiFlag = false;
2792                          }
2793                  }
2794#endif
2795        uiBitsTemp = uiMbBits[iRefList];
2796        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
2797        {
2798          uiBitsTemp += iRefIdxTemp+1;
2799          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
2800        }
2801#if H0111_MVD_L1_ZERO
2802#if ZERO_MVD_EST
2803        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp, &uiZeroMvdDistTemp);
2804#else
2805        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
2806#endif
2807#else
2808#if ZERO_MVD_EST
2809        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &uiZeroMvdDistTemp);
2810#else
2811        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp]);
2812#endif
2813#endif
2814        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
2815        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
2816       
2817#if H0111_MVD_L1_ZERO
2818        if(pcCU->getSlice()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
2819        {
2820          bestBiPDist = biPDistTemp;
2821          bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
2822          bestBiPRefIdxL1 = iRefIdxTemp;
2823        }
2824#endif
2825
2826#if HHI_INTER_VIEW_MOTION_PRED
2827        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][iNumAMVPCands];
2828#else
2829        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
2830#endif
2831#if ZERO_MVD_EST
2832        if ((iRefList != 1 || !pcCU->getSlice()->getNoBackPredFlag()) &&
2833            (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) <= 0 || pcCU->getSlice()->getRefIdxOfLC(eRefPicList, iRefIdxTemp)>=0))
2834        {
2835          uiZeroMvdBitsTemp = uiBitsTemp;
2836          uiZeroMvdBitsTemp += 2; //zero mvd bits
2837
2838          m_pcRdCost->getMotionCost( 1, 0 );
2839          uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost(uiZeroMvdBitsTemp);
2840
2841          if (uiZeroMvdCostTemp < uiZeroMvdCost)
2842          {
2843            uiZeroMvdCost = uiZeroMvdCostTemp;
2844            iZeroMvdDir = iRefList + 1;
2845            aiZeroMvdRefIdx[iRefList] = iRefIdxTemp;
2846            aiZeroMvdMvpIdx[iRefList] = aaiMvpIdx[iRefList][iRefIdxTemp];
2847            auiZeroMvdBits[iRefList] = uiZeroMvdBitsTemp;
2848          }         
2849        }
2850#endif
2851       
2852#if GPB_SIMPLE_UNI
2853        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0)
2854        {
2855          if ( iRefList && ( pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag() && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)>=0 ) ) )
2856            {
2857              if ( pcCU->getSlice()->getNoBackPredFlag() )
2858              {
2859                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
2860                uiCostTemp = uiCostTempL0[iRefIdxTemp];
2861                /*first subtract the bit-rate part of the cost of the other list*/
2862                uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[iRefIdxTemp] );
2863              }
2864              else
2865              {
2866                cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)]; 
2867                uiCostTemp = uiCostTempL0[pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)];
2868                /*first subtract the bit-rate part of the cost of the other list*/
2869                uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)] );
2870              }
2871              /*correct the bit-rate part of the current ref*/
2872              m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
2873              uiBitsTemp += m_pcRdCost->getBits( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
2874              /*calculate the correct cost*/
2875              uiCostTemp += m_pcRdCost->getCost( uiBitsTemp );
2876            }
2877            else
2878            {
2879              xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
2880            }
2881        }
2882        else
2883        {
2884          if (iRefList && pcCU->getSlice()->getNoBackPredFlag())
2885          {
2886            uiCostTemp = MAX_UINT;
2887            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][iRefIdxTemp];
2888          }
2889          else
2890          { 
2891            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
2892          }       
2893        }
2894#else
2895        xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
2896#endif
2897        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
2898        if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
2899        {         
2900          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
2901        }
2902
2903        if(pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && !pcCU->getSlice()->getNoBackPredFlag())
2904        {
2905          if(iRefList==REF_PIC_LIST_0)
2906          {
2907            uiCostTempL0[iRefIdxTemp] = uiCostTemp;
2908            uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
2909            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_0, iRefIdxTemp)<0)
2910            {
2911              uiCostTemp = MAX_UINT;
2912            }
2913          }
2914          else
2915          {
2916            if(pcCU->getSlice()->getRefIdxOfLC(REF_PIC_LIST_1, iRefIdxTemp)<0)
2917            {
2918              uiCostTemp = MAX_UINT;
2919            }           
2920          }
2921        }
2922
2923        if ( ( iRefList == 0 && uiCostTemp < uiCost[iRefList] ) ||
2924            ( iRefList == 1 &&  pcCU->getSlice()->getNoBackPredFlag() && iRefIdxTemp == iRefIdx[0] ) ||
2925            ( iRefList == 1 && (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0) && (iRefIdxTemp==0 || iRefIdxTemp == iRefIdx[0]) && !pcCU->getSlice()->getNoBackPredFlag() && (iRefIdxTemp == pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(iRefIdxTemp)) ) ||
2926            ( iRefList == 1 && !pcCU->getSlice()->getNoBackPredFlag() && uiCostTemp < uiCost[iRefList] ) )
2927          {
2928            uiCost[iRefList] = uiCostTemp;
2929            uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
2930           
2931            // set motion
2932            cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
2933            iRefIdx[iRefList] = iRefIdxTemp;
2934            pcCU->getCUMvField(eRefPicList)->setAllMv( cMv[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
2935            pcCU->getCUMvField(eRefPicList)->setAllRefIdx( iRefIdx[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
2936
2937#if H0111_MVD_L1_ZERO
2938            if(!pcCU->getSlice()->getMvdL1ZeroFlag())
2939            {
2940#endif
2941              // storing list 1 prediction signal for iterative bi-directional prediction
2942              if ( eRefPicList == REF_PIC_LIST_1 )
2943              {
2944                TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
2945                motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
2946              }
2947              if ( (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) && eRefPicList == REF_PIC_LIST_0 )
2948              {
2949                TComYuv*  pcYuvPred = &m_acYuvPred[iRefList];
2950                motionCompensation ( pcCU, pcYuvPred, eRefPicList, iPartIdx );
2951              }
2952#if H0111_MVD_L1_ZERO
2953            }
2954#endif
2955          }
2956      }
2957    }
2958#if LG_RESTRICTEDRESPRED_M24766
2959        if( pcCU->getResPredFlag( 0 ) && bLastResiFlag)
2960        { // subtract residual prediction from original in motion search
2961                pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ));
2962        }
2963#endif
2964    //  Bi-directional prediction
2965    if ( pcCU->getSlice()->isInterB() )
2966    {
2967#if LG_RESTRICTEDRESPRED_M24766
2968                Int iLastAddResiShift = -1000;
2969#endif
2970      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
2971      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
2972     
2973      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
2974      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
2975     
2976#if H0111_MVD_L1_ZERO
2977      UInt uiMotBits[2];
2978
2979      if(pcCU->getSlice()->getMvdL1ZeroFlag())
2980      {
2981        xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
2982        pcCU->setMVPIdxSubParts( bestBiPMvpL1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
2983        aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1;
2984        cMvPredBi[1][bestBiPRefIdxL1]   = pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()->m_acMvCand[bestBiPMvpL1];
2985
2986        cMvBi[1] = cMvPredBi[1][bestBiPRefIdxL1];
2987        iRefIdxBi[1] = bestBiPRefIdxL1;
2988        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
2989        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
2990        TComYuv* pcYuvPred = &m_acYuvPred[1];
2991        motionCompensation( pcCU, pcYuvPred, REF_PIC_LIST_1, iPartIdx );
2992
2993        uiMotBits[0] = uiBits[0] - uiMbBits[0];
2994        uiMotBits[1] = uiMbBits[1];
2995
2996        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
2997        {
2998          uiMotBits[1] += bestBiPRefIdxL1+1;
2999          if ( bestBiPRefIdxL1 == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiMotBits[1]--;
3000        }
3001
3002#if HHI_INTER_VIEW_MOTION_PRED
3003        uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][iNumAMVPCands];
3004#else
3005        uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS];
3006#endif
3007
3008        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3009
3010        cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1];
3011      }
3012      else
3013      {
3014        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3015        uiMotBits[1] = uiBits[1] - uiMbBits[1];
3016        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3017      }
3018#else   
3019      UInt uiMotBits[2] = { uiBits[0] - uiMbBits[0], uiBits[1] - uiMbBits[1] };
3020      uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3021#endif     
3022
3023      // 4-times iteration (default)
3024      Int iNumIter = 4;
3025     
3026      // fast encoder setting: only one iteration
3027#if H0111_MVD_L1_ZERO
3028      if ( m_pcEncCfg->getUseFastEnc() || pcCU->getSlice()->getMvdL1ZeroFlag())
3029#else
3030      if ( m_pcEncCfg->getUseFastEnc() )
3031#endif
3032      {
3033        iNumIter = 1;
3034      }
3035     
3036      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3037      {
3038       
3039        Int         iRefList    = iIter % 2;
3040        if ( m_pcEncCfg->getUseFastEnc() && (pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 )) )
3041        {
3042          iRefList = 1;
3043        }
3044        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3045
3046#if H0111_MVD_L1_ZERO
3047        if(pcCU->getSlice()->getMvdL1ZeroFlag())
3048        {
3049          iRefList = 0;
3050          eRefPicList = REF_PIC_LIST_0;
3051        }
3052#endif
3053
3054        Bool bChanged = false;
3055       
3056        iRefStart = 0;
3057        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3058       
3059        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3060        {
3061          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3062          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3063          {
3064            uiBitsTemp += iRefIdxTemp+1;
3065            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 ) uiBitsTemp--;
3066          }
3067#if HHI_INTER_VIEW_MOTION_PRED
3068          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][iNumAMVPCands];
3069#else
3070          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3071#endif
3072#if LG_RESTRICTEDRESPRED_M24766
3073                  Int iAddResiShift = -1, iPredFrom = 0;
3074                  Int iBestRefIdx = pcCU->getCUMvField(eRefPicList == REF_PIC_LIST_0 ? REF_PIC_LIST_1 : REF_PIC_LIST_0)->getRefIdx(uiPartAddr);
3075
3076                  iPredFrom = iBestRefIdx >= 0 ? 3 : 1;
3077                  if(iBestRefIdx >= 0 && pcCU->getSlice()->getViewId() == pcCU->getSlice()->getRefViewId(eRefPicList == REF_PIC_LIST_0 ? REF_PIC_LIST_1 : REF_PIC_LIST_0, iBestRefIdx))
3078                          iAddResiShift++;
3079                  if(pcCU->getSlice()->getViewId() == pcCU->getSlice()->getRefViewId(eRefPicList, iRefIdxTemp))
3080                          iAddResiShift++;
3081                  iAddResiShift = (pcCU->getSlice()->getPPS()->getUseWP() || iPredFrom != 3) ? (iAddResiShift >= 0 ? 0 : -1) : (iAddResiShift >= 0 ? 1-iAddResiShift : -1);
3082
3083                  if( pcCU->getResPredFlag( 0 ) )
3084                  {
3085                          if(iLastAddResiShift != iAddResiShift)
3086                          {
3087                                  //add substracted residual last time
3088                                  if(iLastAddResiShift >= 0 )
3089                                  {
3090                                          iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = iLastAddResiShift;
3091                                          pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ));
3092                                  }
3093                                  //substract residual
3094                                  if(iAddResiShift >= 0)
3095                                  {
3096                                          iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = iAddResiShift;
3097                                          pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ), true );
3098                                  }
3099                                  iLastAddResiShift = iAddResiShift;
3100                          }
3101                  }
3102#endif
3103          // call ME
3104          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3105          if ( pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3106          {
3107            xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3108            xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3109          }
3110         
3111          if ( uiCostTemp < uiCostBi )
3112          {
3113            bChanged = true;
3114           
3115            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3116            iRefIdxBi[iRefList] = iRefIdxTemp;
3117           
3118            uiCostBi            = uiCostTemp;
3119            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3120            uiBits[2]           = uiBitsTemp;
3121           
3122#if H0111_MVD_L1_ZERO
3123            if(iNumIter!=1)
3124            {
3125#endif
3126              //  Set motion
3127              pcCU->getCUMvField( eRefPicList )->setAllMv( cMvBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3128              pcCU->getCUMvField( eRefPicList )->setAllRefIdx( iRefIdxBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3129
3130              TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3131              motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3132#if H0111_MVD_L1_ZERO
3133            }
3134#endif
3135          }
3136        } // for loop-iRefIdxTemp
3137       
3138        if ( !bChanged )
3139        {
3140          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL )
3141          {
3142            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3143            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3144#if H0111_MVD_L1_ZERO
3145            if(!pcCU->getSlice()->getMvdL1ZeroFlag())
3146            {
3147#endif
3148              xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3149              xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3150#if H0111_MVD_L1_ZERO
3151            }
3152#endif
3153          }
3154          break;
3155        }
3156      } // for loop-iter
3157#if LG_RESTRICTEDRESPRED_M24766
3158          if( pcCU->getResPredFlag( 0 ) && iLastAddResiShift >= 0)
3159          {
3160                  iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = iLastAddResiShift;
3161                  pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ));
3162          }
3163#endif
3164    } // if (B_SLICE)
3165#if ZERO_MVD_EST
3166    if ( pcCU->getSlice()->isInterB() )
3167    {
3168      m_pcRdCost->getMotionCost( 1, 0 );
3169
3170      for ( Int iL0RefIdxTemp = 0; iL0RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1; iL0RefIdxTemp++ )
3171      for ( Int iL1RefIdxTemp = 0; iL1RefIdxTemp <= pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1; iL1RefIdxTemp++ )
3172      {
3173        UInt uiRefIdxBitsTemp = 0;
3174        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 1 )
3175        {
3176          uiRefIdxBitsTemp += iL0RefIdxTemp+1;
3177          if ( iL0RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0)-1 ) uiRefIdxBitsTemp--;
3178        }
3179        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3180        {
3181          uiRefIdxBitsTemp += iL1RefIdxTemp+1;
3182          if ( iL1RefIdxTemp == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 ) uiRefIdxBitsTemp--;
3183        }
3184
3185        Int iL0MVPIdx = 0;
3186        Int iL1MVPIdx = 0;
3187
3188        for (iL0MVPIdx = 0; iL0MVPIdx < aaiMvpNum[0][iL0RefIdxTemp]; iL0MVPIdx++)
3189        {
3190          for (iL1MVPIdx = 0; iL1MVPIdx < aaiMvpNum[1][iL1RefIdxTemp]; iL1MVPIdx++)
3191          {
3192            uiZeroMvdBitsTemp = uiRefIdxBitsTemp;
3193            uiZeroMvdBitsTemp += uiMbBits[2];
3194            uiZeroMvdBitsTemp += m_auiMVPIdxCost[iL0MVPIdx][aaiMvpNum[0][iL0RefIdxTemp]] + m_auiMVPIdxCost[iL1MVPIdx][aaiMvpNum[1][iL1RefIdxTemp]];
3195            uiZeroMvdBitsTemp += 4; //zero mvd for both directions
3196            pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( aacAMVPInfo[0][iL0RefIdxTemp].m_acMvCand[iL0MVPIdx], iL0RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3197            pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( aacAMVPInfo[1][iL1RefIdxTemp].m_acMvCand[iL1MVPIdx], iL1RefIdxTemp, ePartSize, uiPartAddr, iPartIdx, 0 );
3198 
3199            xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiZeroMvdDistTemp, m_pcEncCfg->getUseHADME() );
3200            uiZeroMvdCostTemp = uiZeroMvdDistTemp + m_pcRdCost->getCost( uiZeroMvdBitsTemp );
3201            if (uiZeroMvdCostTemp < uiZeroMvdCost)
3202            {
3203              uiZeroMvdCost = uiZeroMvdCostTemp;
3204              iZeroMvdDir = 3;
3205              aiZeroMvdMvpIdx[0] = iL0MVPIdx;
3206              aiZeroMvdMvpIdx[1] = iL1MVPIdx;
3207              aiZeroMvdRefIdx[0] = iL0RefIdxTemp;
3208              aiZeroMvdRefIdx[1] = iL1RefIdxTemp;
3209              auiZeroMvdBits[2] = uiZeroMvdBitsTemp;
3210            }
3211          }
3212        }
3213      }
3214    }
3215#endif
3216
3217#if AMP_MRG
3218    } //end if bTestNormalMC
3219#endif
3220    //  Clear Motion Field
3221    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3222    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3223    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3224    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3225
3226    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3227    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3228    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3229    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3230   
3231    UInt uiMEBits = 0;
3232    // Set Motion Field_
3233    if ( pcCU->getSlice()->getNoBackPredFlag() || (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getSlice()->getRefIdxOfL0FromRefIdxOfL1(0)==0 ) )
3234    {
3235      uiCost[1] = MAX_UINT;
3236    }
3237#if AMP_MRG
3238    if (bTestNormalMC)
3239    {
3240#endif
3241#if ZERO_MVD_EST
3242    if (uiZeroMvdCost <= uiCostBi && uiZeroMvdCost <= uiCost[0] && uiZeroMvdCost <= uiCost[1])
3243    {
3244      if (iZeroMvdDir == 3)
3245      {
3246        uiLastMode = 2;
3247
3248        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3249        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3250 
3251        pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3252       
3253        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3254        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3255        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3256        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3257        uiMEBits = auiZeroMvdBits[2];
3258      }
3259      else if (iZeroMvdDir == 1)
3260      {       
3261        uiLastMode = 0;
3262
3263        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( aacAMVPInfo[0][aiZeroMvdRefIdx[0]].m_acMvCand[aiZeroMvdMvpIdx[0]], aiZeroMvdRefIdx[0], ePartSize, uiPartAddr, iPartIdx, 0 );
3264
3265        pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3266       
3267        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[0], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3268        pcCU->setMVPNumSubParts( aaiMvpNum[0][aiZeroMvdRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3269        uiMEBits = auiZeroMvdBits[0];
3270      }
3271      else if (iZeroMvdDir == 2)
3272      {
3273        uiLastMode = 1;
3274
3275        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( aacAMVPInfo[1][aiZeroMvdRefIdx[1]].m_acMvCand[aiZeroMvdMvpIdx[1]], aiZeroMvdRefIdx[1], ePartSize, uiPartAddr, iPartIdx, 0 );
3276
3277        pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3278       
3279        pcCU->setMVPIdxSubParts( aiZeroMvdMvpIdx[1], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3280        pcCU->setMVPNumSubParts( aaiMvpNum[1][aiZeroMvdRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3281        uiMEBits = auiZeroMvdBits[1];
3282      }
3283      else
3284      {
3285        assert(0);
3286      }
3287    }
3288    else
3289#endif
3290    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3291    {
3292      uiLastMode = 2;
3293      {
3294            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMvBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3295            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdxBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3296            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3297            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3298      }
3299      {
3300        TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3301            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3302      }
3303      {
3304        TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3305            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3306      }
3307     
3308      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3309     
3310      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3311      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3312      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3313      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3314
3315      uiMEBits = uiBits[2];
3316    }
3317    else if ( uiCost[0] <= uiCost[1] )
3318    {
3319      uiLastMode = 0;
3320          pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
3321          pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
3322      {
3323        TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3324            pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3325      }
3326      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3327     
3328      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3329      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3330
3331      uiMEBits = uiBits[0];
3332    }
3333    else
3334    {
3335      uiLastMode = 1;
3336          pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
3337          pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
3338      {
3339        TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3340            pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3341      }
3342      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3343     
3344      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3345      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3346
3347      uiMEBits = uiBits[1];
3348    }
3349#if AMP_MRG
3350    } // end if bTestNormalMC
3351#endif
3352
3353    if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3354    {
3355      UInt uiMRGInterDir = 0;     
3356      TComMvField cMRGMvField[2];
3357      UInt uiMRGIndex = 0;
3358
3359      UInt uiMEInterDir = 0;
3360      TComMvField cMEMvField[2];
3361
3362      m_pcRdCost->getMotionCost( 1, 0 );
3363#if AMP_MRG
3364      // calculate ME cost
3365      UInt uiMEError = MAX_UINT;
3366      UInt uiMECost = MAX_UINT;
3367
3368      if (bTestNormalMC)
3369      {
3370#if LG_RESTRICTEDRESPRED_M24766
3371                  Int iAddResiShift = pcCU->getResiPredMode(uiPartAddr);
3372                  iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = \
3373                          (pcCU->getSlice()->getPPS()->getUseWP() || pcCU->getInterDir(uiPartAddr) != 3)? (iAddResiShift >= 0 ? 0 : -1) : (iAddResiShift >= 0 ? 1-iAddResiShift : -1);
3374                  if(pcCU->getResPredFlag(0) && iAddResiShift >= 0)
3375                  {
3376                          pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ), true);
3377                  }
3378#endif
3379        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3380        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3381#if LG_RESTRICTEDRESPRED_M24766
3382                if(pcCU->getResPredFlag(0) && iAddResiShift >= 0)
3383                {
3384                        pcOrgYuv->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcResiPredYuv, pcCU->getWidth( 0 ), pcCU->getHeight( 0 ));
3385                }
3386#endif
3387      }
3388#else
3389      // calculate ME cost
3390      UInt uiMEError = MAX_UINT;
3391      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3392      UInt uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3393#endif
3394      // save ME result.
3395      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3396      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3397      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3398
3399      // find Merge result
3400      UInt uiMRGCost = MAX_UINT;
3401#if CU_BASED_MRG_CAND_LIST
3402      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand);
3403#else
3404#if LG_RESTRICTEDRESPRED_M24766
3405      xMergeEstimation( pcCU, pcOrgYuv, rpcResiPredYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost );
3406#else
3407      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost );
3408#endif
3409#endif
3410      if ( uiMRGCost < uiMECost )
3411      {
3412        // set Merge result
3413        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3414        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3415        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3416        {
3417          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3418          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3419        }
3420
3421        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3422        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3423
3424        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3425        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3426        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3427        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3428      }
3429      else
3430      {
3431        // set ME result
3432        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3433        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3434        {
3435          pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3436          pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3437        }
3438      }
3439    }
3440
3441    //  MC
3442    motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
3443   
3444  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3445
3446  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
3447
3448  return;
3449}
3450
3451// AMVP
3452#if H0111_MVD_L1_ZERO
3453#if ZERO_MVD_EST
3454Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDistBiP, UInt* puiDist  )
3455#else
3456Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDistBiP )
3457#endif
3458#else
3459#if ZERO_MVD_EST
3460Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, UInt* puiDist )
3461#else
3462Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled )
3463#endif
3464#endif
3465{
3466  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3467 
3468  TComMv  cBestMv;
3469  Int     iBestIdx = 0;
3470  TComMv  cZeroMv;
3471  TComMv  cMvPred;
3472  UInt    uiBestCost = MAX_INT;
3473  UInt    uiPartAddr = 0;
3474  Int     iRoiWidth, iRoiHeight;
3475  Int     i;
3476 
3477  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3478  // Fill the MV Candidates
3479  if (!bFilled)
3480  {
3481    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
3482  }
3483 
3484  // initialize Mvp index & Mvp
3485  iBestIdx = 0;
3486  cBestMv  = pcAMVPInfo->m_acMvCand[0];
3487#if !ZERO_MVD_EST
3488  if( pcCU->getAMVPMode(uiPartAddr) == AM_NONE || (pcAMVPInfo->iN <= 1 && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL) )
3489  {
3490    rcMvPred = cBestMv;
3491   
3492    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3493    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3494
3495#if H0111_MVD_L1_ZERO
3496    if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefPicList==REF_PIC_LIST_1)
3497    {
3498#if HHI_INTER_VIEW_MOTION_PRED
3499      Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
3500#if ZERO_MVD_EST
3501      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, iNumAMVPCands, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3502#else
3503      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, iNumAMVPCands, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3504#endif
3505#else
3506#if ZERO_MVD_EST
3507      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3508#else
3509      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3510#endif
3511#endif
3512    }
3513#endif
3514    return;
3515  }
3516#endif 
3517  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL && bFilled)
3518  {
3519    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
3520    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
3521    return;
3522  }
3523 
3524  if (pcCU->getAMVPMode(uiPartAddr) == AM_EXPL)
3525  {
3526    m_cYuvPredTemp.clear();
3527#if ZERO_MVD_EST
3528    UInt uiDist;
3529#endif
3530    //-- Check Minimum Cost.
3531    for ( i = 0 ; i < pcAMVPInfo->iN; i++)
3532    {
3533      UInt uiTmpCost;
3534#if HHI_INTER_VIEW_MOTION_PRED
3535      Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
3536#if ZERO_MVD_EST
3537      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, iNumAMVPCands, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3538#else
3539      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, iNumAMVPCands, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3540#endif
3541#else
3542#if ZERO_MVD_EST
3543      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight, uiDist );
3544#else
3545      uiTmpCost = xGetTemplateCost( pcCU, uiPartIdx, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3546#endif     
3547#endif
3548      if ( uiBestCost > uiTmpCost )
3549      {
3550        uiBestCost = uiTmpCost;
3551        cBestMv   = pcAMVPInfo->m_acMvCand[i];
3552        iBestIdx  = i;
3553        #if H0111_MVD_L1_ZERO
3554        (*puiDistBiP) = uiTmpCost;
3555        #endif
3556        #if ZERO_MVD_EST
3557        (*puiDist) = uiDist;
3558        #endif
3559      }
3560    }
3561   
3562    m_cYuvPredTemp.clear();
3563  }
3564 
3565  // Setting Best MVP
3566  rcMvPred = cBestMv;
3567  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3568  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3569  return;
3570}
3571
3572UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
3573{
3574  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
3575 
3576  if (iNum == 1)
3577    return 0;
3578 
3579  UInt uiLength = 1;
3580  Int iTemp = iIdx;
3581  if ( iTemp == 0 )
3582  {
3583    return uiLength;
3584  }
3585 
3586  Bool bCodeLast = ( iNum-1 > iTemp );
3587 
3588  uiLength += (iTemp-1);
3589 
3590  if( bCodeLast )
3591  {
3592    uiLength++;
3593  }
3594 
3595  return uiLength;
3596}
3597
3598Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
3599{
3600  if ( eCUMode == SIZE_2Nx2N )
3601  {
3602    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3603    uiBlkBit[1] = 3;
3604    uiBlkBit[2] = 5;
3605  }
3606  else if ( (eCUMode == SIZE_2NxN || eCUMode == SIZE_2NxnU) || eCUMode == SIZE_2NxnD )
3607  {
3608    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} } };
3609    if ( bPSlice )
3610    {
3611      uiBlkBit[0] = 3;
3612      uiBlkBit[1] = 0;
3613      uiBlkBit[2] = 0;
3614    }
3615    else
3616    {
3617      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3618    }
3619  }
3620  else if ( (eCUMode == SIZE_Nx2N || eCUMode == SIZE_nLx2N) || eCUMode == SIZE_nRx2N )
3621  {
3622    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} } };
3623    if ( bPSlice )
3624    {
3625      uiBlkBit[0] = 3;
3626      uiBlkBit[1] = 0;
3627      uiBlkBit[2] = 0;
3628    }
3629    else
3630    {
3631      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3632    }
3633  }
3634  else if ( eCUMode == SIZE_NxN )
3635  {
3636    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3637    uiBlkBit[1] = 3;
3638    uiBlkBit[2] = 5;
3639  }
3640  else
3641  {
3642    printf("Wrong!\n");
3643    assert( 0 );
3644  }
3645}
3646
3647Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
3648{
3649  pDst->iN = pSrc->iN;
3650  for (Int i = 0; i < pSrc->iN; i++)
3651  {
3652    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
3653  }
3654}
3655
3656Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, UInt& ruiCost )
3657{
3658  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3659 
3660  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
3661 
3662  if (pcAMVPInfo->iN < 2) return;
3663 
3664  m_pcRdCost->getMotionCost( 1, 0 );
3665  m_pcRdCost->setCostScale ( 0    );
3666 
3667  Int iBestMVPIdx = riMVPIdx;
3668 
3669#if HHI_INTER_VIEW_MOTION_PRED
3670  Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
3671#endif
3672 
3673  m_pcRdCost->setPredictor( rcMvPred );
3674  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3675#if HHI_INTER_VIEW_MOTION_PRED
3676  iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][iNumAMVPCands];
3677#else
3678  iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
3679#endif
3680  Int iBestMvBits = iOrgMvBits;
3681 
3682  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
3683  {
3684    if (iMVPIdx == riMVPIdx) continue;
3685   
3686    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
3687   
3688    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
3689#if HHI_INTER_VIEW_MOTION_PRED
3690    iMvBits += m_auiMVPIdxCost[iMVPIdx][iNumAMVPCands];
3691#else
3692    iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
3693#endif
3694   
3695    if (iMvBits < iBestMvBits)
3696    {
3697      iBestMvBits = iMvBits;
3698      iBestMVPIdx = iMVPIdx;
3699    }
3700  }
3701 
3702  if (iBestMVPIdx != riMVPIdx)  //if changed
3703  {
3704    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
3705   
3706    riMVPIdx = iBestMVPIdx;
3707    UInt uiOrgBits = ruiBits;
3708    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
3709    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
3710  }
3711}
3712
3713UInt TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
3714                                  UInt        uiPartIdx,
3715                                  UInt      uiPartAddr,
3716                                  TComYuv*    pcOrgYuv,
3717                                  TComYuv*    pcTemplateCand,
3718                                  TComMv      cMvCand,
3719                                  Int         iMVPIdx,
3720                                  Int     iMVPNum,
3721                                  RefPicList  eRefPicList,
3722                                  Int         iRefIdx,
3723                                  Int         iSizeX,
3724                                  Int         iSizeY
3725                               #if ZERO_MVD_EST
3726                                , UInt&       ruiDist
3727                               #endif
3728                                  )
3729{
3730  UInt uiCost  = MAX_INT;
3731 
3732  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
3733 
3734  pcCU->clipMv( cMvCand );
3735
3736#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3737  if( pcCU->getSlice()->getIsDepth() )
3738    cMvCand <<= 2;
3739#endif
3740  // prediction pattern
3741  if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType()==P_SLICE )
3742  {
3743    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, true );
3744  }
3745  else
3746  {
3747    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false );
3748  }
3749
3750  if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType()==P_SLICE )
3751  {
3752    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, uiPartIdx, iRefIdx );
3753  }
3754
3755  // calc distortion
3756#if ZERO_MVD_EST
3757  m_pcRdCost->getMotionCost( 1, 0 );
3758  DistParam cDistParam;
3759  m_pcRdCost->setDistParam( cDistParam, 
3760                            pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), 
3761                            pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), 
3762#if NS_HAD
3763                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME(), m_pcEncCfg->getUseNSQT() );
3764#else
3765                            iSizeX, iSizeY, m_pcEncCfg->getUseHADME() );
3766#endif
3767  ruiDist = cDistParam.DistFunc( &cDistParam );
3768  uiCost = ruiDist + m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] );
3769#else
3770// GT: CONSIDER ADDING VSO HERE
3771#if WEIGHTED_CHROMA_DISTORTION
3772  uiCost = m_pcRdCost->getDistPart( pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, false, DF_SAD );
3773#else
3774  uiCost = m_pcRdCost->getDistPart( pcTemplateCand->getLumaAddr(uiPartAddr), pcTemplateCand->getStride(), pcOrgYuv->getLumaAddr(uiPartAddr), pcOrgYuv->getStride(), iSizeX, iSizeY, DF_SAD );
3775#endif
3776  uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
3777#endif
3778  return uiCost;
3779}
3780
3781Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, UInt& ruiCost, Bool bBi  )
3782{
3783  UInt          uiPartAddr;
3784  Int           iRoiWidth;
3785  Int           iRoiHeight;
3786 
3787  TComMv        cMvHalf, cMvQter;
3788  TComMv        cMvSrchRngLT;
3789  TComMv        cMvSrchRngRB;
3790 
3791  TComYuv*      pcYuv = pcYuvOrg;
3792  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
3793 
3794  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
3795  TComPattern*  pcPatternKey  = pcCU->getPattern        ();
3796 
3797  Double        fWeight       = 1.0;
3798 
3799  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3800 
3801  if ( bBi )
3802  {
3803    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
3804    pcYuv                = &m_cYuvPredTemp;
3805   
3806    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
3807   
3808    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight );
3809   
3810    fWeight = 0.5;
3811  }
3812 
3813  //  Search key pattern initialization
3814  pcPatternKey->initPattern( pcYuv->getLumaAddr( uiPartAddr ),
3815                            pcYuv->getCbAddr  ( uiPartAddr ),
3816                            pcYuv->getCrAddr  ( uiPartAddr ),
3817                            iRoiWidth,
3818                            iRoiHeight,
3819                            pcYuv->getStride(),
3820                            0, 0, 0, 0 );
3821 
3822  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr );
3823  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride();
3824 
3825  TComMv      cMvPred = *pcMvPred;
3826 
3827  if ( bBi )  xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3828  else        xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3829 
3830  m_pcRdCost->getMotionCost ( 1, 0 );
3831 
3832  m_pcRdCost->setPredictor  ( *pcMvPred );
3833#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3834  if( pcCU->getSlice()->getIsDepth() )
3835    m_pcRdCost->setCostScale  ( 0 );
3836  else
3837#endif
3838  m_pcRdCost->setCostScale  ( 2 );
3839
3840#if HHI_INTER_VIEW_MOTION_PRED
3841  { // init inter-view regularization
3842    TComMv  cOrgDepthMapMv;
3843    Bool    bMultiviewReg = pcCU->getIViewOrgDepthMvPred( iPartIdx, eRefPicList, iRefIdxPred, cOrgDepthMapMv );
3844#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3845    if( bMultiviewReg && pcCU->getSlice()->getSPS()->isDepth() )
3846    {
3847      cOrgDepthMapMv += TComMv( 2, 2 );
3848      cOrgDepthMapMv >>= 2;
3849    }
3850#endif
3851    m_pcRdCost->setMultiviewReg( bMultiviewReg ? &cOrgDepthMapMv : 0 );
3852    if( bMultiviewReg && !bBi )
3853    {
3854      xSetSearchRange( pcCU, cOrgDepthMapMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3855    }
3856  }
3857#endif
3858
3859  setWpScalingDistParam( pcCU, iRefIdxPred, eRefPicList );
3860  //  Do integer search
3861  if ( !m_iFastSearch || bBi )
3862  {
3863    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
3864  }
3865  else
3866  {
3867    rcMv = *pcMvPred;
3868    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
3869  }
3870 
3871  m_pcRdCost->getMotionCost( 1, 0 );
3872#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3873  if( ! pcCU->getSlice()->getIsDepth() )
3874  {
3875#endif
3876  m_pcRdCost->setCostScale ( 1 );
3877 
3878  {
3879    xPatternSearchFracDIF( pcCU, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost
3880                          ,bBi
3881                          );
3882  }
3883 
3884 
3885 
3886  m_pcRdCost->setCostScale( 0 );
3887  rcMv <<= 2;
3888  rcMv += (cMvHalf <<= 1);
3889  rcMv +=  cMvQter;
3890#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3891  }
3892#endif
3893 
3894  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
3895#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3896  if( pcCU->getSlice()->getIsDepth() )
3897    ruiCost += m_pcRdCost->getCost( uiMvBits );
3898#endif
3899 
3900  ruiBits      += uiMvBits;
3901  ruiCost       = (UInt)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
3902}
3903
3904
3905Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
3906{
3907  Int  iMvShift = 2;
3908#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
3909  if( pcCU->getSlice()->getIsDepth() )
3910    iMvShift = 0;
3911#endif
3912  TComMv cTmpMvPred = cMvPred;
3913  pcCU->clipMv( cTmpMvPred );
3914
3915  rcMvSrchRngLT.setHor( cTmpMvPred.getHor() - (iSrchRng << iMvShift) );
3916  rcMvSrchRngLT.setVer( cTmpMvPred.getVer() - (iSrchRng << iMvShift) );
3917 
3918  rcMvSrchRngRB.setHor( cTmpMvPred.getHor() + (iSrchRng << iMvShift) );
3919  rcMvSrchRngRB.setVer( cTmpMvPred.getVer() + (iSrchRng << iMvShift) );
3920  pcCU->clipMv        ( rcMvSrchRngLT );
3921  pcCU->clipMv        ( rcMvSrchRngRB );
3922 
3923  rcMvSrchRngLT >>= iMvShift;
3924  rcMvSrchRngRB >>= iMvShift;
3925}
3926
3927Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
3928{
3929  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
3930  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
3931  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
3932  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
3933 
3934  UInt  uiSad;
3935  UInt  uiSadBest         = MAX_UINT;
3936  Int   iBestX = 0;
3937  Int   iBestY = 0;
3938 
3939  Pel*  piRefSrch;
3940 
3941  //-- jclee for using the SAD function pointer
3942  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
3943 
3944  // fast encoder decision: use subsampled SAD for integer ME
3945  if ( m_pcEncCfg->getUseFastEnc() )
3946  {
3947    if ( m_cDistParam.iRows > 8 )
3948    {
3949      m_cDistParam.iSubShift = 1;
3950    }
3951  }
3952 
3953  piRefY += (iSrchRngVerTop * iRefStride);
3954  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
3955  {
3956    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
3957    {
3958      //  find min. distortion position
3959      piRefSrch = piRefY + x;
3960      m_cDistParam.pCur = piRefSrch;
3961
3962      setDistParamComp(0);
3963
3964      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
3965     
3966      // motion cost
3967      uiSad += m_pcRdCost->getCost( x, y );
3968     
3969      if ( uiSad < uiSadBest )
3970      {
3971        uiSadBest = uiSad;
3972        iBestX    = x;
3973        iBestY    = y;
3974      }
3975    }
3976    piRefY += iRefStride;
3977  }
3978 
3979  rcMv.set( iBestX, iBestY );
3980 
3981  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
3982  return;
3983}
3984
3985Void TEncSearch::xPatternSearchFast( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
3986{
3987  pcCU->getMvPredLeft       ( m_acMvPredictors[0] );
3988  pcCU->getMvPredAbove      ( m_acMvPredictors[1] );
3989  pcCU->getMvPredAboveRight ( m_acMvPredictors[2] );
3990 
3991  switch ( m_iFastSearch )
3992  {
3993    case 1:
3994      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD );
3995      break;
3996     
3997    default:
3998      break;
3999  }
4000}
4001
4002Void TEncSearch::xTZSearch( TComDataCU* pcCU, TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, UInt& ruiSAD )
4003{
4004  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4005  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4006  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4007  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4008 
4009  TZ_SEARCH_CONFIGURATION
4010 
4011  UInt uiSearchRange = m_iSearchRange;
4012  pcCU->clipMv( rcMv );
4013#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4014  if( ! pcCU->getSlice()->getIsDepth() )
4015#endif
4016  rcMv >>= 2;
4017  // init TZSearchStruct
4018  IntTZSearchStruct cStruct;
4019  cStruct.iYStride    = iRefStride;
4020  cStruct.piRefY      = piRefY;
4021  cStruct.uiBestSad   = MAX_UINT;
4022 
4023  // set rcMv (Median predictor) as start point and as best point
4024  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4025 
4026  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4027  if ( bTestOtherPredictedMV )
4028  {
4029    for ( UInt index = 0; index < 3; index++ )
4030    {
4031      TComMv cMv = m_acMvPredictors[index];
4032      pcCU->clipMv( cMv );
4033#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
4034      if( ! pcCU->getSlice()->getIsDepth() )
4035#endif
4036      cMv >>= 2;
4037      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4038    }
4039  }
4040 
4041  // test whether zero Mv is better start point than Median predictor
4042  if ( bTestZeroVector )
4043  {
4044    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4045  }
4046 
4047  // start search
4048  Int  iDist = 0;
4049  Int  iStartX = cStruct.iBestX;
4050  Int  iStartY = cStruct.iBestY;
4051 
4052  // first search
4053  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4054  {
4055    if ( bFirstSearchDiamond == 1 )
4056    {
4057      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4058    }
4059    else
4060    {
4061      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4062    }
4063   
4064    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4065    {
4066      break;
4067    }
4068  }
4069 
4070  // test whether zero Mv is a better start point than Median predictor
4071  if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4072  {
4073    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4074    if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4075    {
4076      // test its neighborhood
4077      for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4078      {
4079        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
4080        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4081        {
4082          break;
4083        }
4084      }
4085    }
4086  }
4087 
4088  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4089  if ( cStruct.uiBestDistance == 1 )
4090  {
4091    cStruct.uiBestDistance = 0;
4092    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4093  }
4094 
4095  // raster search if distance is too big
4096  if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4097  {
4098    cStruct.uiBestDistance = iRaster;
4099    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4100    {
4101      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4102      {
4103        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4104      }
4105    }
4106  }
4107 
4108  // raster refinement
4109  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4110  {
4111    while ( cStruct.uiBestDistance > 0 )
4112    {
4113      iStartX = cStruct.iBestX;
4114      iStartY = cStruct.iBestY;
4115      if ( cStruct.uiBestDistance > 1 )
4116      {
4117        iDist = cStruct.uiBestDistance >>= 1;
4118        if ( bRasterRefinementDiamond == 1 )
4119        {
4120          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4121        }
4122        else
4123        {
4124          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4125        }
4126      }
4127     
4128      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4129      if ( cStruct.uiBestDistance == 1 )
4130      {
4131        cStruct.uiBestDistance = 0;
4132        if ( cStruct.ucPointNr != 0 )
4133        {
4134          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4135        }
4136      }
4137    }
4138  }
4139 
4140  // start refinement
4141  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4142  {
4143    while ( cStruct.uiBestDistance > 0 )
4144    {
4145      iStartX = cStruct.iBestX;
4146      iStartY = cStruct.iBestY;
4147      cStruct.uiBestDistance = 0;
4148      cStruct.ucPointNr = 0;
4149      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4150      {
4151        if ( bStarRefinementDiamond == 1 )
4152        {
4153          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4154        }
4155        else
4156        {
4157          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4158        }
4159        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4160        {
4161          break;
4162        }
4163      }
4164     
4165      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4166      if ( cStruct.uiBestDistance == 1 )
4167      {
4168        cStruct.uiBestDistance = 0;
4169        if ( cStruct.ucPointNr != 0 )
4170        {
4171          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4172        }
4173      }
4174    }
4175  }
4176 
4177  // write out best match
4178  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4179  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
4180}
4181
4182Void TEncSearch::xPatternSearchFracDIF(TComDataCU* pcCU,
4183                                       TComPattern* pcPatternKey,
4184                                       Pel* piRefY,
4185                                       Int iRefStride,
4186                                       TComMv* pcMvInt,
4187                                       TComMv& rcMvHalf,
4188                                       TComMv& rcMvQter,
4189                                       UInt& ruiCost
4190                                       ,Bool biPred
4191                                       )
4192{
4193  //  Reference pattern initialization (integer scale)
4194  TComPattern cPatternRoi;
4195  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4196  cPatternRoi.initPattern( piRefY +  iOffset,
4197                          NULL,
4198                          NULL,
4199                          pcPatternKey->getROIYWidth(),
4200                          pcPatternKey->getROIYHeight(),
4201                          iRefStride,
4202                          0, 0, 0, 0 );
4203 
4204  //  Half-pel refinement
4205  xExtDIFUpSamplingH ( &cPatternRoi, biPred );
4206 
4207  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4208  TComMv baseRefMv(0, 0);
4209  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 2, rcMvHalf   );
4210 
4211  m_pcRdCost->setCostScale( 0 );
4212 
4213  xExtDIFUpSamplingQ ( &cPatternRoi, rcMvHalf, biPred );
4214  baseRefMv = rcMvHalf;
4215  baseRefMv <<= 1;
4216 
4217  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4218  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4219  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 1, rcMvQter );
4220}
4221
4222/** encode residual and calculate rate-distortion for a CU block
4223 * \param pcCU
4224 * \param pcYuvOrg
4225 * \param pcYuvPred
4226 * \param rpcYuvResi
4227 * \param rpcYuvResiBest
4228 * \param rpcYuvRec
4229 * \param bSkipRes
4230 * \returns Void
4231 */
4232#if HHI_INTER_VIEW_RESIDUAL_PRED
4233Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred, TComYuv*& rpcYuvResi, TComYuv*& rpcYuvResiBest, TComYuv*& rpcYuvRec, TComYuv*& rpcYuvResPrd, Bool bSkipRes )
4234#else
4235Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred, TComYuv*& rpcYuvResi, TComYuv*& rpcYuvResiBest, TComYuv*& rpcYuvRec, Bool bSkipRes )
4236#endif
4237{
4238  if ( pcCU->isIntra(0) )
4239  {
4240    return;
4241  }
4242 
4243  PredMode  ePredMode    = pcCU->getPredictionMode( 0 );
4244  Bool      bHighPass    = pcCU->getSlice()->getDepth() ? true : false;
4245  UInt      uiBits       = 0, uiBitsBest = 0;
4246  Dist      uiDistortion = 0, uiDistortionBest = 0;
4247 
4248  UInt      uiWidth      = pcCU->getWidth ( 0 );
4249  UInt      uiHeight     = pcCU->getHeight( 0 );
4250#if LG_RESTRICTEDRESPRED_M24766
4251  Int       iPUResiPredShift[4];
4252#endif
4253  //  No residual coding : SKIP mode
4254  if ( ePredMode == MODE_SKIP && bSkipRes )
4255  {
4256    rpcYuvResi->clear();
4257   
4258    pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4259   
4260#if HHI_INTER_VIEW_RESIDUAL_PRED
4261    // add residual prediction
4262    if( pcCU->getResPredFlag( 0 ) )
4263    {
4264#if LG_RESTRICTEDRESPRED_M24766
4265                pcCU->getPUResiPredShift(iPUResiPredShift, 0);
4266                rpcYuvRec->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcYuvResPrd, uiWidth, uiHeight );
4267#else
4268      rpcYuvRec->add( rpcYuvResPrd, uiWidth, uiHeight );
4269#endif
4270      rpcYuvRec->clip( uiWidth, uiHeight );
4271    }
4272#endif
4273
4274#if HHI_VSO   
4275    if ( m_pcRdCost->getUseVSO() )
4276    {
4277      uiDistortion = m_pcRdCost->getDistVS( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight     , false, 0 );
4278        }
4279    else   
4280    {
4281#endif
4282#if WEIGHTED_CHROMA_DISTORTION
4283    uiDistortion = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4284    + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, true )
4285    + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, true );
4286#else
4287    uiDistortion = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4288    + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4289    + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4290#endif
4291#if HHI_VSO   
4292    }
4293#endif
4294
4295    if( m_bUseSBACRD )
4296      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4297   
4298    m_pcEntropyCoder->resetBits();
4299#if HHI_MPI
4300    if( pcCU->getTextureModeDepth( 0 ) == -1 )
4301    {
4302#endif
4303    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4304    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, 0, true );
4305#if HHI_INTER_VIEW_RESIDUAL_PRED
4306    m_pcEntropyCoder->encodeResPredFlag( pcCU, 0, 0, true );
4307#endif
4308#if HHI_MPI
4309    }
4310#endif
4311   
4312    uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4313    pcCU->getTotalBits()       = uiBits;
4314    pcCU->getTotalDistortion() = uiDistortion;
4315
4316#if HHI_VSO
4317    if ( m_pcRdCost->getUseLambdaScaleVSO() )
4318    {
4319      pcCU->getTotalCost() = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );
4320    }
4321    else
4322#endif
4323    {
4324    pcCU->getTotalCost()       = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4325    }
4326   
4327    if( m_bUseSBACRD )
4328      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4329   
4330    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4331    pcCU->setTrIdxSubParts( 0, 0, pcCU->getDepth(0) );
4332   
4333#if HHI_VSO // necessary?
4334    // set Model
4335    if( m_pcRdCost->getUseRenModel() )
4336    {
4337      Pel*  piSrc       = rpcYuvRec->getLumaAddr();
4338      UInt  uiSrcStride = rpcYuvRec->getStride();
4339      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4340    }
4341#endif
4342
4343    return;
4344  }
4345 
4346  //  Residual coding.
4347#if H0736_AVC_STYLE_QP_RANGE
4348  Int    qp, qpBest = 0, qpMin, qpMax;
4349#else
4350  UInt    uiQp, uiQpBest = 0, uiQpMin, uiQpMax;
4351#endif
4352  Double  dCost, dCostBest = MAX_DOUBLE;
4353 
4354  UInt uiTrLevel = 0;
4355  if( (pcCU->getWidth(0) > pcCU->getSlice()->getSPS()->getMaxTrSize()) )
4356  {
4357    while( pcCU->getWidth(0) > (pcCU->getSlice()->getSPS()->getMaxTrSize()<<uiTrLevel) ) uiTrLevel++;
4358  }
4359  UInt uiMaxTrMode = pcCU->getSlice()->getSPS()->getMaxTrDepth() + uiTrLevel;
4360 
4361  while((uiWidth>>uiMaxTrMode) < (g_uiMaxCUWidth>>g_uiMaxCUDepth)) uiMaxTrMode--;
4362 
4363#if H0736_AVC_STYLE_QP_RANGE
4364  qpMin =  bHighPass ? Clip3( -pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, pcCU->getQP(0) - m_iMaxDeltaQP ) : pcCU->getQP( 0 );
4365  qpMax =  bHighPass ? Clip3( -pcCU->getSlice()->getSPS()->getQpBDOffsetY(), MAX_QP, pcCU->getQP(0) + m_iMaxDeltaQP ) : pcCU->getQP( 0 );
4366#else
4367  uiQpMin      = bHighPass ? min( MAX_QP, max( MIN_QP, pcCU->getQP(0) - m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4368  uiQpMax      = bHighPass ? min( MAX_QP, max( MIN_QP, pcCU->getQP(0) + m_iMaxDeltaQP ) ) : pcCU->getQP( 0 );
4369#endif
4370
4371  #if HHI_INTERVIEW_SKIP
4372  if( bSkipRes)
4373  {
4374    rpcYuvResi->clear() ;
4375  }
4376  else
4377  {
4378#if LG_RESTRICTEDRESPRED_M24766
4379          iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = 0;
4380          rpcYuvResi->subtract(iPUResiPredShift, pcCU->getPartitionSize(0), pcYuvOrg, pcYuvPred, 0, uiWidth );
4381#else
4382  rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4383#endif
4384#if HHI_INTER_VIEW_RESIDUAL_PRED
4385    // subtract residual prediction
4386    if( pcCU->getResPredFlag( 0 ) )
4387    {
4388#if LG_RESTRICTEDRESPRED_M24766
4389                pcCU->getPUResiPredShift(iPUResiPredShift, 0);
4390                rpcYuvResi->subtract(iPUResiPredShift, pcCU->getPartitionSize(0), rpcYuvResi, rpcYuvResPrd, 0, uiWidth );
4391#else
4392      rpcYuvResi->subtract( rpcYuvResi, rpcYuvResPrd, 0, uiWidth );
4393#endif
4394    }
4395#endif
4396  }
4397#else
4398  rpcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, uiWidth );
4399#if HHI_INTER_VIEW_RESIDUAL_PRED
4400  // add residual prediction
4401  if( pcCU->getResPredFlag( 0 ) )
4402  {
4403    rpcYuvResi->subtract( rpcYuvResi, rpcYuvResPrd, uiWidth, uiHeight );
4404  }
4405#endif
4406#endif
4407
4408#if H0736_AVC_STYLE_QP_RANGE
4409  for ( qp = qpMin; qp <= qpMax; qp++ )
4410#else
4411  for ( uiQp = uiQpMin; uiQp <= uiQpMax; uiQp++ )
4412#endif
4413  {
4414    dCost = 0.;
4415    uiBits = 0;
4416    uiDistortion = 0;
4417    if( m_bUseSBACRD )
4418    {
4419      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4420    }
4421   
4422    Dist uiZeroDistortion = 0;
4423#if HHI_VSO
4424    if ( m_pcRdCost->getUseVSO() )
4425    {
4426      m_cYuvRecTemp.create( pcYuvPred->getWidth(), pcYuvPred->getHeight()  );
4427    }
4428#endif
4429#if IBDI_DISTORTION || HHI_VSO
4430    xEstimateResidualQT( pcCU, 0, 0, 0, pcYuvOrg, pcYuvPred, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4431#else
4432    xEstimateResidualQT( pcCU, 0, 0, 0, rpcYuvResi,  pcCU->getDepth(0), dCost, uiBits, uiDistortion, &uiZeroDistortion );
4433#endif
4434   
4435
4436#if HHI_VSO
4437    if ( m_pcRdCost->getUseVSO() )
4438    {
4439      m_cYuvRecTemp.destroy();
4440    }
4441#endif
4442
4443    double dZeroCost;
4444#if HHI_VSO
4445    if( m_pcRdCost->getUseLambdaScaleVSO() )
4446    {
4447      dZeroCost = m_pcRdCost->calcRdCostVSO( 0, uiZeroDistortion );
4448    }
4449    else
4450#endif
4451    {
4452      dZeroCost = m_pcRdCost->calcRdCost( 0, uiZeroDistortion );
4453    }
4454
4455#if LOSSLESS_CODING
4456    if(pcCU->isLosslessCoded( 0 ))
4457    { 
4458      dZeroCost = dCost + 1;
4459    }
4460#endif
4461    if ( dZeroCost < dCost )
4462    {
4463      dCost        = dZeroCost;
4464      uiBits       = 0;
4465      uiDistortion = uiZeroDistortion;
4466     
4467      const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4468      ::memset( pcCU->getTransformIdx()      , 0, uiQPartNum * sizeof(UChar) );
4469      ::memset( pcCU->getCbf( TEXT_LUMA )    , 0, uiQPartNum * sizeof(UChar) );
4470      ::memset( pcCU->getCbf( TEXT_CHROMA_U ), 0, uiQPartNum * sizeof(UChar) );
4471      ::memset( pcCU->getCbf( TEXT_CHROMA_V ), 0, uiQPartNum * sizeof(UChar) );
4472      ::memset( pcCU->getCoeffY()            , 0, uiWidth * uiHeight * sizeof( TCoeff )      );
4473      ::memset( pcCU->getCoeffCb()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4474      ::memset( pcCU->getCoeffCr()           , 0, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4475    }
4476    else
4477    {
4478      xSetResidualQTData( pcCU, 0, 0, 0, NULL, pcCU->getDepth(0), false );
4479    }
4480   
4481    if( m_bUseSBACRD )
4482    {
4483      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4484    }
4485#if 0 // check
4486    {
4487      m_pcEntropyCoder->resetBits();
4488      m_pcEntropyCoder->encodeCoeff( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
4489      const UInt uiBitsForCoeff = m_pcEntropyCoder->getNumberOfWrittenBits();
4490      if( m_bUseSBACRD )
4491      {
4492        m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4493      }
4494      if( uiBitsForCoeff != uiBits )
4495        assert( 0 );
4496    }
4497#endif
4498    uiBits = 0;
4499    {
4500      TComYuv *pDummy = NULL;
4501      xAddSymbolBitsInter( pcCU, 0, 0, uiBits, pDummy, NULL, pDummy );
4502    }
4503   
4504    Double dExactCost;
4505#if HHI_VSO
4506    if( m_pcRdCost->getUseLambdaScaleVSO() )
4507    {
4508      dExactCost = m_pcRdCost->calcRdCostVSO( uiBits, uiDistortion );;
4509    }
4510    else
4511#endif
4512    {
4513      dExactCost = m_pcRdCost->calcRdCost( uiBits, uiDistortion );
4514    }
4515   
4516    dCost = dExactCost;
4517   
4518    if ( dCost < dCostBest )
4519    {
4520      if ( !pcCU->getQtRootCbf( 0 ) )
4521      {
4522        rpcYuvResiBest->clear();
4523      }
4524      else
4525      {
4526        xSetResidualQTData( pcCU, 0, 0, 0, rpcYuvResiBest, pcCU->getDepth(0), true );
4527      }
4528     
4529#if H0736_AVC_STYLE_QP_RANGE
4530      if( qpMin != qpMax && qp != qpMax )
4531#else
4532      if( uiQpMin != uiQpMax && uiQp != uiQpMax )
4533#endif
4534      {
4535        const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4536        ::memcpy( m_puhQTTempTrIdx, pcCU->getTransformIdx(),        uiQPartNum * sizeof(UChar) );
4537        ::memcpy( m_puhQTTempCbf[0], pcCU->getCbf( TEXT_LUMA ),     uiQPartNum * sizeof(UChar) );
4538        ::memcpy( m_puhQTTempCbf[1], pcCU->getCbf( TEXT_CHROMA_U ), uiQPartNum * sizeof(UChar) );
4539        ::memcpy( m_puhQTTempCbf[2], pcCU->getCbf( TEXT_CHROMA_V ), uiQPartNum * sizeof(UChar) );
4540        ::memcpy( m_pcQTTempCoeffY,  pcCU->getCoeffY(),  uiWidth * uiHeight * sizeof( TCoeff )      );
4541        ::memcpy( m_pcQTTempCoeffCb, pcCU->getCoeffCb(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4542        ::memcpy( m_pcQTTempCoeffCr, pcCU->getCoeffCr(), uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4543#if ADAPTIVE_QP_SELECTION
4544        ::memcpy( m_pcQTTempArlCoeffY,  pcCU->getArlCoeffY(),  uiWidth * uiHeight * sizeof( Int )      );
4545        ::memcpy( m_pcQTTempArlCoeffCb, pcCU->getArlCoeffCb(), uiWidth * uiHeight * sizeof( Int ) >> 2 );
4546        ::memcpy( m_pcQTTempArlCoeffCr, pcCU->getArlCoeffCr(), uiWidth * uiHeight * sizeof( Int ) >> 2 );
4547#endif
4548      }
4549      uiBitsBest       = uiBits;
4550      uiDistortionBest = uiDistortion;
4551      dCostBest        = dCost;
4552#if H0736_AVC_STYLE_QP_RANGE
4553      qpBest           = qp;
4554#else
4555      uiQpBest         = uiQp;
4556#endif     
4557      if( m_bUseSBACRD )
4558      {
4559        m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4560      }
4561    }
4562
4563#if HHI_VSO
4564    // GT: reset Model, only fordQP necessary??
4565    if( m_pcRdCost->getUseRenModel() )
4566    {
4567      Pel*  piSrc       = pcYuvOrg->getLumaAddr();
4568      UInt  uiSrcStride = pcYuvOrg->getStride();
4569      m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4570    }
4571#endif
4572  }
4573 
4574  assert ( dCostBest != MAX_DOUBLE );
4575 
4576#if H0736_AVC_STYLE_QP_RANGE
4577  if( qpMin != qpMax && qpBest != qpMax )
4578#else
4579  if( uiQpMin != uiQpMax && uiQpBest != uiQpMax )
4580#endif
4581  {
4582    if( m_bUseSBACRD )
4583    {
4584      assert( 0 ); // check
4585      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4586    }
4587    // copy best cbf and trIdx to pcCU
4588    const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (pcCU->getDepth(0) << 1);
4589    ::memcpy( pcCU->getTransformIdx(),       m_puhQTTempTrIdx,  uiQPartNum * sizeof(UChar) );
4590    ::memcpy( pcCU->getCbf( TEXT_LUMA ),     m_puhQTTempCbf[0], uiQPartNum * sizeof(UChar) );
4591    ::memcpy( pcCU->getCbf( TEXT_CHROMA_U ), m_puhQTTempCbf[1], uiQPartNum * sizeof(UChar) );
4592    ::memcpy( pcCU->getCbf( TEXT_CHROMA_V ), m_puhQTTempCbf[2], uiQPartNum * sizeof(UChar) );
4593    ::memcpy( pcCU->getCoeffY(),  m_pcQTTempCoeffY,  uiWidth * uiHeight * sizeof( TCoeff )      );
4594    ::memcpy( pcCU->getCoeffCb(), m_pcQTTempCoeffCb, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4595    ::memcpy( pcCU->getCoeffCr(), m_pcQTTempCoeffCr, uiWidth * uiHeight * sizeof( TCoeff ) >> 2 );
4596#if ADAPTIVE_QP_SELECTION
4597    ::memcpy( pcCU->getArlCoeffY(),  m_pcQTTempArlCoeffY,  uiWidth * uiHeight * sizeof( Int )      );
4598    ::memcpy( pcCU->getArlCoeffCb(), m_pcQTTempArlCoeffCb, uiWidth * uiHeight * sizeof( Int ) >> 2 );
4599    ::memcpy( pcCU->getArlCoeffCr(), m_pcQTTempArlCoeffCr, uiWidth * uiHeight * sizeof( Int ) >> 2 );
4600#endif
4601  }
4602#if HHI_INTER_VIEW_RESIDUAL_PRED
4603  // add residual prediction
4604  if( pcCU->getResPredFlag( 0 ) )
4605  {
4606    pcYuvPred->copyToPartYuv( rpcYuvRec, 0 );
4607#if LG_RESTRICTEDRESPRED_M24766
4608        pcCU->getPUResiPredShift(iPUResiPredShift, 0);
4609        rpcYuvRec->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcYuvResPrd,   uiWidth, uiHeight );
4610        iPUResiPredShift[0] = iPUResiPredShift[1] = iPUResiPredShift[2] = iPUResiPredShift[3] = 0;
4611    rpcYuvRec->add(iPUResiPredShift, pcCU->getPartitionSize(0), rpcYuvResiBest, uiWidth, uiHeight );
4612#else
4613    rpcYuvRec->add( rpcYuvResPrd,   uiWidth, uiHeight );
4614    rpcYuvRec->add( rpcYuvResiBest, uiWidth, uiHeight );
4615#endif
4616    rpcYuvRec->clip( uiWidth, uiHeight );
4617  }
4618  else
4619#endif
4620  rpcYuvRec->addClip ( pcYuvPred, rpcYuvResiBest, 0, uiWidth );
4621 
4622  // update with clipped distortion and cost (qp estimation loop uses unclipped values)
4623
4624#if HHI_VSO // GT: might be removed since VSO already provided clipped distortion
4625  if ( m_pcRdCost->getUseVSO() )
4626  {
4627    uiDistortionBest = m_pcRdCost->getDistVS  ( pcCU, 0, rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight, false, 0    );
4628  }
4629  else
4630#endif
4631{
4632#if WEIGHTED_CHROMA_DISTORTION
4633  uiDistortionBest = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4634  + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, true )
4635  + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1, true );
4636#else
4637  uiDistortionBest = m_pcRdCost->getDistPart( rpcYuvRec->getLumaAddr(), rpcYuvRec->getStride(),  pcYuvOrg->getLumaAddr(), pcYuvOrg->getStride(),  uiWidth,      uiHeight      )
4638  + m_pcRdCost->getDistPart( rpcYuvRec->getCbAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCbAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 )
4639  + m_pcRdCost->getDistPart( rpcYuvRec->getCrAddr(),   rpcYuvRec->getCStride(), pcYuvOrg->getCrAddr(),   pcYuvOrg->getCStride(), uiWidth >> 1, uiHeight >> 1 );
4640#endif
4641}
4642#if HHI_VSO
4643  if ( m_pcRdCost->getUseLambdaScaleVSO() )
4644  {
4645    dCostBest = m_pcRdCost->calcRdCostVSO( uiBitsBest, uiDistortionBest );
4646  }
4647  else
4648#endif
4649  {
4650  dCostBest = m_pcRdCost->calcRdCost( uiBitsBest, uiDistortionBest );
4651  }
4652 
4653  pcCU->getTotalBits()       = uiBitsBest;
4654  pcCU->getTotalDistortion() = uiDistortionBest;
4655  pcCU->getTotalCost()       = dCostBest;
4656 
4657  if ( pcCU->isSkipped(0) )
4658  {
4659    pcCU->setCbfSubParts( 0, 0, 0, 0, pcCU->getDepth( 0 ) );
4660  }
4661 
4662#if H0736_AVC_STYLE_QP_RANGE
4663  pcCU->setQPSubParts( qpBest, 0, pcCU->getDepth(0) );
4664#else
4665  pcCU->setQPSubParts( uiQpBest, 0, pcCU->getDepth(0) );
4666#endif
4667
4668  // set Model
4669#if HHI_VSO // necessary??
4670  if( m_pcRdCost->getUseRenModel() )
4671  {
4672    Pel*  piSrc       = rpcYuvRec->getLumaAddr();
4673    UInt  uiSrcStride = rpcYuvRec->getStride();
4674    m_pcRdCost->setRenModelData( pcCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
4675}
4676#endif
4677
4678}
4679
4680#if IBDI_DISTORTION || HHI_VSO
4681Void 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 )
4682#else
4683Void TEncSearch::xEstimateResidualQT( TComDataCU* pcCU, UInt uiQuadrant, UInt uiAbsPartIdx, UInt absTUPartIdx, TComYuv* pcResi, const UInt uiDepth, Double &rdCost, UInt &ruiBits, Dist &ruiDist, Dist *puiZeroDist )
4684#endif
4685{
4686  const UInt uiTrMode = uiDepth - pcCU->getDepth( 0 );
4687 
4688  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
4689  const UInt uiLog2TrSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth]+2;
4690 
4691#if G519_TU_AMP_NSQT_HARMONIZATION
4692  UInt SplitFlag = ((pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && ( pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N ));
4693#else
4694  UInt SplitFlag = ((pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && ( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2NxN || pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_Nx2N));
4695#endif
4696  Bool bCheckFull;
4697  if ( SplitFlag && uiDepth == pcCU->getDepth(uiAbsPartIdx) && ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ) )
4698     bCheckFull = false;
4699  else
4700     bCheckFull =  ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
4701
4702  const Bool bCheckSplit  = ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
4703 
4704  assert( bCheckFull || bCheckSplit );
4705 
4706  Bool  bCodeChroma   = true;
4707  UInt  uiTrModeC     = uiTrMode;
4708  UInt  uiLog2TrSizeC = uiLog2TrSize-1;
4709  if( uiLog2TrSize == 2 )
4710  {
4711    uiLog2TrSizeC++;
4712    uiTrModeC    --;
4713    UInt  uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( pcCU->getDepth( 0 ) + uiTrModeC ) << 1 );
4714    bCodeChroma   = ( ( uiAbsPartIdx % uiQPDiv ) == 0 );
4715  }
4716 
4717  const UInt uiSetCbf = 1 << uiTrMode;
4718  // code full block
4719  Double dSingleCost = MAX_DOUBLE;
4720  UInt uiSingleBits = 0;
4721  Dist uiSingleDist = 0;
4722  UInt uiAbsSumY = 0, uiAbsSumU = 0, uiAbsSumV = 0;
4723 
4724  if( m_bUseSBACRD )
4725  {
4726    m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4727  }
4728 
4729  if( bCheckFull )
4730  {
4731    const UInt uiNumCoeffPerAbsPartIdxIncrement = pcCU->getSlice()->getSPS()->getMaxCUWidth() * pcCU->getSlice()->getSPS()->getMaxCUHeight() >> ( pcCU->getSlice()->getSPS()->getMaxCUDepth() << 1 );
4732    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
4733    TCoeff *pcCoeffCurrY = m_ppcQTTempCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
4734    TCoeff *pcCoeffCurrU = m_ppcQTTempCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4735    TCoeff *pcCoeffCurrV = m_ppcQTTempCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4736#if ADAPTIVE_QP_SELECTION   
4737    Int *pcArlCoeffCurrY = m_ppcQTTempArlCoeffY [uiQTTempAccessLayer] +  uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx;
4738    Int *pcArlCoeffCurrU = m_ppcQTTempArlCoeffCb[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);
4739    Int *pcArlCoeffCurrV = m_ppcQTTempArlCoeffCr[uiQTTempAccessLayer] + (uiNumCoeffPerAbsPartIdxIncrement * uiAbsPartIdx>>2);   
4740#endif
4741   
4742    Int trWidth = 0, trHeight = 0, trWidthC = 0, trHeightC = 0;
4743    UInt absTUPartIdxC = uiAbsPartIdx;
4744
4745    trWidth  = trHeight  = 1 << uiLog2TrSize;
4746    trWidthC = trHeightC = 1 <<uiLog2TrSizeC;
4747    pcCU->getNSQTSize ( uiTrMode, uiAbsPartIdx, trWidth, trHeight );
4748    pcCU->getNSQTSize ( uiTrModeC, uiAbsPartIdx, trWidthC, trHeightC );
4749
4750    if( bCodeChroma && pcCU->useNonSquareTrans( uiTrMode, uiAbsPartIdx ) && !( uiLog2TrSizeC  == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() && uiTrModeC == 1 ) )
4751    { 
4752      absTUPartIdxC = pcCU->getNSAddrChroma( uiLog2TrSizeC, uiTrModeC, uiQuadrant, absTUPartIdx );
4753    }
4754    pcCU->setTrIdxSubParts( uiDepth - pcCU->getDepth( 0 ), uiAbsPartIdx, uiDepth );
4755    if (m_pcEncCfg->getUseRDOQ())
4756    {
4757      m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, trWidth, trHeight, TEXT_LUMA );       
4758    }
4759
4760#if H0736_AVC_STYLE_QP_RANGE
4761    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
4762#else
4763    m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA, 0 );
4764#endif
4765
4766#if RDOQ_CHROMA_LAMBDA
4767    m_pcTrQuant->selectLambda(TEXT_LUMA); 
4768#endif
4769    m_pcTrQuant->transformNxN( pcCU, pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride (), pcCoeffCurrY, 
4770#if ADAPTIVE_QP_SELECTION
4771                                 pcArlCoeffCurrY, 
4772#endif     
4773                                 trWidth,   trHeight,    uiAbsSumY, TEXT_LUMA,     uiAbsPartIdx );
4774   
4775    pcCU->setCbfSubParts( uiAbsSumY ? uiSetCbf : 0, TEXT_LUMA, uiAbsPartIdx, uiDepth );
4776   
4777    if( bCodeChroma )
4778    {
4779      if (m_pcEncCfg->getUseRDOQ())
4780      {
4781        m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, trWidthC, trHeightC, TEXT_CHROMA );         
4782      }
4783
4784#if H0736_AVC_STYLE_QP_RANGE
4785      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), pcCU->getSlice()->getPPS()->getChromaQpOffset() );
4786#else
4787      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getPPS()->getChromaQpOffset() );
4788#endif
4789
4790#if RDOQ_CHROMA_LAMBDA
4791      m_pcTrQuant->selectLambda(TEXT_CHROMA); 
4792#endif
4793
4794      m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrU, 
4795#if ADAPTIVE_QP_SELECTION
4796                                 pcArlCoeffCurrU, 
4797#endif       
4798                                 trWidthC, trHeightC, uiAbsSumU, TEXT_CHROMA_U, uiAbsPartIdx );
4799#if H0736_AVC_STYLE_QP_RANGE
4800      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), pcCU->getSlice()->getPPS()->getChromaQpOffset2nd() );
4801#else
4802      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getPPS()->getChromaQpOffset2nd() );
4803#endif
4804      m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrV, 
4805#if ADAPTIVE_QP_SELECTION
4806                                 pcArlCoeffCurrV, 
4807#endif       
4808                                 trWidthC, trHeightC, uiAbsSumV, TEXT_CHROMA_V, uiAbsPartIdx );
4809
4810      pcCU->setCbfSubParts( uiAbsSumU ? uiSetCbf : 0, TEXT_CHROMA_U, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
4811      pcCU->setCbfSubParts( uiAbsSumV ? uiSetCbf : 0, TEXT_CHROMA_V, uiAbsPartIdx, pcCU->getDepth(0)+uiTrModeC );
4812    }
4813   
4814    m_pcEntropyCoder->resetBits();
4815   
4816    {
4817      m_pcEntropyCoder->encodeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA,     uiTrMode );
4818    }
4819   
4820    m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrY, uiAbsPartIdx,  trWidth,  trHeight,    uiDepth, TEXT_LUMA );
4821    const UInt uiSingleBitsY = m_pcEntropyCoder->getNumberOfWrittenBits();
4822   
4823    UInt uiSingleBitsU = 0;
4824    UInt uiSingleBitsV = 0;
4825    if( bCodeChroma )
4826    {
4827      {
4828        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrMode );
4829      }
4830      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrU, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_U );
4831      uiSingleBitsU = m_pcEntropyCoder->getNumberOfWrittenBits() - uiSingleBitsY;
4832     
4833      {
4834        m_pcEntropyCoder->encodeQtCbf   ( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrMode );
4835      }
4836      m_pcEntropyCoder->encodeCoeffNxN( pcCU, pcCoeffCurrV, uiAbsPartIdx, trWidthC, trHeightC, uiDepth, TEXT_CHROMA_V );
4837      uiSingleBitsV = m_pcEntropyCoder->getNumberOfWrittenBits() - ( uiSingleBitsY + uiSingleBitsU );
4838    }
4839   
4840    const UInt uiNumSamplesLuma = 1 << (uiLog2TrSize<<1);
4841    const UInt uiNumSamplesChro = 1 << (uiLog2TrSizeC<<1);
4842   
4843    Dist uiDistY;
4844
4845//GT VSO
4846
4847    // GT Fix: Not necessary for VSO, however used for chroma later, irrelevant except from valgrind error message
4848    ::memset( m_pTempPel, 0, sizeof( Pel ) * uiNumSamplesLuma ); // not necessary needed for inside of recursion (only at the beginning)
4849   
4850#if HHI_VSO
4851    if ( m_pcRdCost->getUseVSO() )
4852    {
4853      uiDistY = m_pcRdCost->getDistVS  ( pcCU, uiAbsPartIdx, pcPred->getLumaAddr( uiAbsPartIdx ), pcPred->getStride(), pcOrg->getLumaAddr( uiAbsPartIdx), pcOrg->getStride(), 1<< uiLog2TrSize, 1<< uiLog2TrSize, false, 0 ); // initialized with zero residual distortion
4854    }
4855    else
4856#endif
4857    {
4858#if IBDI_DISTORTION
4859     uiDistY = m_pcRdCost->getDistPart( pcPred->getLumaAddr( absTUPartIdx ), pcPred->getStride(), pcOrg->getLumaAddr( absTUPartIdx), pcOrg->getStride(), trWidth, trHeight);
4860#else
4861     uiDistY = m_pcRdCost->getDistPart( m_pTempPel, trWidth, pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride(), trWidth, trHeight ); // initialized with zero residual destortion
4862#endif
4863    }
4864
4865
4866    if ( puiZeroDist )
4867    {
4868      *puiZeroDist += uiDistY;
4869    }
4870    if( uiAbsSumY )
4871    {
4872      Pel *pcResiCurrY = m_pcQTTempTComYuv[ uiQTTempAccessLayer ].getLumaAddr( absTUPartIdx );
4873
4874#if H0736_AVC_STYLE_QP_RANGE
4875      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA, pcCU->getSlice()->getSPS()->getQpBDOffsetY(), 0 );
4876#else
4877      m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_LUMA, 0 );
4878#endif
4879
4880      Int scalingListType = 3 + g_eTTable[(Int)TEXT_LUMA];
4881      assert(scalingListType < 6);     
4882#if LOSSLESS_CODING
4883      m_pcTrQuant->invtransformNxN( pcCU, TEXT_LUMA,REG_DCT, pcResiCurrY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),  pcCoeffCurrY, trWidth, trHeight, scalingListType );//this is for inter mode only
4884#else     
4885      m_pcTrQuant->invtransformNxN( TEXT_LUMA,REG_DCT, pcResiCurrY, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),  pcCoeffCurrY, trWidth, trHeight, scalingListType );//this is for inter mode only
4886#endif
4887     
4888      Dist uiNonzeroDistY;
4889
4890#if HHI_VSO     
4891      if ( m_pcRdCost->getUseVSO() )
4892      {
4893        static int iCount = 1; 
4894        iCount++; 
4895        m_cYuvRecTemp.addClipPartLuma( &m_pcQTTempTComYuv[uiQTTempAccessLayer], pcPred, uiAbsPartIdx, 1<< uiLog2TrSize  );
4896        uiNonzeroDistY = m_pcRdCost->getDistVS( pcCU, uiAbsPartIdx, m_cYuvRecTemp.getLumaAddr(uiAbsPartIdx), m_cYuvRecTemp.getStride(),
4897                                                pcOrg->getLumaAddr( uiAbsPartIdx ), pcOrg->getStride(), 1<< uiLog2TrSize,   1<< uiLog2TrSize, false, 0 );
4898      }
4899      else
4900#endif
4901      {
4902        uiNonzeroDistY = m_pcRdCost->getDistPart( m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( absTUPartIdx ), m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(),
4903          pcResi->getLumaAddr( absTUPartIdx ), pcResi->getStride(), trWidth,trHeight );
4904      }
4905
4906#if LOSSLESS_CODING
4907      if (pcCU->isLosslessCoded(0)) 
4908      {
4909        uiDistY = uiNonzeroDistY;
4910      }
4911      else
4912      {
4913
4914      Double singleCostY;
4915      Double nullCostY;
4916
4917#if HHI_VSO     
4918      if ( m_pcRdCost->getUseLambdaScaleVSO())
4919      {
4920        singleCostY = m_pcRdCost->calcRdCostVSO( uiSingleBitsY, uiNonzeroDistY );
4921        nullCostY   = m_pcRdCost->calcRdCostVSO( 0, uiDistY );
4922      }
4923      else
4924#endif
4925      {
4926        singleCostY = m_pcRdCost->calcRdCost( uiSingleBitsY, uiNonzeroDistY );
4927        nullCostY   = m_pcRdCost->calcRdCost( 0, uiDistY );
4928      }
4929        if( nullCostY < singleCostY ) 
4930        {   
4931          uiAbsSumY = 0;
4932          ::memset( pcCoeffCurrY, 0, sizeof( TCoeff ) * uiNumSamplesLuma );
4933        }
4934        else
4935        {
4936          uiDistY = uiNonzeroDistY;
4937        }
4938      }
4939#else
4940      Double dSingleCostY;
4941      Double dNullCostY;
4942
4943#if HHI_VSO     
4944      if ( m_pcRdCost->getUseLambdaScaleVSO())
4945      {
4946        dSingleCostY = m_pcRdCost->calcRdCostVSO( uiSingleBitsY, uiNonzeroDistY );
4947        dNullCostY   = m_pcRdCost->calcRdCostVSO( 0, uiDistY );
4948      }
4949      else
4950#endif
4951      {
4952        dSingleCostY = m_pcRdCost->calcRdCost( uiSingleBitsY, uiNonzeroDistY );
4953        dNullCostY   = m_pcRdCost->calcRdCost( 0, uiDistY );
4954      }
4955      if( dNullCostY < dSingleCostY )
4956      {
4957        uiAbsSumY = 0;
4958        ::memset( pcCoeffCurrY, 0, sizeof( TCoeff ) * uiNumSamplesLuma );
4959      }
4960      else
4961      {
4962        uiDistY = uiNonzeroDistY;
4963      }
4964#endif
4965    }
4966   
4967    if( !uiAbsSumY )
4968    {
4969      Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getLumaAddr( absTUPartIdx );
4970      const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride();
4971      for( UInt uiY = 0; uiY < trHeight; ++uiY )
4972      {
4973        ::memset( pcPtr, 0, sizeof( Pel ) * trWidth );
4974        pcPtr += uiStride;
4975      } 
4976    }
4977   
4978    UInt uiDistU = 0;
4979    UInt uiDistV = 0;
4980    if( bCodeChroma )
4981    {
4982#if IBDI_DISTORTION
4983      uiDistU = m_pcRdCost->getDistPart( pcPred->getCbAddr( absTUPartIdxC ), pcPred->getCStride(), pcOrg->getCbAddr( absTUPartIdxC ), pcOrg->getCStride(), trWidthC, trHeightC
4984#if WEIGHTED_CHROMA_DISTORTION
4985                                          , true
4986#endif
4987                                          );
4988#else
4989      uiDistU = m_pcRdCost->getDistPart( m_pTempPel, trWidthC, pcResi->getCbAddr( absTUPartIdxC ), pcResi->getCStride(), trWidthC, trHeightC
4990#if WEIGHTED_CHROMA_DISTORTION
4991                                          , true
4992#endif
4993                                          ); // initialized with zero residual destortion
4994#endif
4995      if ( puiZeroDist )
4996      {
4997        *puiZeroDist += uiDistU;
4998      }
4999      if( uiAbsSumU )
5000      {
5001        Pel *pcResiCurrU = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC );
5002
5003#if H0736_AVC_STYLE_QP_RANGE
5004        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), pcCU->getSlice()->getPPS()->getChromaQpOffset() );
5005#else
5006        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), false, pcCU->getSlice()->getSliceType(), TEXT_CHROMA, pcCU->getSlice()->getPPS()->getChromaQpOffset() );
5007#endif
5008
5009        Int scalingListType = 3 + g_eTTable[(Int)TEXT_CHROMA_U];
5010        assert(scalingListType < 6);
5011#if LOSSLESS_CODING
5012        m_pcTrQuant->invtransformNxN( pcCU, TEXT_CHROMA,REG_DCT, pcResiCurrU, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrU, trWidthC, trHeightC, scalingListType  );
5013#else
5014        m_pcTrQuant->invtransformNxN( TEXT_CHROMA,REG_DCT, pcResiCurrU, m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(), pcCoeffCurrU, trWidthC, trHeightC, scalingListType );
5015#endif       
5016       
5017        const UInt uiNonzeroDistU = m_pcRdCost->getDistPart( m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC), m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride(),
5018          pcResi->getCbAddr( absTUPartIdxC), pcResi->getCStride(), trWidthC, trHeightC
5019#if WEIGHTED_CHROMA_DISTORTION
5020          , true
5021#endif
5022          );
5023
5024#if LOSSLESS_CODING
5025        if(pcCU->isLosslessCoded(0)) 
5026        {
5027          uiDistU = uiNonzeroDistU;
5028        }
5029        else
5030        {
5031          const Double dSingleCostU = m_pcRdCost->calcRdCost( uiSingleBitsU, uiNonzeroDistU );
5032          const Double dNullCostU   = m_pcRdCost->calcRdCost( 0, uiDistU );
5033          if( dNullCostU < dSingleCostU )
5034          {
5035            uiAbsSumU = 0;
5036            ::memset( pcCoeffCurrU, 0, sizeof( TCoeff ) * uiNumSamplesChro );
5037          }
5038          else
5039          {
5040            uiDistU = uiNonzeroDistU;
5041          }
5042        }
5043#else
5044        const Double dSingleCostU = m_pcRdCost->calcRdCost( uiSingleBitsU, uiNonzeroDistU );
5045        const Double dNullCostU   = m_pcRdCost->calcRdCost( 0, uiDistU );
5046        if( dNullCostU < dSingleCostU )
5047        {
5048          uiAbsSumU = 0;
5049          ::memset( pcCoeffCurrU, 0, sizeof( TCoeff ) * uiNumSamplesChro );
5050        }
5051        else
5052        {
5053          uiDistU = uiNonzeroDistU;
5054        }
5055#endif
5056      }
5057      if( !uiAbsSumU )
5058      {
5059        Pel *pcPtr =  m_pcQTTempTComYuv[uiQTTempAccessLayer].getCbAddr( absTUPartIdxC );
5060          const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCStride();
5061        for( UInt uiY = 0; uiY < trHeightC; ++uiY )
5062        {
5063          ::memset( pcPtr, 0, sizeof(Pel) * trWidthC );
5064          pcPtr += uiStride;
5065        }
5066      }
5067     
5068#if IBDI_DISTORTION
5069      uiDistV = m_pcRdCost->getDistPart( pcPred->getCrAddr( absTUPartIdxC ), pcPred->getCStride(), pcOrg->getCrAddr( absTUPartIdxC ), pcOrg->getCStride(), trWidthC, trHeightC
5070#if WEIGHTED_CHROMA_DISTORTION
5071                                          , true
5072#endif
5073                                          );
5074#else
5075      uiDistV = m_pcRdCost->getDistPart( m_pTempPel, trWidthC, pcResi->getCrAddr( absTUPartIdxC), pcResi->getCStride(), trWidthC, trHeightC
5076#if WEIGHTED_CHROMA_DISTORTION
5077                                          , true
5078#endif
5079                                          ); // initialized with zero residual destortion
5080#endif
5081      if ( puiZeroDist )
5082      {
5083        *puiZeroDist += uiDistV;
5084      }
5085      if( uiAbsSumV )
5086      {
5087        Pel *pcResiCurrV = m_pcQTTempTComYuv[uiQTTempAccessLayer].getCrAddr( absTUPartIdxC );