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

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

Bug fixes:

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