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

Last change on this file since 1427 was 1424, checked in by seregin, 10 years ago

fix uninitialized variables at encoder

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