source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/TEncSearch.cpp @ 1400

Last change on this file since 1400 was 1398, checked in by seregin, 10 years ago

port rev 4551

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