Ticket #115: TEncSearch.cpp

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