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

Last change on this file since 1514 was 1514, checked in by seregin, 8 years ago

remove redundant code

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