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

Last change on this file since 1590 was 1567, checked in by seregin, 9 years ago

port rev 4744

  • Property svn:eol-style set to native
File size: 228.8 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2016, 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()->getTransquantBypassEnabledFlag())
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->checkZeroMVILRMerge(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]);
2891
2892    if( bZeroMVILR )
2893    {
2894#endif
2895#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
2896    if (!(pcCU->isInterLayerReference(uhInterDirNeighbours[uiMergeCand], cMvFieldNeighbours[0 + 2*uiMergeCand], cMvFieldNeighbours[1 + 2*uiMergeCand]) && m_disableILP))
2897    {
2898#endif
2899    Distortion uiCostCand = std::numeric_limits<Distortion>::max();
2900    UInt       uiBitsCand = 0;
2901
2902    PartSize ePartSize = pcCU->getPartitionSize( 0 );
2903
2904    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
2905    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], ePartSize, uiAbsPartIdx, 0, iPUIdx );
2906
2907    xGetInterPredictionError( pcCU, pcYuvOrg, iPUIdx, uiCostCand, m_pcEncCfg->getUseHADME() );
2908    uiBitsCand = uiMergeCand + 1;
2909    if (uiMergeCand == m_pcEncCfg->getMaxNumMergeCand() -1)
2910    {
2911        uiBitsCand--;
2912    }
2913    uiCostCand = uiCostCand + m_pcRdCost->getCost( uiBitsCand );
2914    if ( uiCostCand < ruiCost )
2915    {
2916      ruiCost = uiCostCand;
2917      pacMvField[0] = cMvFieldNeighbours[0 + 2*uiMergeCand];
2918      pacMvField[1] = cMvFieldNeighbours[1 + 2*uiMergeCand];
2919      uiInterDir = uhInterDirNeighbours[uiMergeCand];
2920      uiMergeIndex = uiMergeCand;
2921    }
2922#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
2923    }
2924#endif
2925#if REF_IDX_ME_ZEROMV
2926    }
2927#endif
2928  }
2929}
2930
2931/** convert bi-pred merge candidates to uni-pred
2932 * \param pcCU
2933 * \param puIdx
2934 * \param mvFieldNeighbours
2935 * \param interDirNeighbours
2936 * \param numValidMergeCand
2937 * \returns Void
2938 */
2939Void TEncSearch::xRestrictBipredMergeCand( TComDataCU* pcCU, UInt puIdx, TComMvField* mvFieldNeighbours, UChar* interDirNeighbours, Int numValidMergeCand )
2940{
2941  if ( pcCU->isBipredRestriction(puIdx) )
2942  {
2943    for( UInt mergeCand = 0; mergeCand < numValidMergeCand; ++mergeCand )
2944    {
2945      if ( interDirNeighbours[mergeCand] == 3 )
2946      {
2947        interDirNeighbours[mergeCand] = 1;
2948        mvFieldNeighbours[(mergeCand << 1) + 1].setMvField(TComMv(0,0), -1);
2949      }
2950    }
2951  }
2952}
2953
2954//! search of the best candidate for inter prediction
2955#if SVC_EXTENSION
2956#if AMP_MRG
2957Bool TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseRes, Bool bUseMRG )
2958#else
2959Bool TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv, Bool bUseRes )
2960#endif
2961#else
2962#if AMP_MRG
2963Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseRes, Bool bUseMRG )
2964#else
2965Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv, Bool bUseRes )
2966#endif
2967#endif
2968{
2969  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
2970  {
2971    m_acYuvPred[i].clear();
2972  }
2973  m_cYuvPredTemp.clear();
2974  pcPredYuv->clear();
2975
2976  if ( !bUseRes )
2977  {
2978    pcResiYuv->clear();
2979  }
2980
2981  pcRecoYuv->clear();
2982
2983  TComMv       cMvSrchRngLT;
2984  TComMv       cMvSrchRngRB;
2985
2986  TComMv       cMvZero;
2987  TComMv       TempMv; //kolya
2988
2989  TComMv       cMv[2];
2990  TComMv       cMvBi[2];
2991  TComMv       cMvTemp[2][33];
2992
2993  Int          iNumPart    = pcCU->getNumPartitions();
2994  Int          iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
2995
2996  TComMv       cMvPred[2][33];
2997
2998  TComMv       cMvPredBi[2][33];
2999  Int          aaiMvpIdxBi[2][33];
3000
3001  Int          aaiMvpIdx[2][33];
3002  Int          aaiMvpNum[2][33];
3003
3004  AMVPInfo     aacAMVPInfo[2][33];
3005
3006  Int          iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
3007  Int          iRefIdxBi[2];
3008
3009  UInt         uiPartAddr;
3010  Int          iRoiWidth, iRoiHeight;
3011
3012  UInt         uiMbBits[3] = {1, 1, 0};
3013
3014  UInt         uiLastMode = 0;
3015  Int          iRefStart, iRefEnd;
3016
3017  PartSize     ePartSize = pcCU->getPartitionSize( 0 );
3018
3019  Int          bestBiPRefIdxL1 = 0;
3020  Int          bestBiPMvpL1 = 0;
3021  Distortion   biPDistTemp = std::numeric_limits<Distortion>::max();
3022
3023  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
3024  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
3025  Int numValidMergeCand = 0 ;
3026
3027  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3028  {
3029    Distortion   uiCost[2] = { std::numeric_limits<Distortion>::max(), std::numeric_limits<Distortion>::max() };
3030    Distortion   uiCostBi  =   std::numeric_limits<Distortion>::max();
3031    Distortion   uiCostTemp;
3032
3033    UInt         uiBits[3];
3034    UInt         uiBitsTemp;
3035    Distortion   bestBiPDist = std::numeric_limits<Distortion>::max();
3036
3037    Distortion   uiCostTempL0[MAX_NUM_REF];
3038    for (Int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++)
3039    {
3040      uiCostTempL0[iNumRef] = std::numeric_limits<Distortion>::max();
3041    }
3042    UInt         uiBitsTempL0[MAX_NUM_REF];
3043
3044    TComMv       mvValidList1;
3045    Int          refIdxValidList1 = 0;
3046    UInt         bitsValidList1 = MAX_UINT;
3047    Distortion   costValidList1 = std::numeric_limits<Distortion>::max();
3048
3049    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
3050
3051    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3052
3053#if AMP_MRG
3054    Bool bTestNormalMC = true;
3055
3056    if ( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 )
3057    {
3058      bTestNormalMC = false;
3059    }
3060
3061    if (bTestNormalMC)
3062    {
3063#endif
3064
3065#if SVC_EXTENSION
3066      Bool doneUniPred = false;
3067#endif
3068
3069    //  Uni-directional prediction
3070    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
3071    {
3072      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3073
3074      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
3075      {
3076#if SVC_EXTENSION
3077        TComPic* pcPic = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxTemp );
3078       
3079        // motion search only for the ILRP with sample prediction type
3080        if( pcPic->isILR( pcCU->getPic()->getLayerId() ) && !pcCU->getSlice()->getVPS()->isSamplePredictionType( pcCU->getPic()->getLayerIdx(), pcPic->getLayerIdx() ) )
3081        {
3082          continue;
3083        }
3084
3085#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3086        if( pcPic->isILR(pcCU->getPic()->getLayerId()) && m_disableILP )
3087        {
3088          continue;
3089        }
3090#endif
3091#if ENCODER_FAST_MODE       
3092        if( pcPic->isILR(pcCU->getPic()->getLayerId()) && (ePartSize == SIZE_2Nx2N) ) 
3093        {
3094          continue;
3095        }
3096#endif
3097        doneUniPred = true;
3098#endif
3099
3100        uiBitsTemp = uiMbBits[iRefList];
3101        if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3102        {
3103          uiBitsTemp += iRefIdxTemp+1;
3104          if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 )
3105          {
3106            uiBitsTemp--;
3107          }
3108        }
3109        xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
3110        aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
3111        aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
3112
3113        if(pcCU->getSlice()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
3114        {
3115#if REF_IDX_ME_ZEROMV
3116          Bool bZeroMVILR = pcCU->checkZeroMVILRMvdL1Zero(iRefList, iRefIdxTemp, aaiMvpIdx[iRefList][iRefIdxTemp]);
3117
3118          if( bZeroMVILR )
3119          {
3120#endif
3121          bestBiPDist = biPDistTemp;
3122          bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
3123          bestBiPRefIdxL1 = iRefIdxTemp;
3124#if REF_IDX_ME_ZEROMV
3125          }
3126#endif
3127        }
3128
3129        uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3130
3131        if ( m_pcEncCfg->getFastMEForGenBLowDelayEnabled() && iRefList == 1 )    // list 1
3132        {
3133          if ( pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 )
3134          {
3135            cMvTemp[1][iRefIdxTemp] = cMvTemp[0][pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3136            uiCostTemp = uiCostTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )];
3137            /*first subtract the bit-rate part of the cost of the other list*/
3138            uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp )] );
3139            /*correct the bit-rate part of the current ref*/
3140            m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
3141            uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
3142            /*calculate the correct cost*/
3143            uiCostTemp += m_pcRdCost->getCost( uiBitsTemp );
3144          }
3145          else
3146          {
3147            xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3148          }
3149        }
3150        else
3151        {
3152          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
3153        }
3154        xCopyAMVPInfo(pcCU->getCUMvField(eRefPicList)->getAMVPInfo(), &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
3155        xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3156
3157        if ( iRefList == 0 )
3158        {
3159          uiCostTempL0[iRefIdxTemp] = uiCostTemp;
3160          uiBitsTempL0[iRefIdxTemp] = uiBitsTemp;
3161        }
3162        if ( uiCostTemp < uiCost[iRefList] )
3163        {
3164          uiCost[iRefList] = uiCostTemp;
3165          uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction
3166
3167          // set motion
3168          cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3169          iRefIdx[iRefList] = iRefIdxTemp;
3170        }
3171
3172        if ( iRefList == 1 && uiCostTemp < costValidList1 && pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) < 0 )
3173        {
3174          costValidList1 = uiCostTemp;
3175          bitsValidList1 = uiBitsTemp;
3176
3177          // set motion
3178          mvValidList1     = cMvTemp[iRefList][iRefIdxTemp];
3179          refIdxValidList1 = iRefIdxTemp;
3180        }
3181      }
3182    }
3183
3184#if SVC_EXTENSION
3185    if( pcCU->getPic()->getLayerId() && !doneUniPred )
3186    {
3187      // there is no valid reference pictures for inter prediction
3188      return false;
3189    }
3190#endif
3191
3192    //  Bi-predictive Motion estimation
3193#if REF_IDX_ME_ZEROMV
3194    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) && !(pcCU->getSlice()->getMvdL1ZeroFlag() && bestBiPDist == MAX_INT) )
3195#else
3196    if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
3197#endif
3198    {
3199
3200      cMvBi[0] = cMv[0];            cMvBi[1] = cMv[1];
3201      iRefIdxBi[0] = iRefIdx[0];    iRefIdxBi[1] = iRefIdx[1];
3202
3203      ::memcpy(cMvPredBi, cMvPred, sizeof(cMvPred));
3204      ::memcpy(aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx));
3205
3206      UInt uiMotBits[2];
3207
3208      if(pcCU->getSlice()->getMvdL1ZeroFlag())
3209      {
3210        xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3211        pcCU->setMVPIdxSubParts( bestBiPMvpL1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3212        aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1;
3213        cMvPredBi[1][bestBiPRefIdxL1]   = pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo()->m_acMvCand[bestBiPMvpL1];
3214
3215        cMvBi[1] = cMvPredBi[1][bestBiPRefIdxL1];
3216        iRefIdxBi[1] = bestBiPRefIdxL1;
3217        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3218        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3219        TComYuv* pcYuvPred = &m_acYuvPred[REF_PIC_LIST_1];
3220        motionCompensation( pcCU, pcYuvPred, REF_PIC_LIST_1, iPartIdx );
3221
3222        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3223        uiMotBits[1] = uiMbBits[1];
3224
3225        if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 1 )
3226        {
3227          uiMotBits[1] += bestBiPRefIdxL1+1;
3228          if ( bestBiPRefIdxL1 == pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1)-1 )
3229          {
3230            uiMotBits[1]--;
3231          }
3232        }
3233
3234        uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS];
3235
3236        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3237
3238        cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1];
3239      }
3240      else
3241      {
3242        uiMotBits[0] = uiBits[0] - uiMbBits[0];
3243        uiMotBits[1] = uiBits[1] - uiMbBits[1];
3244        uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
3245      }
3246
3247      // 4-times iteration (default)
3248      Int iNumIter = 4;
3249
3250      // fast encoder setting: only one iteration
3251      if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || pcCU->getSlice()->getMvdL1ZeroFlag() )
3252      {
3253        iNumIter = 1;
3254      }
3255
3256      for ( Int iIter = 0; iIter < iNumIter; iIter++ )
3257      {
3258        Int         iRefList    = iIter % 2;
3259
3260        if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 )
3261        {
3262          if( uiCost[0] <= uiCost[1] )
3263          {
3264            iRefList = 1;
3265          }
3266          else
3267          {
3268            iRefList = 0;
3269          }
3270        }
3271        else if ( iIter == 0 )
3272        {
3273          iRefList = 0;
3274        }
3275        if ( iIter == 0 && !pcCU->getSlice()->getMvdL1ZeroFlag())
3276        {
3277          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllMv( cMv[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3278          pcCU->getCUMvField(RefPicList(1-iRefList))->setAllRefIdx( iRefIdx[1-iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3279          TComYuv*  pcYuvPred = &m_acYuvPred[1-iRefList];
3280          motionCompensation ( pcCU, pcYuvPred, RefPicList(1-iRefList), iPartIdx );
3281        }
3282
3283        RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
3284
3285        if(pcCU->getSlice()->getMvdL1ZeroFlag())
3286        {
3287          iRefList = 0;
3288          eRefPicList = REF_PIC_LIST_0;
3289        }
3290
3291        Bool bChanged = false;
3292
3293#if ENCODER_FAST_MODE
3294        Bool     testIter = true;
3295        TComPic* pcPic    = pcCU->getSlice()->getRefPic( RefPicList(1 - iRefList), iRefIdxBi[1 - iRefList] );
3296        if(pcPic->isILR(pcCU->getPic()->getLayerId()) && (ePartSize == SIZE_2Nx2N))
3297        {
3298          testIter = false;  //the fixed part is ILR, skip this iteration       
3299        }
3300#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3301        if (pcPic->isILR(pcCU->getPic()->getLayerId()) && m_disableILP)
3302        {
3303          testIter = false;
3304        }
3305#endif
3306        if(testIter)
3307        {
3308#endif
3309        iRefStart = 0;
3310        iRefEnd   = pcCU->getSlice()->getNumRefIdx(eRefPicList)-1;
3311
3312        for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
3313        {
3314#if ENCODER_FAST_MODE
3315          Bool testRefIdx = true;
3316          pcPic = pcCU->getSlice()->getRefPic( RefPicList(iRefList) , iRefIdxTemp );
3317
3318          // motion search only for the ILRP with sample prediction type
3319          if( pcPic->isILR( pcCU->getPic()->getLayerId() ) && !pcCU->getSlice()->getVPS()->isSamplePredictionType( pcCU->getPic()->getLayerIdx(), pcPic->getLayerIdx() ) )
3320          {
3321            continue;
3322          }
3323
3324          if(pcPic->isILR(pcCU->getPic()->getLayerId()) && (ePartSize == SIZE_2Nx2N))
3325          {
3326            testRefIdx = false;  //the refined part is ILR, skip this reference pic           
3327          }
3328#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3329          if (pcPic->isILR(pcCU->getPic()->getLayerId()) && m_disableILP)
3330          {
3331            testRefIdx = false;
3332          }
3333#endif
3334          if(testRefIdx)
3335          {
3336#endif
3337          uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList];
3338          if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 )
3339          {
3340            uiBitsTemp += iRefIdxTemp+1;
3341            if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 )
3342            {
3343              uiBitsTemp--;
3344            }
3345          }
3346          uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
3347          // call ME
3348          xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
3349
3350          xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], pcCU->getCUMvField(eRefPicList)->getAMVPInfo());
3351          xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
3352
3353          if ( uiCostTemp < uiCostBi )
3354          {
3355            bChanged = true;
3356
3357            cMvBi[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
3358            iRefIdxBi[iRefList] = iRefIdxTemp;
3359
3360            uiCostBi            = uiCostTemp;
3361            uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList];
3362            uiBits[2]           = uiBitsTemp;
3363
3364            if(iNumIter!=1)
3365            {
3366              //  Set motion
3367              pcCU->getCUMvField( eRefPicList )->setAllMv( cMvBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3368              pcCU->getCUMvField( eRefPicList )->setAllRefIdx( iRefIdxBi[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
3369
3370              TComYuv* pcYuvPred = &m_acYuvPred[iRefList];
3371              motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
3372            }
3373          }
3374#if ENCODER_FAST_MODE
3375          }
3376#endif
3377        }
3378#if ENCODER_FAST_MODE
3379        } // for loop-iRefIdxTemp
3380#endif
3381 
3382        if ( !bChanged )
3383        {
3384          if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] )
3385          {
3386            xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], pcCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
3387            xCheckBestMVP(pcCU, REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi);
3388            if(!pcCU->getSlice()->getMvdL1ZeroFlag())
3389            {
3390              xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], pcCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
3391              xCheckBestMVP(pcCU, REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi);
3392            }
3393          }
3394          break;
3395        }
3396      } // for loop-iter
3397    } // if (B_SLICE)
3398
3399#if AMP_MRG
3400    } //end if bTestNormalMC
3401#endif
3402    //  Clear Motion Field
3403    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3404    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx );
3405    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3406    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,       ePartSize, uiPartAddr, 0, iPartIdx );
3407
3408    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3409    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3410    pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3411    pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3412
3413    UInt uiMEBits = 0;
3414    // Set Motion Field_
3415    cMv[1] = mvValidList1;
3416    iRefIdx[1] = refIdxValidList1;
3417    uiBits[1] = bitsValidList1;
3418    uiCost[1] = costValidList1;
3419
3420#if AMP_MRG
3421    if (bTestNormalMC)
3422    {
3423#endif
3424    if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1])
3425    {
3426      uiLastMode = 2;
3427      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMvBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3428      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdxBi[0], ePartSize, uiPartAddr, 0, iPartIdx );
3429      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMvBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3430      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdxBi[1], ePartSize, uiPartAddr, 0, iPartIdx );
3431
3432      TempMv = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]];
3433      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3434
3435      TempMv = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]];
3436      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3437
3438      pcCU->setInterDirSubParts( 3, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3439
3440      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3441      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdxBi[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3442      pcCU->setMVPIdxSubParts( aaiMvpIdxBi[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3443      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdxBi[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3444
3445      uiMEBits = uiBits[2];
3446    }
3447    else if ( uiCost[0] <= uiCost[1] )
3448    {
3449      uiLastMode = 0;
3450      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
3451      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
3452
3453      TempMv = cMv[0] - cMvPred[0][iRefIdx[0]];
3454      pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3455
3456      pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3457
3458      pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3459      pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3460
3461      uiMEBits = uiBits[0];
3462    }
3463    else
3464    {
3465      uiLastMode = 1;
3466      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
3467      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
3468
3469      TempMv = cMv[1] - cMvPred[1][iRefIdx[1]];
3470      pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TempMv,                 ePartSize, uiPartAddr, 0, iPartIdx );
3471
3472      pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
3473
3474      pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3475      pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3476
3477      uiMEBits = uiBits[1];
3478    }
3479#if AMP_MRG
3480    } // end if bTestNormalMC
3481#endif
3482
3483    if ( pcCU->getPartitionSize( uiPartAddr ) != SIZE_2Nx2N )
3484    {
3485      UInt uiMRGInterDir = 0;
3486      TComMvField cMRGMvField[2];
3487      UInt uiMRGIndex = 0;
3488
3489      UInt uiMEInterDir = 0;
3490      TComMvField cMEMvField[2];
3491
3492      m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
3493
3494#if AMP_MRG
3495      // calculate ME cost
3496      Distortion uiMEError = std::numeric_limits<Distortion>::max();
3497      Distortion uiMECost  = std::numeric_limits<Distortion>::max();
3498
3499      if (bTestNormalMC)
3500      {
3501        xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3502        uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3503      }
3504#else
3505      // calculate ME cost
3506      Distortion uiMEError = std::numeric_limits<Distortion>::max();
3507      xGetInterPredictionError( pcCU, pcOrgYuv, iPartIdx, uiMEError, m_pcEncCfg->getUseHADME() );
3508      Distortion uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits );
3509#endif
3510      // save ME result.
3511      uiMEInterDir = pcCU->getInterDir( uiPartAddr );
3512      TComDataCU::getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
3513      TComDataCU::getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
3514
3515      // find Merge result
3516      Distortion uiMRGCost = std::numeric_limits<Distortion>::max();
3517
3518      xMergeEstimation( pcCU, pcOrgYuv, iPartIdx, uiMRGInterDir, cMRGMvField, uiMRGIndex, uiMRGCost, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand);
3519
3520      if ( uiMRGCost < uiMECost )
3521      {
3522        // set Merge result
3523        pcCU->setMergeFlagSubParts ( true,          uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3524        pcCU->setMergeIndexSubParts( uiMRGIndex,    uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3525        pcCU->setInterDirSubParts  ( uiMRGInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3526        pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMRGMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3527        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMRGMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3528
3529        pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3530        pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( cMvZero,            ePartSize, uiPartAddr, 0, iPartIdx );
3531
3532        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3533        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3534        pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3535        pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
3536      }
3537      else
3538      {
3539        // set ME result
3540        pcCU->setMergeFlagSubParts( false,        uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3541        pcCU->setInterDirSubParts ( uiMEInterDir, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
3542        pcCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMEMvField[0], ePartSize, uiPartAddr, 0, iPartIdx );
3543        pcCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMEMvField[1], ePartSize, uiPartAddr, 0, iPartIdx );
3544      }
3545    }
3546
3547    //  MC
3548    motionCompensation ( pcCU, pcPredYuv, REF_PIC_LIST_X, iPartIdx );
3549
3550  } //  end of for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )
3551
3552  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
3553
3554#if SVC_EXTENSION
3555  return true;
3556#else
3557  return;
3558#endif
3559}
3560
3561
3562// AMVP
3563Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, Distortion* puiDistBiP )
3564{
3565  AMVPInfo*  pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3566
3567  TComMv     cBestMv;
3568  Int        iBestIdx   = 0;
3569  TComMv     cZeroMv;
3570  TComMv     cMvPred;
3571  Distortion uiBestCost = std::numeric_limits<Distortion>::max();
3572  UInt       uiPartAddr = 0;
3573  Int        iRoiWidth, iRoiHeight;
3574  Int        i;
3575
3576  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3577  // Fill the MV Candidates
3578  if (!bFilled)
3579  {
3580    pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
3581  }
3582
3583  // initialize Mvp index & Mvp
3584  iBestIdx = 0;
3585  cBestMv  = pcAMVPInfo->m_acMvCand[0];
3586  if (pcAMVPInfo->iN <= 1)
3587  {
3588    rcMvPred = cBestMv;
3589
3590    pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3591    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3592
3593    if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefPicList==REF_PIC_LIST_1)
3594    {
3595      (*puiDistBiP) = xGetTemplateCost( pcCU, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, rcMvPred, 0, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3596    }
3597    return;
3598  }
3599
3600  if (bFilled)
3601  {
3602    assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
3603    rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
3604    return;
3605  }
3606
3607  m_cYuvPredTemp.clear();
3608  //-- Check Minimum Cost.
3609  for ( i = 0 ; i < pcAMVPInfo->iN; i++)
3610  {
3611    Distortion uiTmpCost;
3612    uiTmpCost = xGetTemplateCost( pcCU, uiPartAddr, pcOrgYuv, &m_cYuvPredTemp, pcAMVPInfo->m_acMvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx, iRoiWidth, iRoiHeight);
3613    if ( uiBestCost > uiTmpCost )
3614    {
3615      uiBestCost = uiTmpCost;
3616      cBestMv   = pcAMVPInfo->m_acMvCand[i];
3617      iBestIdx  = i;
3618      (*puiDistBiP) = uiTmpCost;
3619    }
3620  }
3621
3622  m_cYuvPredTemp.clear();
3623
3624  // Setting Best MVP
3625  rcMvPred = cBestMv;
3626  pcCU->setMVPIdxSubParts( iBestIdx, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3627  pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
3628  return;
3629}
3630
3631UInt TEncSearch::xGetMvpIdxBits(Int iIdx, Int iNum)
3632{
3633  assert(iIdx >= 0 && iNum >= 0 && iIdx < iNum);
3634
3635  if (iNum == 1)
3636  {
3637    return 0;
3638  }
3639
3640  UInt uiLength = 1;
3641  Int iTemp = iIdx;
3642  if ( iTemp == 0 )
3643  {
3644    return uiLength;
3645  }
3646
3647  Bool bCodeLast = ( iNum-1 > iTemp );
3648
3649  uiLength += (iTemp-1);
3650
3651  if( bCodeLast )
3652  {
3653    uiLength++;
3654  }
3655
3656  return uiLength;
3657}
3658
3659Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bPSlice, Int iPartIdx, UInt uiLastMode, UInt uiBlkBit[3])
3660{
3661  if ( eCUMode == SIZE_2Nx2N )
3662  {
3663    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3664    uiBlkBit[1] = 3;
3665    uiBlkBit[2] = 5;
3666  }
3667  else if ( (eCUMode == SIZE_2NxN || eCUMode == SIZE_2NxnU) || eCUMode == SIZE_2NxnD )
3668  {
3669    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} } };
3670    if ( bPSlice )
3671    {
3672      uiBlkBit[0] = 3;
3673      uiBlkBit[1] = 0;
3674      uiBlkBit[2] = 0;
3675    }
3676    else
3677    {
3678      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3679    }
3680  }
3681  else if ( (eCUMode == SIZE_Nx2N || eCUMode == SIZE_nLx2N) || eCUMode == SIZE_nRx2N )
3682  {
3683    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} } };
3684    if ( bPSlice )
3685    {
3686      uiBlkBit[0] = 3;
3687      uiBlkBit[1] = 0;
3688      uiBlkBit[2] = 0;
3689    }
3690    else
3691    {
3692      ::memcpy( uiBlkBit, aauiMbBits[iPartIdx][uiLastMode], 3*sizeof(UInt) );
3693    }
3694  }
3695  else if ( eCUMode == SIZE_NxN )
3696  {
3697    uiBlkBit[0] = (! bPSlice) ? 3 : 1;
3698    uiBlkBit[1] = 3;
3699    uiBlkBit[2] = 5;
3700  }
3701  else
3702  {
3703    printf("Wrong!\n");
3704    assert( 0 );
3705  }
3706}
3707
3708Void TEncSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
3709{
3710  pDst->iN = pSrc->iN;
3711  for (Int i = 0; i < pSrc->iN; i++)
3712  {
3713    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
3714  }
3715}
3716
3717Void TEncSearch::xCheckBestMVP ( TComDataCU* pcCU, RefPicList eRefPicList, TComMv cMv, TComMv& rcMvPred, Int& riMVPIdx, UInt& ruiBits, Distortion& ruiCost )
3718{
3719  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
3720
3721  assert(pcAMVPInfo->m_acMvCand[riMVPIdx] == rcMvPred);
3722
3723  if (pcAMVPInfo->iN < 2)
3724  {
3725    return;
3726  }
3727
3728  m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(0) );
3729  m_pcRdCost->setCostScale ( 0    );
3730
3731  Int iBestMVPIdx = riMVPIdx;
3732
3733  m_pcRdCost->setPredictor( rcMvPred );
3734  Int iOrgMvBits  = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer());
3735  iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
3736  Int iBestMvBits = iOrgMvBits;
3737
3738  for (Int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->iN; iMVPIdx++)
3739  {
3740    if (iMVPIdx == riMVPIdx)
3741    {
3742      continue;
3743    }
3744
3745    m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
3746
3747    Int iMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer());
3748    iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
3749
3750    if (iMvBits < iBestMvBits)
3751    {
3752      iBestMvBits = iMvBits;
3753      iBestMVPIdx = iMVPIdx;
3754    }
3755  }
3756
3757  if (iBestMVPIdx != riMVPIdx)  //if changed
3758  {
3759    rcMvPred = pcAMVPInfo->m_acMvCand[iBestMVPIdx];
3760
3761    riMVPIdx = iBestMVPIdx;
3762    UInt uiOrgBits = ruiBits;
3763    ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits;
3764    ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits ))  + m_pcRdCost->getCost( ruiBits );
3765  }
3766}
3767
3768
3769Distortion TEncSearch::xGetTemplateCost( TComDataCU* pcCU,
3770                                         UInt        uiPartAddr,
3771                                         TComYuv*    pcOrgYuv,
3772                                         TComYuv*    pcTemplateCand,
3773                                         TComMv      cMvCand,
3774                                         Int         iMVPIdx,
3775                                         Int         iMVPNum,
3776                                         RefPicList  eRefPicList,
3777                                         Int         iRefIdx,
3778                                         Int         iSizeX,
3779                                         Int         iSizeY
3780                                         )
3781{
3782  Distortion uiCost = std::numeric_limits<Distortion>::max();
3783
3784  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
3785
3786  pcCU->clipMv( cMvCand );
3787
3788  // prediction pattern
3789#if SVC_EXTENSION
3790  // Check WP for B-slices
3791  if( pcCU->getSlice()->testWeightPred() )
3792#else
3793  if ( pcCU->getSlice()->testWeightPred() && pcCU->getSlice()->getSliceType()==P_SLICE )
3794#endif
3795  {
3796    xPredInterBlk( COMPONENT_Y, pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, true, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) );
3797  }
3798  else
3799  {
3800    xPredInterBlk( COMPONENT_Y, pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false, pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) );
3801  }
3802
3803#if SVC_EXTENSION
3804  // Check WP for B-slices
3805  if ( pcCU->getSlice()->testWeightPred() )
3806#else
3807  if ( pcCU->getSlice()->testWeightPred() && pcCU->getSlice()->getSliceType()==P_SLICE )
3808#endif
3809  {
3810    xWeightedPredictionUni( pcCU, pcTemplateCand, uiPartAddr, iSizeX, iSizeY, eRefPicList, pcTemplateCand, iRefIdx );
3811  }
3812
3813  // calc distortion
3814
3815  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 );
3816  uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, DF_SAD );
3817  return uiCost;
3818}
3819
3820
3821Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, Distortion& ruiCost, Bool bBi  )
3822{
3823  UInt          uiPartAddr;
3824  Int           iRoiWidth;
3825  Int           iRoiHeight;
3826
3827  TComMv        cMvHalf, cMvQter;
3828  TComMv        cMvSrchRngLT;
3829  TComMv        cMvSrchRngRB;
3830
3831  TComYuv*      pcYuv = pcYuvOrg;
3832
3833  assert(eRefPicList < MAX_NUM_REF_LIST_ADAPT_SR && iRefIdxPred<Int(MAX_IDX_ADAPT_SR));
3834  m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred];
3835
3836  Int           iSrchRng      = ( bBi ? m_bipredSearchRange : m_iSearchRange );
3837  TComPattern   tmpPattern;
3838  TComPattern*  pcPatternKey  = &tmpPattern;
3839
3840  Double        fWeight       = 1.0;
3841
3842  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
3843
3844  if ( bBi ) // Bipredictive ME
3845  {
3846    TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
3847    pcYuv                = &m_cYuvPredTemp;
3848
3849    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
3850
3851    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled() );
3852
3853    fWeight = 0.5;
3854  }
3855  m_cDistParam.bIsBiPred = bBi;
3856
3857  //  Search key pattern initialization
3858  pcPatternKey->initPattern( pcYuv->getAddr  ( COMPONENT_Y, uiPartAddr ),
3859                             iRoiWidth,
3860                             iRoiHeight,
3861                             pcYuv->getStride(COMPONENT_Y),
3862                             pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) );
3863
3864  Pel*        piRefY      = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getAddr( COMPONENT_Y, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu() + uiPartAddr );
3865  Int         iRefStride  = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride(COMPONENT_Y);
3866
3867  TComMv      cMvPred = *pcMvPred;
3868#if VIEW_SCALABILITY
3869  m_vertRestriction = m_pcEncCfg->getUseDisparitySearchRangeRestriction() && pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPOC() == pcCU->getSlice()->getPOC();
3870#endif
3871  if ( bBi )
3872  {
3873    xSetSearchRange   ( pcCU, rcMv   , iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3874  }
3875  else
3876  {
3877    xSetSearchRange   ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
3878  }
3879
3880  m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
3881
3882  m_pcRdCost->setPredictor  ( *pcMvPred );
3883  m_pcRdCost->setCostScale  ( 2 );
3884
3885  setWpScalingDistParam( pcCU, iRefIdxPred, eRefPicList );
3886  //  Do integer search
3887#if REF_IDX_ME_ZEROMV
3888  //scalable layer
3889  if( pcCU->getSlice()->getVPS()->getScalabilityMask( SCALABILITY_ID ) && pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->isILR(pcCU->getPic()->getLayerId()) )  //ILR reference pic
3890  {
3891    rcMv.setZero();  //use Mv(0, 0) for integer ME
3892  }
3893  else  //non ILR reference pic
3894  {
3895#endif
3896   
3897  if ( (m_motionEstimationSearchMethod==MESEARCH_FULL) || bBi )
3898  {
3899    xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
3900  }
3901  else
3902  {
3903    rcMv = *pcMvPred;
3904    const TComMv *pIntegerMv2Nx2NPred=0;
3905    if (pcCU->getPartitionSize(0) != SIZE_2Nx2N || pcCU->getDepth(0) != 0)
3906    {
3907      pIntegerMv2Nx2NPred = &(m_integerMv2Nx2N[eRefPicList][iRefIdxPred]);
3908    }
3909    xPatternSearchFast  ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost, pIntegerMv2Nx2NPred );
3910    if (pcCU->getPartitionSize(0) == SIZE_2Nx2N)
3911    {
3912      m_integerMv2Nx2N[eRefPicList][iRefIdxPred] = rcMv;
3913    }
3914  }
3915#if REF_IDX_ME_ZEROMV
3916  }
3917#endif
3918
3919  m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
3920  m_pcRdCost->setCostScale ( 1 );
3921
3922  const Bool bIsLosslessCoded = pcCU->getCUTransquantBypass(uiPartAddr) != 0;
3923
3924#if REF_IDX_ME_ZEROMV
3925  //scalable layer
3926  if( pcCU->getSlice()->getVPS()->getScalabilityMask( SCALABILITY_ID ) && pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->isILR(pcCU->getPic()->getLayerId()))  //ILR reference pic
3927  {
3928    xPatternSearchFracDIFMv0( pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
3929  }
3930  else    //non ILR reference pic
3931#endif
3932  xPatternSearchFracDIF( bIsLosslessCoded, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost );
3933
3934  m_pcRdCost->setCostScale( 0 );
3935  rcMv <<= 2;
3936  rcMv += (cMvHalf <<= 1);
3937  rcMv +=  cMvQter;
3938
3939  UInt uiMvBits = m_pcRdCost->getBitsOfVectorWithPredictor( rcMv.getHor(), rcMv.getVer() );
3940
3941  ruiBits      += uiMvBits;
3942  ruiCost       = (Distortion)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
3943}
3944
3945
3946Void TEncSearch::xSetSearchRange ( const TComDataCU* const pcCU, const TComMv& cMvPred, const Int iSrchRng,
3947                                   TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
3948{
3949  Int  iMvShift = 2;
3950  TComMv cTmpMvPred = cMvPred;
3951  pcCU->clipMv( cTmpMvPred );
3952
3953  rcMvSrchRngLT.setHor( cTmpMvPred.getHor() - (iSrchRng << iMvShift) );
3954  rcMvSrchRngLT.setVer( cTmpMvPred.getVer() - (iSrchRng << iMvShift) );
3955
3956  rcMvSrchRngRB.setHor( cTmpMvPred.getHor() + (iSrchRng << iMvShift) );
3957  rcMvSrchRngRB.setVer( cTmpMvPred.getVer() + (iSrchRng << iMvShift) );
3958#if VIEW_SCALABILITY
3959  if( m_vertRestriction )
3960  {
3961    Int mvRestricted = ( 56 - 1 ) << iMvShift ; // -1 to consider subpel search
3962    if( rcMvSrchRngRB.getVer() > mvRestricted )
3963    {
3964      rcMvSrchRngRB.setVer( mvRestricted );
3965    }
3966  }
3967#endif
3968  pcCU->clipMv        ( rcMvSrchRngLT );
3969  pcCU->clipMv        ( rcMvSrchRngRB );
3970
3971#if ME_ENABLE_ROUNDING_OF_MVS
3972  rcMvSrchRngLT.divideByPowerOf2(iMvShift);
3973  rcMvSrchRngRB.divideByPowerOf2(iMvShift);
3974#else
3975  rcMvSrchRngLT >>= iMvShift;
3976  rcMvSrchRngRB >>= iMvShift;
3977#endif
3978}
3979
3980
3981Void TEncSearch::xPatternSearch( const TComPattern* const pcPatternKey,
3982                                 const Pel*               piRefY,
3983                                 const Int                iRefStride,
3984                                 const TComMv* const      pcMvSrchRngLT,
3985                                 const TComMv* const      pcMvSrchRngRB,
3986                                 TComMv&      rcMv,
3987                                 Distortion&  ruiSAD )
3988{
3989  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
3990  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
3991  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
3992  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
3993
3994  Distortion  uiSad;
3995  Distortion  uiSadBest = std::numeric_limits<Distortion>::max();
3996  Int         iBestX = 0;
3997  Int         iBestY = 0;
3998
3999  //-- jclee for using the SAD function pointer
4000  m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
4001
4002  // fast encoder decision: use subsampled SAD for integer ME
4003  if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE3 )
4004  {
4005    if ( m_cDistParam.iRows > 8 )
4006    {
4007      m_cDistParam.iSubShift = 1;
4008    }
4009  }
4010
4011  piRefY += (iSrchRngVerTop * iRefStride);
4012  for ( Int y = iSrchRngVerTop; y <= iSrchRngVerBottom; y++ )
4013  {
4014    for ( Int x = iSrchRngHorLeft; x <= iSrchRngHorRight; x++ )
4015    {
4016      //  find min. distortion position
4017      m_cDistParam.pCur = piRefY + x;
4018
4019      setDistParamComp(COMPONENT_Y);
4020
4021      m_cDistParam.bitDepth = pcPatternKey->getBitDepthY();
4022      uiSad = m_cDistParam.DistFunc( &m_cDistParam );
4023
4024      // motion cost
4025      uiSad += m_pcRdCost->getCostOfVectorWithPredictor( x, y );
4026
4027      if ( uiSad < uiSadBest )
4028      {
4029        uiSadBest = uiSad;
4030        iBestX    = x;
4031        iBestY    = y;
4032        m_cDistParam.m_maximumDistortionForEarlyExit = uiSad;
4033      }
4034    }
4035    piRefY += iRefStride;
4036  }
4037
4038  rcMv.set( iBestX, iBestY );
4039
4040  ruiSAD = uiSadBest - m_pcRdCost->getCostOfVectorWithPredictor( iBestX, iBestY );
4041  return;
4042}
4043
4044
4045Void TEncSearch::xPatternSearchFast( const TComDataCU* const  pcCU,
4046                                     const TComPattern* const pcPatternKey,
4047                                     const Pel* const         piRefY,
4048                                     const Int                iRefStride,
4049                                     const TComMv* const      pcMvSrchRngLT,
4050                                     const TComMv* const      pcMvSrchRngRB,
4051                                     TComMv&                  rcMv,
4052                                     Distortion&              ruiSAD,
4053                                     const TComMv* const      pIntegerMv2Nx2NPred )
4054{
4055  assert (MD_LEFT < NUM_MV_PREDICTORS);
4056  pcCU->getMvPredLeft       ( m_acMvPredictors[MD_LEFT] );
4057  assert (MD_ABOVE < NUM_MV_PREDICTORS);
4058  pcCU->getMvPredAbove      ( m_acMvPredictors[MD_ABOVE] );
4059  assert (MD_ABOVE_RIGHT < NUM_MV_PREDICTORS);
4060  pcCU->getMvPredAboveRight ( m_acMvPredictors[MD_ABOVE_RIGHT] );
4061
4062  switch ( m_motionEstimationSearchMethod )
4063  {
4064    case MESEARCH_DIAMOND:
4065      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred, false );
4066      break;
4067
4068    case MESEARCH_SELECTIVE:
4069      xTZSearchSelective( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred );
4070      break;
4071
4072    case MESEARCH_DIAMOND_ENHANCED:
4073      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred, true );
4074      break;
4075
4076    case MESEARCH_FULL: // shouldn't get here.
4077    default:
4078      break;
4079  }
4080}
4081
4082
4083Void TEncSearch::xTZSearch( const TComDataCU* const pcCU,
4084                            const TComPattern* const pcPatternKey,
4085                            const Pel* const         piRefY,
4086                            const Int                iRefStride,
4087                            const TComMv* const      pcMvSrchRngLT,
4088                            const TComMv* const      pcMvSrchRngRB,
4089                            TComMv&                  rcMv,
4090                            Distortion&              ruiSAD,
4091                            const TComMv* const      pIntegerMv2Nx2NPred,
4092                            const Bool               bExtendedSettings)
4093{
4094  const Bool bUseAdaptiveRaster                      = bExtendedSettings;
4095  const Int  iRaster                                 = 5;
4096  const Bool bTestOtherPredictedMV                   = bExtendedSettings;
4097  const Bool bTestZeroVector                         = true;
4098  const Bool bTestZeroVectorStart                    = bExtendedSettings;
4099  const Bool bTestZeroVectorStop                     = false;
4100  const Bool bFirstSearchDiamond                     = true;  // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
4101  const Bool bFirstCornersForDiamondDist1            = bExtendedSettings;
4102  const Bool bFirstSearchStop                        = m_pcEncCfg->getFastMEAssumingSmootherMVEnabled();
4103  const UInt uiFirstSearchRounds                     = 3;     // first search stop X rounds after best match (must be >=1)
4104  const Bool bEnableRasterSearch                     = true;
4105  const Bool bAlwaysRasterSearch                     = bExtendedSettings;  // true: BETTER but factor 2 slower
4106  const Bool bRasterRefinementEnable                 = false; // enable either raster refinement or star refinement
4107  const Bool bRasterRefinementDiamond                = false; // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
4108  const Bool bRasterRefinementCornersForDiamondDist1 = bExtendedSettings;
4109  const Bool bStarRefinementEnable                   = true;  // enable either star refinement or raster refinement
4110  const Bool bStarRefinementDiamond                  = true;  // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
4111  const Bool bStarRefinementCornersForDiamondDist1   = bExtendedSettings;
4112  const Bool bStarRefinementStop                     = false;
4113  const UInt uiStarRefinementRounds                  = 2;  // star refinement stop X rounds after best match (must be >=1)
4114  const Bool bNewZeroNeighbourhoodTest               = bExtendedSettings;
4115
4116  UInt uiSearchRange = m_iSearchRange;
4117  pcCU->clipMv( rcMv );
4118#if ME_ENABLE_ROUNDING_OF_MVS
4119  rcMv.divideByPowerOf2(2);
4120#else
4121  rcMv >>= 2;
4122#endif
4123  // init TZSearchStruct
4124  IntTZSearchStruct cStruct;
4125  cStruct.iYStride    = iRefStride;
4126  cStruct.piRefY      = piRefY;
4127  cStruct.uiBestSad   = MAX_UINT;
4128
4129  // set rcMv (Median predictor) as start point and as best point
4130  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4131
4132  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4133  if ( bTestOtherPredictedMV )
4134  {
4135    for ( UInt index = 0; index < NUM_MV_PREDICTORS; index++ )
4136    {
4137      TComMv cMv = m_acMvPredictors[index];
4138      pcCU->clipMv( cMv );
4139#if ME_ENABLE_ROUNDING_OF_MVS
4140      cMv.divideByPowerOf2(2);
4141#else
4142      cMv >>= 2;
4143#endif
4144      if (cMv != rcMv && (cMv.getHor() != cStruct.iBestX && cMv.getVer() != cStruct.iBestY))
4145      {
4146        // only test cMV if not obviously previously tested.
4147        xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4148      }
4149    }
4150  }
4151
4152  // test whether zero Mv is better start point than Median predictor
4153  if ( bTestZeroVector )
4154  {
4155    if ((rcMv.getHor() != 0 || rcMv.getVer() != 0) &&
4156        (0 != cStruct.iBestX || 0 != cStruct.iBestY))
4157    {
4158      // only test 0-vector if not obviously previously tested.
4159      xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4160    }
4161  }
4162
4163  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
4164  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
4165  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
4166  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
4167
4168  if (pIntegerMv2Nx2NPred != 0)
4169  {
4170    TComMv integerMv2Nx2NPred = *pIntegerMv2Nx2NPred;
4171    integerMv2Nx2NPred <<= 2;
4172    pcCU->clipMv( integerMv2Nx2NPred );
4173#if ME_ENABLE_ROUNDING_OF_MVS
4174    integerMv2Nx2NPred.divideByPowerOf2(2);
4175#else
4176    integerMv2Nx2NPred >>= 2;
4177#endif
4178    if ((rcMv != integerMv2Nx2NPred) &&
4179        (integerMv2Nx2NPred.getHor() != cStruct.iBestX || integerMv2Nx2NPred.getVer() != cStruct.iBestY))
4180    {
4181      // only test integerMv2Nx2NPred if not obviously previously tested.
4182      xTZSearchHelp(pcPatternKey, cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
4183    }
4184
4185    // reset search range
4186    TComMv cMvSrchRngLT;
4187    TComMv cMvSrchRngRB;
4188    Int iSrchRng = m_iSearchRange;
4189    TComMv currBestMv(cStruct.iBestX, cStruct.iBestY );
4190    currBestMv <<= 2;
4191    xSetSearchRange( pcCU, currBestMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4192    iSrchRngHorLeft   = cMvSrchRngLT.getHor();
4193    iSrchRngHorRight  = cMvSrchRngRB.getHor();
4194    iSrchRngVerTop    = cMvSrchRngLT.getVer();
4195    iSrchRngVerBottom = cMvSrchRngRB.getVer();
4196  }
4197
4198  // start search
4199  Int  iDist = 0;
4200  Int  iStartX = cStruct.iBestX;
4201  Int  iStartY = cStruct.iBestY;
4202
4203  const Bool bBestCandidateZero = (cStruct.iBestX == 0) && (cStruct.iBestY == 0);
4204
4205  // first search around best position up to now.
4206  // The following works as a "subsampled/log" window search around the best candidate
4207  for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4208  {
4209    if ( bFirstSearchDiamond == 1 )
4210    {
4211      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, bFirstCornersForDiamondDist1 );
4212    }
4213    else
4214    {
4215      xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4216    }
4217
4218    if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion
4219    {
4220      break;
4221    }
4222  }
4223
4224  if (!bNewZeroNeighbourhoodTest)
4225  {
4226    // test whether zero Mv is a better start point than Median predictor
4227    if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
4228    {
4229      xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4230      if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) )
4231      {
4232        // test its neighborhood
4233        for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
4234        {
4235          xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist, false );
4236          if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
4237          {
4238            break;
4239          }
4240        }
4241      }
4242    }
4243  }
4244  else
4245  {
4246    // Test also zero neighbourhood but with half the range
4247    // It was reported that the original (above) search scheme using bTestZeroVectorStart did not
4248    // make sense since one would have already checked the zero candidate earlier
4249    // and thus the conditions for that test would have not been satisfied
4250    if (bTestZeroVectorStart == true && bBestCandidateZero != true)
4251    {
4252      for ( iDist = 1; iDist <= ((Int)uiSearchRange >> 1); iDist*=2 )
4253      {
4254        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist, false );
4255        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 2) ) // stop criterion
4256        {
4257          break;
4258        }
4259      }
4260    }
4261  }
4262
4263  // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4264  if ( cStruct.uiBestDistance == 1 )
4265  {
4266    cStruct.uiBestDistance = 0;
4267    xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4268  }
4269
4270  // raster search if distance is too big
4271  if (bUseAdaptiveRaster)
4272  {
4273    int iWindowSize = iRaster;
4274    Int   iSrchRngRasterLeft   = iSrchRngHorLeft;
4275    Int   iSrchRngRasterRight  = iSrchRngHorRight;
4276    Int   iSrchRngRasterTop    = iSrchRngVerTop;
4277    Int   iSrchRngRasterBottom = iSrchRngVerBottom;
4278
4279    if (!(bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster))))
4280    {
4281      iWindowSize ++;
4282      iSrchRngRasterLeft /= 2;
4283      iSrchRngRasterRight /= 2;
4284      iSrchRngRasterTop /= 2;
4285      iSrchRngRasterBottom /= 2;
4286    }
4287    cStruct.uiBestDistance = iWindowSize;
4288    for ( iStartY = iSrchRngRasterTop; iStartY <= iSrchRngRasterBottom; iStartY += iWindowSize )
4289    {
4290      for ( iStartX = iSrchRngRasterLeft; iStartX <= iSrchRngRasterRight; iStartX += iWindowSize )
4291      {
4292        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iWindowSize );
4293      }
4294    }
4295  }
4296  else
4297  {
4298    if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
4299    {
4300      cStruct.uiBestDistance = iRaster;
4301      for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += iRaster )
4302      {
4303        for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += iRaster )
4304        {
4305          xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iRaster );
4306        }
4307      }
4308    }
4309  }
4310
4311  // raster refinement
4312
4313  if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 )
4314  {
4315    while ( cStruct.uiBestDistance > 0 )
4316    {
4317      iStartX = cStruct.iBestX;
4318      iStartY = cStruct.iBestY;
4319      if ( cStruct.uiBestDistance > 1 )
4320      {
4321        iDist = cStruct.uiBestDistance >>= 1;
4322        if ( bRasterRefinementDiamond == 1 )
4323        {
4324          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, bRasterRefinementCornersForDiamondDist1 );
4325        }
4326        else
4327        {
4328          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4329        }
4330      }
4331
4332      // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1
4333      if ( cStruct.uiBestDistance == 1 )
4334      {
4335        cStruct.uiBestDistance = 0;
4336        if ( cStruct.ucPointNr != 0 )
4337        {
4338          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4339        }
4340      }
4341    }
4342  }
4343
4344  // star refinement
4345  if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4346  {
4347    while ( cStruct.uiBestDistance > 0 )
4348    {
4349      iStartX = cStruct.iBestX;
4350      iStartY = cStruct.iBestY;
4351      cStruct.uiBestDistance = 0;
4352      cStruct.ucPointNr = 0;
4353      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4354      {
4355        if ( bStarRefinementDiamond == 1 )
4356        {
4357          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, bStarRefinementCornersForDiamondDist1 );
4358        }
4359        else
4360        {
4361          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4362        }
4363        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4364        {
4365          break;
4366        }
4367      }
4368
4369      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4370      if ( cStruct.uiBestDistance == 1 )
4371      {
4372        cStruct.uiBestDistance = 0;
4373        if ( cStruct.ucPointNr != 0 )
4374        {
4375          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4376        }
4377      }
4378    }
4379  }
4380
4381  // write out best match
4382  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4383  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY );
4384}
4385
4386
4387Void TEncSearch::xTZSearchSelective( const TComDataCU* const   pcCU,
4388                                     const TComPattern* const  pcPatternKey,
4389                                     const Pel* const          piRefY,
4390                                     const Int                 iRefStride,
4391                                     const TComMv* const       pcMvSrchRngLT,
4392                                     const TComMv* const       pcMvSrchRngRB,
4393                                     TComMv                   &rcMv,
4394                                     Distortion               &ruiSAD,
4395                                     const TComMv* const       pIntegerMv2Nx2NPred )
4396{
4397  const Bool bTestOtherPredictedMV    = true;
4398  const Bool bTestZeroVector          = true;
4399  const Bool bEnableRasterSearch      = true;
4400  const Bool bAlwaysRasterSearch      = false;  // 1: BETTER but factor 15x slower
4401  const Bool bStarRefinementEnable    = true;   // enable either star refinement or raster refinement
4402  const Bool bStarRefinementDiamond   = true;   // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
4403  const Bool bStarRefinementStop      = false;
4404  const UInt uiStarRefinementRounds   = 2;  // star refinement stop X rounds after best match (must be >=1)
4405  const UInt uiSearchRange            = m_iSearchRange;
4406  const Int  uiSearchRangeInitial     = m_iSearchRange >> 2;
4407  const Int  uiSearchStep             = 4;
4408  const Int  iMVDistThresh            = 8;
4409
4410  Int   iSrchRngHorLeft         = pcMvSrchRngLT->getHor();
4411  Int   iSrchRngHorRight        = pcMvSrchRngRB->getHor();
4412  Int   iSrchRngVerTop          = pcMvSrchRngLT->getVer();
4413  Int   iSrchRngVerBottom       = pcMvSrchRngRB->getVer();
4414  Int   iFirstSrchRngHorLeft    = 0;
4415  Int   iFirstSrchRngHorRight   = 0;
4416  Int   iFirstSrchRngVerTop     = 0;
4417  Int   iFirstSrchRngVerBottom  = 0;
4418  Int   iStartX                 = 0;
4419  Int   iStartY                 = 0;
4420  Int   iBestX                  = 0;
4421  Int   iBestY                  = 0;
4422  Int   iDist                   = 0;
4423
4424  pcCU->clipMv( rcMv );
4425#if ME_ENABLE_ROUNDING_OF_MVS
4426  rcMv.divideByPowerOf2(2);
4427#else
4428  rcMv >>= 2;
4429#endif
4430  // init TZSearchStruct
4431  IntTZSearchStruct cStruct;
4432  cStruct.iYStride    = iRefStride;
4433  cStruct.piRefY      = piRefY;
4434  cStruct.uiBestSad   = MAX_UINT;
4435  cStruct.iBestX = 0;
4436  cStruct.iBestY = 0;
4437
4438
4439  // set rcMv (Median predictor) as start point and as best point
4440  xTZSearchHelp( pcPatternKey, cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 );
4441
4442  // test whether one of PRED_A, PRED_B, PRED_C MV is better start point than Median predictor
4443  if ( bTestOtherPredictedMV )
4444  {
4445    for ( UInt index = 0; index < NUM_MV_PREDICTORS; index++ )
4446    {
4447      TComMv cMv = m_acMvPredictors[index];
4448      pcCU->clipMv( cMv );
4449#if ME_ENABLE_ROUNDING_OF_MVS
4450      cMv.divideByPowerOf2(2);
4451#else
4452      cMv >>= 2;
4453#endif
4454      xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
4455    }
4456  }
4457
4458  // test whether zero Mv is better start point than Median predictor
4459  if ( bTestZeroVector )
4460  {
4461    xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
4462  }
4463
4464  if ( pIntegerMv2Nx2NPred != 0 )
4465  {
4466    TComMv integerMv2Nx2NPred = *pIntegerMv2Nx2NPred;
4467    integerMv2Nx2NPred <<= 2;
4468    pcCU->clipMv( integerMv2Nx2NPred );
4469#if ME_ENABLE_ROUNDING_OF_MVS
4470    integerMv2Nx2NPred.divideByPowerOf2(2);
4471#else
4472    integerMv2Nx2NPred >>= 2;
4473#endif
4474    xTZSearchHelp(pcPatternKey, cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
4475
4476    // reset search range
4477    TComMv cMvSrchRngLT;
4478    TComMv cMvSrchRngRB;
4479    Int iSrchRng = m_iSearchRange;
4480    TComMv currBestMv(cStruct.iBestX, cStruct.iBestY );
4481    currBestMv <<= 2;
4482    xSetSearchRange( pcCU, currBestMv, iSrchRng, cMvSrchRngLT, cMvSrchRngRB );
4483    iSrchRngHorLeft   = cMvSrchRngLT.getHor();
4484    iSrchRngHorRight  = cMvSrchRngRB.getHor();
4485    iSrchRngVerTop    = cMvSrchRngLT.getVer();
4486    iSrchRngVerBottom = cMvSrchRngRB.getVer();
4487  }
4488
4489  // Initial search
4490  iBestX = cStruct.iBestX;
4491  iBestY = cStruct.iBestY; 
4492  iFirstSrchRngHorLeft    = ((iBestX - uiSearchRangeInitial) > iSrchRngHorLeft)   ? (iBestX - uiSearchRangeInitial) : iSrchRngHorLeft;
4493  iFirstSrchRngVerTop     = ((iBestY - uiSearchRangeInitial) > iSrchRngVerTop)    ? (iBestY - uiSearchRangeInitial) : iSrchRngVerTop;
4494  iFirstSrchRngHorRight   = ((iBestX + uiSearchRangeInitial) < iSrchRngHorRight)  ? (iBestX + uiSearchRangeInitial) : iSrchRngHorRight; 
4495  iFirstSrchRngVerBottom  = ((iBestY + uiSearchRangeInitial) < iSrchRngVerBottom) ? (iBestY + uiSearchRangeInitial) : iSrchRngVerBottom;   
4496
4497  for ( iStartY = iFirstSrchRngVerTop; iStartY <= iFirstSrchRngVerBottom; iStartY += uiSearchStep )
4498  {
4499    for ( iStartX = iFirstSrchRngHorLeft; iStartX <= iFirstSrchRngHorRight; iStartX += uiSearchStep )
4500    {
4501      xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, 0 );
4502      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 1, false );
4503      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 2, false );
4504    }
4505  }
4506
4507  Int iMaxMVDistToPred = (abs(cStruct.iBestX - iBestX) > iMVDistThresh || abs(cStruct.iBestY - iBestY) > iMVDistThresh);
4508
4509  //full search with early exit if MV is distant from predictors
4510  if ( bEnableRasterSearch && (iMaxMVDistToPred || bAlwaysRasterSearch) )
4511  {
4512    for ( iStartY = iSrchRngVerTop; iStartY <= iSrchRngVerBottom; iStartY += 1 )
4513    {
4514      for ( iStartX = iSrchRngHorLeft; iStartX <= iSrchRngHorRight; iStartX += 1 )
4515      {
4516        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, 1 );
4517      }
4518    }
4519  }
4520  //Smaller MV, refine around predictor
4521  else if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
4522  {
4523    // start refinement
4524    while ( cStruct.uiBestDistance > 0 )
4525    {
4526      iStartX = cStruct.iBestX;
4527      iStartY = cStruct.iBestY;
4528      cStruct.uiBestDistance = 0;
4529      cStruct.ucPointNr = 0;
4530      for ( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
4531      {
4532        if ( bStarRefinementDiamond == 1 )
4533        {
4534          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, false );
4535        }
4536        else
4537        {
4538          xTZ8PointSquareSearch  ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
4539        }
4540        if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
4541        {
4542          break;
4543        }
4544      }
4545
4546      // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
4547      if ( cStruct.uiBestDistance == 1 )
4548      {
4549        cStruct.uiBestDistance = 0;
4550        if ( cStruct.ucPointNr != 0 )
4551        {
4552          xTZ2PointSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB );
4553        }
4554      }
4555    }
4556  }
4557
4558  // write out best match
4559  rcMv.set( cStruct.iBestX, cStruct.iBestY );
4560  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY );
4561
4562}
4563
4564
4565Void TEncSearch::xPatternSearchFracDIF(
4566                                       Bool         bIsLosslessCoded,
4567                                       TComPattern* pcPatternKey,
4568                                       Pel*         piRefY,
4569                                       Int          iRefStride,
4570                                       TComMv*      pcMvInt,
4571                                       TComMv&      rcMvHalf,
4572                                       TComMv&      rcMvQter,
4573                                       Distortion&  ruiCost
4574                                      )
4575{
4576  //  Reference pattern initialization (integer scale)
4577  TComPattern cPatternRoi;
4578  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
4579  cPatternRoi.initPattern(piRefY + iOffset,
4580                          pcPatternKey->getROIYWidth(),
4581                          pcPatternKey->getROIYHeight(),
4582                          iRefStride,
4583                          pcPatternKey->getBitDepthY());
4584
4585  //  Half-pel refinement
4586  xExtDIFUpSamplingH ( &cPatternRoi );
4587
4588  rcMvHalf = *pcMvInt;   rcMvHalf <<= 1;    // for mv-cost
4589  TComMv baseRefMv(0, 0);
4590  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 2, rcMvHalf, !bIsLosslessCoded );
4591
4592  m_pcRdCost->setCostScale( 0 );
4593
4594  xExtDIFUpSamplingQ ( &cPatternRoi, rcMvHalf );
4595  baseRefMv = rcMvHalf;
4596  baseRefMv <<= 1;
4597
4598  rcMvQter = *pcMvInt;   rcMvQter <<= 1;    // for mv-cost
4599  rcMvQter += rcMvHalf;  rcMvQter <<= 1;
4600  ruiCost = xPatternRefinement( pcPatternKey, baseRefMv, 1, rcMvQter, !bIsLosslessCoded );
4601}
4602
4603
4604//! encode residual and calculate rate-distortion for a CU block
4605Void TEncSearch::encodeResAndCalcRdInterCU( TComDataCU* pcCU, TComYuv* pcYuvOrg, TComYuv* pcYuvPred,
4606                                            TComYuv* pcYuvResi, TComYuv* pcYuvResiBest, TComYuv* pcYuvRec,
4607                                            Bool bSkipResidual DEBUG_STRING_FN_DECLARE(sDebug) )
4608{
4609  assert ( !pcCU->isIntra(0) );
4610
4611  const UInt cuWidthPixels      = pcCU->getWidth ( 0 );
4612  const UInt cuHeightPixels     = pcCU->getHeight( 0 );
4613  const Int  numValidComponents = pcCU->getPic()->getNumberValidComponents();
4614  const TComSPS &sps=*(pcCU->getSlice()->getSPS());
4615
4616  // 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.
4617  // due to prior calls to TComDataCU::initEstData(  );
4618
4619  if ( bSkipResidual ) //  No residual coding : SKIP mode
4620  {
4621    pcCU->setSkipFlagSubParts( true, 0, pcCU->getDepth(0) );
4622
4623    pcYuvResi->clear();
4624
4625    pcYuvPred->copyToPartYuv( pcYuvRec, 0 );
4626    Distortion distortion = 0;
4627
4628    for (Int comp=0; comp < numValidComponents; comp++)
4629    {
4630      const ComponentID compID=ComponentID(comp);
4631      const UInt csx=pcYuvOrg->getComponentScaleX(compID);
4632      const UInt csy=pcYuvOrg->getComponentScaleY(compID);
4633      distortion += m_pcRdCost->getDistPart( sps.getBitDepth(toChannelType(compID)), pcYuvRec->getAddr(compID), pcYuvRec->getStride(compID), pcYuvOrg->getAddr(compID),
4634                                               pcYuvOrg->getStride(compID), cuWidthPixels >> csx, cuHeightPixels >> csy, compID);
4635    }
4636
4637    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST]);
4638    m_pcEntropyCoder->resetBits();
4639
4640    if (pcCU->getSlice()->getPPS()->getTransquantBypassEnabledFlag())
4641    {
4642      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
4643    }
4644
4645    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
4646    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, true );
4647
4648    UInt uiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4649    pcCU->getTotalBits()       = uiBits;
4650    pcCU->getTotalDistortion() = distortion;
4651    pcCU->getTotalCost()       = m_pcRdCost->calcRdCost( uiBits, distortion );
4652
4653    m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_TEMP_BEST]);
4654
4655#if DEBUG_STRING
4656    pcYuvResiBest->clear(); // Clear the residual image, if we didn't code it.
4657    for(UInt i=0; i<MAX_NUM_COMPONENT+1; i++)
4658    {
4659      sDebug+=debug_reorder_data_inter_token[i];
4660    }
4661#endif
4662
4663    return;
4664  }
4665
4666  //  Residual coding.
4667
4668   pcYuvResi->subtract( pcYuvOrg, pcYuvPred, 0, cuWidthPixels );
4669
4670  TComTURecurse tuLevel0(pcCU, 0);
4671
4672  Double     nonZeroCost       = 0;
4673  UInt       nonZeroBits       = 0;
4674  Distortion nonZeroDistortion = 0;
4675  Distortion zeroDistortion    = 0;
4676
4677  m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_CURR_BEST ] );
4678
4679  xEstimateInterResidualQT( pcYuvResi,  nonZeroCost, nonZeroBits, nonZeroDistortion, &zeroDistortion, tuLevel0 DEBUG_STRING_PASS_INTO(sDebug) );
4680
4681  // -------------------------------------------------------
4682  // set the coefficients in the pcCU, and also calculates the residual data.
4683  // If a block full of 0's is efficient, then just use 0's.
4684  // The costs at this point do not include header bits.
4685
4686  m_pcEntropyCoder->resetBits();
4687  m_pcEntropyCoder->encodeQtRootCbfZero( );
4688  const UInt   zeroResiBits = m_pcEntropyCoder->getNumberOfWrittenBits();
4689  const Double zeroCost     = (pcCU->isLosslessCoded( 0 )) ? (nonZeroCost+1) : (m_pcRdCost->calcRdCost( zeroResiBits, zeroDistortion ));
4690
4691  if ( zeroCost < nonZeroCost || !pcCU->getQtRootCbf(0) )
4692  {
4693    const UInt uiQPartNum = tuLevel0.GetAbsPartIdxNumParts();
4694    ::memset( pcCU->getTransformIdx()     , 0, uiQPartNum * sizeof(UChar) );
4695    for (Int comp=0; comp < numValidComponents; comp++)
4696    {
4697      const ComponentID component = ComponentID(comp);
4698      ::memset( pcCU->getCbf( component ) , 0, uiQPartNum * sizeof(UChar) );
4699      ::memset( pcCU->getCrossComponentPredictionAlpha(component), 0, ( uiQPartNum * sizeof(SChar) ) );
4700    }
4701    static const UInt useTS[MAX_NUM_COMPONENT]={0,0,0};
4702    pcCU->setTransformSkipSubParts ( useTS, 0, pcCU->getDepth(0) );
4703#if DEBUG_STRING
4704    sDebug.clear();
4705    for(UInt i=0; i<MAX_NUM_COMPONENT+1; i++)
4706    {
4707      sDebug+=debug_reorder_data_inter_token[i];
4708    }
4709#endif
4710  }
4711  else
4712  {
4713    xSetInterResidualQTData( NULL, false, tuLevel0); // Call first time to set coefficients.
4714  }
4715
4716  // all decisions now made. Fully encode the CU, including the headers:
4717  m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
4718
4719  UInt finalBits = 0;
4720  xAddSymbolBitsInter( pcCU, finalBits );
4721  // we've now encoded the pcCU, and so have a valid bit cost
4722
4723  if ( !pcCU->getQtRootCbf( 0 ) )
4724  {
4725    pcYuvResiBest->clear(); // Clear the residual image, if we didn't code it.
4726  }
4727  else
4728  {
4729    xSetInterResidualQTData( pcYuvResiBest, true, tuLevel0 ); // else set the residual image data pcYUVResiBest from the various temp images.
4730  }
4731  m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ pcCU->getDepth( 0 ) ][ CI_TEMP_BEST ] );
4732
4733  pcYuvRec->addClip ( pcYuvPred, pcYuvResiBest, 0, cuWidthPixels, sps.getBitDepths() );
4734
4735  // update with clipped distortion and cost (previously unclipped reconstruction values were used)
4736
4737  Distortion finalDistortion = 0;
4738  for(Int comp=0; comp<numValidComponents; comp++)
4739  {
4740    const ComponentID compID=ComponentID(comp);
4741    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);
4742  }
4743
4744  pcCU->getTotalBits()       = finalBits;
4745  pcCU->getTotalDistortion() = finalDistortion;
4746  pcCU->getTotalCost()       = m_pcRdCost->calcRdCost( finalBits, finalDistortion );
4747}
4748
4749
4750
4751Void TEncSearch::xEstimateInterResidualQT( TComYuv    *pcResi,
4752                                           Double     &rdCost,
4753                                           UInt       &ruiBits,
4754                                           Distortion &ruiDist,
4755                                           Distortion *puiZeroDist,
4756                                           TComTU     &rTu
4757                                           DEBUG_STRING_FN_DECLARE(sDebug) )
4758{
4759  TComDataCU *pcCU        = rTu.getCU();
4760  const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
4761  const UInt uiDepth      = rTu.GetTransformDepthTotal();
4762  const UInt uiTrMode     = rTu.GetTransformDepthRel();
4763  const UInt subTUDepth   = uiTrMode + 1;
4764  const UInt numValidComp = pcCU->getPic()->getNumberValidComponents();
4765  DEBUG_STRING_NEW(sSingleStringComp[MAX_NUM_COMPONENT])
4766
4767  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
4768  const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
4769
4770  UInt SplitFlag = ((pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && pcCU->isInter(uiAbsPartIdx) && ( pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N ));
4771#if DEBUG_STRING
4772  const Int debugPredModeMask = DebugStringGetPredModeMask(pcCU->getPredictionMode(uiAbsPartIdx));
4773#endif
4774
4775  Bool bCheckFull;
4776
4777  if ( SplitFlag && uiDepth == pcCU->getDepth(uiAbsPartIdx) && ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ) )
4778  {
4779    bCheckFull = false;
4780  }
4781  else
4782  {
4783    bCheckFull =  ( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() );
4784  }
4785
4786  const Bool bCheckSplit  = ( uiLog2TrSize >  pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
4787
4788  assert( bCheckFull || bCheckSplit );
4789
4790  // code full block
4791  Double     dSingleCost = MAX_DOUBLE;
4792  UInt       uiSingleBits                                                                                                        = 0;
4793  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}};
4794  Distortion uiSingleDist                                                                                                        = 0;
4795  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}};
4796  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}};
4797  //  Stores the best explicit RDPCM mode for a TU encoded without split
4798  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}};
4799  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}};
4800
4801  m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4802
4803  if( bCheckFull )
4804  {
4805    Double minCost[MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/];
4806    Bool checkTransformSkip[MAX_NUM_COMPONENT];
4807    pcCU->setTrIdxSubParts( uiTrMode, uiAbsPartIdx, uiDepth );
4808
4809    m_pcEntropyCoder->resetBits();
4810
4811    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)
4812
4813    const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
4814    TCoeff *pcCoeffCurr[MAX_NUM_COMPONENT];
4815#if ADAPTIVE_QP_SELECTION
4816    TCoeff *pcArlCoeffCurr[MAX_NUM_COMPONENT];
4817#endif
4818
4819    for(UInt i=0; i<numValidComp; i++)
4820    {
4821      minCost[i][0] = MAX_DOUBLE;
4822      minCost[i][1] = MAX_DOUBLE;
4823    }
4824
4825    Pel crossCPredictedResidualBuffer[ MAX_TU_SIZE * MAX_TU_SIZE ];
4826
4827    for(UInt i=0; i<numValidComp; i++)
4828    {
4829      checkTransformSkip[i]=false;
4830      const ComponentID compID=ComponentID(i);
4831      const Int channelBitDepth=pcCU->getSlice()->getSPS()->getBitDepth(toChannelType(compID));
4832      pcCoeffCurr[compID]    = m_ppcQTTempCoeff[compID][uiQTTempAccessLayer] + rTu.getCoefficientOffset(compID);
4833#if ADAPTIVE_QP_SELECTION
4834      pcArlCoeffCurr[compID] = m_ppcQTTempArlCoeff[compID ][uiQTTempAccessLayer] +  rTu.getCoefficientOffset(compID);
4835#endif
4836
4837      if(rTu.ProcessComponentSection(compID))
4838      {
4839        const QpParam cQP(*pcCU, compID);
4840
4841        checkTransformSkip[compID] = pcCU->getSlice()->getPPS()->getUseTransformSkip() &&
4842                                     TUCompRectHasAssociatedTransformSkipFlag(rTu.getRect(compID), pcCU->getSlice()->getPPS()->getPpsRangeExtension().getLog2MaxTransformSkipBlockSize()) &&
4843                                     (!pcCU->isLosslessCoded(0));
4844
4845        const Bool splitIntoSubTUs = rTu.getRect(compID).width != rTu.getRect(compID).height;
4846
4847        TComTURecurse TUIterator(rTu, false, (splitIntoSubTUs ? TComTU::VERTICAL_SPLIT : TComTU::DONT_SPLIT), true, compID);
4848
4849        const UInt partIdxesPerSubTU = TUIterator.GetAbsPartIdxNumParts(compID);
4850
4851        do
4852        {
4853          const UInt           subTUIndex             = TUIterator.GetSectionNumber();
4854          const UInt           subTUAbsPartIdx        = TUIterator.GetAbsPartIdxTU(compID);
4855          const TComRectangle &tuCompRect             = TUIterator.getRect(compID);
4856          const UInt           subTUBufferOffset      = tuCompRect.width * tuCompRect.height * subTUIndex;
4857
4858                TCoeff        *currentCoefficients    = pcCoeffCurr[compID] + subTUBufferOffset;
4859#if ADAPTIVE_QP_SELECTION
4860                TCoeff        *currentARLCoefficients = pcArlCoeffCurr[compID] + subTUBufferOffset;
4861#endif
4862          const Bool isCrossCPredictionAvailable      =    isChroma(compID)
4863                                                         && pcCU->getSlice()->getPPS()->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag()
4864                                                         && (pcCU->getCbf(subTUAbsPartIdx, COMPONENT_Y, uiTrMode) != 0);
4865
4866          SChar preCalcAlpha = 0;
4867          const Pel *pLumaResi = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( COMPONENT_Y, rTu.getRect( COMPONENT_Y ).x0, rTu.getRect( COMPONENT_Y ).y0 );
4868
4869          if (isCrossCPredictionAvailable)
4870          {
4871            const Bool bUseReconstructedResidualForEstimate = m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate();
4872            const Pel  *const lumaResidualForEstimate       = bUseReconstructedResidualForEstimate ? pLumaResi                                                     : pcResi->getAddrPix(COMPONENT_Y, tuCompRect.x0, tuCompRect.y0);
4873            const UInt        lumaResidualStrideForEstimate = bUseReconstructedResidualForEstimate ? m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y) : pcResi->getStride(COMPONENT_Y);
4874
4875            preCalcAlpha = xCalcCrossComponentPredictionAlpha(TUIterator,
4876                                                              compID,
4877                                                              lumaResidualForEstimate,
4878                                                              pcResi->getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4879                                                              tuCompRect.width,
4880                                                              tuCompRect.height,
4881                                                              lumaResidualStrideForEstimate,
4882                                                              pcResi->getStride(compID));
4883          }
4884
4885          const Int transformSkipModesToTest    = checkTransformSkip[compID] ? 2 : 1;
4886          const Int crossCPredictionModesToTest = (preCalcAlpha != 0)        ? 2 : 1; // preCalcAlpha cannot be anything other than 0 if isCrossCPredictionAvailable is false
4887
4888          const Bool isOneMode                  = (crossCPredictionModesToTest == 1) && (transformSkipModesToTest == 1);
4889
4890          for (Int transformSkipModeId = 0; transformSkipModeId < transformSkipModesToTest; transformSkipModeId++)
4891          {
4892            pcCU->setTransformSkipPartRange(transformSkipModeId, compID, subTUAbsPartIdx, partIdxesPerSubTU);
4893
4894            for (Int crossCPredictionModeId = 0; crossCPredictionModeId < crossCPredictionModesToTest; crossCPredictionModeId++)
4895            {
4896              const Bool isFirstMode          = (transformSkipModeId == 0) && (crossCPredictionModeId == 0);
4897              const Bool bUseCrossCPrediction = crossCPredictionModeId != 0;
4898
4899              m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
4900              m_pcEntropyCoder->resetBits();
4901
4902              pcCU->setTransformSkipPartRange(transformSkipModeId, compID, subTUAbsPartIdx, partIdxesPerSubTU);
4903              pcCU->setCrossComponentPredictionAlphaPartRange((bUseCrossCPrediction ? preCalcAlpha : 0), compID, subTUAbsPartIdx, partIdxesPerSubTU );
4904
4905              if ((compID != COMPONENT_Cr) && ((transformSkipModeId == 1) ? m_pcEncCfg->getUseRDOQTS() : m_pcEncCfg->getUseRDOQ()))
4906              {
4907                m_pcEntropyCoder->estimateBit(m_pcTrQuant->m_pcEstBitsSbac, tuCompRect.width, tuCompRect.height, toChannelType(compID));
4908              }
4909
4910#if RDOQ_CHROMA_LAMBDA
4911              m_pcTrQuant->selectLambda(compID);
4912#endif
4913
4914              Pel *pcResiCurrComp = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0);
4915              UInt resiStride     = m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID);
4916
4917              TCoeff bestCoeffComp   [MAX_TU_SIZE*MAX_TU_SIZE];
4918              Pel    bestResiComp    [MAX_TU_SIZE*MAX_TU_SIZE];
4919
4920#if ADAPTIVE_QP_SELECTION
4921              TCoeff bestArlCoeffComp[MAX_TU_SIZE*MAX_TU_SIZE];
4922#endif
4923              TCoeff     currAbsSum   = 0;
4924              UInt       currCompBits = 0;
4925              Distortion currCompDist = 0;
4926              Double     currCompCost = 0;
4927              UInt       nonCoeffBits = 0;
4928              Distortion nonCoeffDist = 0;
4929              Double     nonCoeffCost = 0;
4930
4931              if(!isOneMode && !isFirstMode)
4932              {
4933                memcpy(bestCoeffComp,    currentCoefficients,    (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
4934#if ADAPTIVE_QP_SELECTION
4935                memcpy(bestArlCoeffComp, currentARLCoefficients, (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
4936#endif
4937                for(Int y = 0; y < tuCompRect.height; y++)
4938                {
4939                  memcpy(&bestResiComp[y * tuCompRect.width], (pcResiCurrComp + (y * resiStride)), (sizeof(Pel) * tuCompRect.width));
4940                }
4941              }
4942
4943              if (bUseCrossCPrediction)
4944              {
4945                TComTrQuant::crossComponentPrediction(TUIterator,
4946                                                      compID,
4947                                                      pLumaResi,
4948                                                      pcResi->getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4949                                                      crossCPredictedResidualBuffer,
4950                                                      tuCompRect.width,
4951                                                      tuCompRect.height,
4952                                                      m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
4953                                                      pcResi->getStride(compID),
4954                                                      tuCompRect.width,
4955                                                      false);
4956
4957                m_pcTrQuant->transformNxN(TUIterator, compID, crossCPredictedResidualBuffer, tuCompRect.width, currentCoefficients,
4958#if ADAPTIVE_QP_SELECTION
4959                                          currentARLCoefficients,
4960#endif
4961                                          currAbsSum, cQP);
4962              }
4963              else
4964              {
4965                m_pcTrQuant->transformNxN(TUIterator, compID, pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ), pcResi->getStride(compID), currentCoefficients,
4966#if ADAPTIVE_QP_SELECTION
4967                                          currentARLCoefficients,
4968#endif
4969                                          currAbsSum, cQP);
4970              }
4971
4972              if(isFirstMode || (currAbsSum == 0))
4973              {
4974                if (bUseCrossCPrediction)
4975                {
4976                  TComTrQuant::crossComponentPrediction(TUIterator,
4977                                                        compID,
4978                                                        pLumaResi,
4979                                                        m_pTempPel,
4980                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
4981                                                        tuCompRect.width,
4982                                                        tuCompRect.height,
4983                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
4984                                                        tuCompRect.width,
4985                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID),
4986                                                        true);
4987
4988                  nonCoeffDist = m_pcRdCost->getDistPart( channelBitDepth, m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4989                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride( compID ), pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4990                                                          pcResi->getStride(compID), tuCompRect.width, tuCompRect.height, compID); // initialized with zero residual distortion
4991                }
4992                else
4993                {
4994                  nonCoeffDist = m_pcRdCost->getDistPart( channelBitDepth, m_pTempPel, tuCompRect.width, pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
4995                                                          pcResi->getStride(compID), tuCompRect.width, tuCompRect.height, compID); // initialized with zero residual distortion
4996                }
4997
4998                m_pcEntropyCoder->encodeQtCbfZero( TUIterator, toChannelType(compID) );
4999
5000                if ( isCrossCPredictionAvailable )
5001                {
5002                  m_pcEntropyCoder->encodeCrossComponentPrediction( TUIterator, compID );
5003                }
5004
5005                nonCoeffBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5006                nonCoeffCost = m_pcRdCost->calcRdCost( nonCoeffBits, nonCoeffDist );
5007              }
5008
5009              if((puiZeroDist != NULL) && isFirstMode)
5010              {
5011                *puiZeroDist += nonCoeffDist; // initialized with zero residual distortion
5012              }
5013
5014              DEBUG_STRING_NEW(sSingleStringTest)
5015
5016              if( currAbsSum > 0 ) //if non-zero coefficients are present, a residual needs to be derived for further prediction
5017              {
5018                if (isFirstMode)
5019                {
5020                  m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5021                  m_pcEntropyCoder->resetBits();
5022                }
5023
5024                m_pcEntropyCoder->encodeQtCbf( TUIterator, compID, true );
5025
5026                if (isCrossCPredictionAvailable)
5027                {
5028                  m_pcEntropyCoder->encodeCrossComponentPrediction( TUIterator, compID );
5029                }
5030
5031                m_pcEntropyCoder->encodeCoeffNxN( TUIterator, currentCoefficients, compID );
5032                currCompBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5033
5034                pcResiCurrComp = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 );
5035
5036                m_pcTrQuant->invTransformNxN( TUIterator, compID, pcResiCurrComp, m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID), currentCoefficients, cQP DEBUG_STRING_PASS_INTO_OPTIONAL(&sSingleStringTest, (DebugOptionList::DebugString_InvTran.getInt()&debugPredModeMask)) );
5037
5038                if (bUseCrossCPrediction)
5039                {
5040                  TComTrQuant::crossComponentPrediction(TUIterator,
5041                                                        compID,
5042                                                        pLumaResi,
5043                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
5044                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
5045                                                        tuCompRect.width,
5046                                                        tuCompRect.height,
5047                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
5048                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID     ),
5049                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID     ),
5050                                                        true);
5051                }
5052
5053                currCompDist = m_pcRdCost->getDistPart( channelBitDepth, m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
5054                                                        m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID),
5055                                                        pcResi->getAddrPix( compID, tuCompRect.x0, tuCompRect.y0 ),
5056                                                        pcResi->getStride(compID),
5057                                                        tuCompRect.width, tuCompRect.height, compID);
5058
5059                currCompCost = m_pcRdCost->calcRdCost(currCompBits, currCompDist);
5060                 
5061                if (pcCU->isLosslessCoded(0))
5062                {
5063                  nonCoeffCost = MAX_DOUBLE;
5064                }
5065              }
5066              else if ((transformSkipModeId == 1) && !bUseCrossCPrediction)
5067              {
5068                currCompCost = MAX_DOUBLE;
5069              }
5070              else
5071              {
5072                currCompBits = nonCoeffBits;
5073                currCompDist = nonCoeffDist;
5074                currCompCost = nonCoeffCost;
5075              }
5076
5077              // evaluate
5078              if ((currCompCost < minCost[compID][subTUIndex]) || ((transformSkipModeId == 1) && (currCompCost == minCost[compID][subTUIndex])))
5079              {
5080                bestExplicitRdpcmModeUnSplit[compID][subTUIndex] = pcCU->getExplicitRdpcmMode(compID, subTUAbsPartIdx);
5081
5082                if(isFirstMode) //check for forced null
5083                {
5084                  if((nonCoeffCost < currCompCost) || (currAbsSum == 0))
5085                  {
5086                    memset(currentCoefficients, 0, (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
5087
5088                    currAbsSum   = 0;
5089                    currCompBits = nonCoeffBits;
5090                    currCompDist = nonCoeffDist;
5091                    currCompCost = nonCoeffCost;
5092                  }
5093                }
5094
5095#if DEBUG_STRING
5096                if (currAbsSum > 0)
5097                {
5098                  DEBUG_STRING_SWAP(sSingleStringComp[compID], sSingleStringTest)
5099                }
5100                else
5101                {
5102                  sSingleStringComp[compID].clear();
5103                }
5104#endif
5105
5106                uiAbsSum                 [compID][subTUIndex] = currAbsSum;
5107                uiSingleDistComp         [compID][subTUIndex] = currCompDist;
5108                minCost                  [compID][subTUIndex] = currCompCost;
5109                uiBestTransformMode      [compID][subTUIndex] = transformSkipModeId;
5110                bestCrossCPredictionAlpha[compID][subTUIndex] = (crossCPredictionModeId == 1) ? pcCU->getCrossComponentPredictionAlpha(subTUAbsPartIdx, compID) : 0;
5111
5112                if (uiAbsSum[compID][subTUIndex] == 0)
5113                {
5114                  if (bUseCrossCPrediction)
5115                  {
5116                    TComTrQuant::crossComponentPrediction(TUIterator,
5117                                                          compID,
5118                                                          pLumaResi,
5119                                                          m_pTempPel,
5120                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0),
5121                                                          tuCompRect.width,
5122                                                          tuCompRect.height,
5123                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(COMPONENT_Y),
5124                                                          tuCompRect.width,
5125                                                          m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID),
5126                                                          true);
5127                  }
5128                  else
5129                  {
5130                    pcResiCurrComp = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix(compID, tuCompRect.x0, tuCompRect.y0);
5131                    const UInt uiStride = m_pcQTTempTComYuv[uiQTTempAccessLayer].getStride(compID);
5132                    for(UInt uiY = 0; uiY < tuCompRect.height; uiY++)
5133                    {
5134                      memset(pcResiCurrComp, 0, (sizeof(Pel) * tuCompRect.width));
5135                      pcResiCurrComp += uiStride;
5136                    }
5137                  }
5138                }
5139              }
5140              else
5141              {
5142                // reset
5143                memcpy(currentCoefficients,    bestCoeffComp,    (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
5144#if ADAPTIVE_QP_SELECTION
5145                memcpy(currentARLCoefficients, bestArlCoeffComp, (sizeof(TCoeff) * tuCompRect.width * tuCompRect.height));
5146#endif
5147                for (Int y = 0; y < tuCompRect.height; y++)
5148                {
5149                  memcpy((pcResiCurrComp + (y * resiStride)), &bestResiComp[y * tuCompRect.width], (sizeof(Pel) * tuCompRect.width));
5150                }
5151              }
5152            }
5153          }
5154
5155          pcCU->setExplicitRdpcmModePartRange            (   bestExplicitRdpcmModeUnSplit[compID][subTUIndex],                            compID, subTUAbsPartIdx, partIdxesPerSubTU);
5156          pcCU->setTransformSkipPartRange                (   uiBestTransformMode         [compID][subTUIndex],                            compID, subTUAbsPartIdx, partIdxesPerSubTU );
5157          pcCU->setCbfPartRange                          ((((uiAbsSum                    [compID][subTUIndex] > 0) ? 1 : 0) << uiTrMode), compID, subTUAbsPartIdx, partIdxesPerSubTU );
5158          pcCU->setCrossComponentPredictionAlphaPartRange(   bestCrossCPredictionAlpha   [compID][subTUIndex],                            compID, subTUAbsPartIdx, partIdxesPerSubTU );
5159        } while (TUIterator.nextSection(rTu)); //end of sub-TU loop
5160      } // processing section
5161    } // component loop
5162
5163    for(UInt ch = 0; ch < numValidComp; ch++)
5164    {
5165      const ComponentID compID = ComponentID(ch);
5166      if (rTu.ProcessComponentSection(compID) && (rTu.getRect(compID).width != rTu.getRect(compID).height))
5167      {
5168        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
5169      }
5170    }
5171
5172    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5173    m_pcEntropyCoder->resetBits();
5174
5175    if( uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5176    {
5177      m_pcEntropyCoder->encodeTransformSubdivFlag( 0, 5 - uiLog2TrSize );
5178    }
5179
5180    for(UInt ch = 0; ch < numValidComp; ch++)
5181    {
5182      const UInt chOrderChange = ((ch + 1) == numValidComp) ? 0 : (ch + 1);
5183      const ComponentID compID=ComponentID(chOrderChange);
5184      if( rTu.ProcessComponentSection(compID) )
5185      {
5186        m_pcEntropyCoder->encodeQtCbf( rTu, compID, true );
5187      }
5188    }
5189
5190    for(UInt ch = 0; ch < numValidComp; ch++)
5191    {
5192      const ComponentID compID=ComponentID(ch);
5193      if (rTu.ProcessComponentSection(compID))
5194      {
5195        if(isChroma(compID) && (uiAbsSum[COMPONENT_Y][0] != 0))
5196        {
5197          m_pcEntropyCoder->encodeCrossComponentPrediction( rTu, compID );
5198        }
5199
5200        m_pcEntropyCoder->encodeCoeffNxN( rTu, pcCoeffCurr[compID], compID );
5201        for (UInt subTUIndex = 0; subTUIndex < 2; subTUIndex++)
5202        {
5203          uiSingleDist += uiSingleDistComp[compID][subTUIndex];
5204        }
5205      }
5206    }
5207
5208    uiSingleBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5209
5210    dSingleCost = m_pcRdCost->calcRdCost( uiSingleBits, uiSingleDist );
5211  } // check full
5212
5213  // code sub-blocks
5214  if( bCheckSplit )
5215  {
5216    if( bCheckFull )
5217    {
5218      m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5219      m_pcRDGoOnSbacCoder->load ( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5220    }
5221    Distortion uiSubdivDist = 0;
5222    UInt       uiSubdivBits = 0;
5223    Double     dSubdivCost = 0.0;
5224
5225    //save the non-split CBFs in case we need to restore them later
5226
5227    UInt bestCBF     [MAX_NUM_COMPONENT];
5228    UInt bestsubTUCBF[MAX_NUM_COMPONENT][2];
5229    for(UInt ch = 0; ch < numValidComp; ch++)
5230    {
5231      const ComponentID compID=ComponentID(ch);
5232
5233      if (rTu.ProcessComponentSection(compID))
5234      {
5235        bestCBF[compID] = pcCU->getCbf(uiAbsPartIdx, compID, uiTrMode);
5236
5237        const TComRectangle &tuCompRect = rTu.getRect(compID);
5238        if (tuCompRect.width != tuCompRect.height)
5239        {
5240          const UInt partIdxesPerSubTU = rTu.GetAbsPartIdxNumParts(compID) >> 1;
5241
5242          for (UInt subTU = 0; subTU < 2; subTU++)
5243          {
5244            bestsubTUCBF[compID][subTU] = pcCU->getCbf ((uiAbsPartIdx + (subTU * partIdxesPerSubTU)), compID, subTUDepth);
5245          }
5246        }
5247      }
5248    }
5249
5250
5251    TComTURecurse tuRecurseChild(rTu, false);
5252    const UInt uiQPartNumSubdiv = tuRecurseChild.GetAbsPartIdxNumParts();
5253
5254    DEBUG_STRING_NEW(sSplitString[MAX_NUM_COMPONENT])
5255
5256    do
5257    {
5258      DEBUG_STRING_NEW(childString)
5259      xEstimateInterResidualQT( pcResi, dSubdivCost, uiSubdivBits, uiSubdivDist, bCheckFull ? NULL : puiZeroDist,  tuRecurseChild DEBUG_STRING_PASS_INTO(childString));
5260#if DEBUG_STRING
5261      // split the string by component and append to the relevant output (because decoder decodes in channel order, whereas this search searches by TU-order)
5262      std::size_t lastPos=0;
5263      const std::size_t endStrng=childString.find(debug_reorder_data_inter_token[MAX_NUM_COMPONENT], lastPos);
5264      for(UInt ch = 0; ch < numValidComp; ch++)
5265      {
5266        if (lastPos!=std::string::npos && childString.find(debug_reorder_data_inter_token[ch], lastPos)==lastPos)
5267        {
5268          lastPos+=strlen(debug_reorder_data_inter_token[ch]); // skip leading string
5269        }
5270        std::size_t pos=childString.find(debug_reorder_data_inter_token[ch+1], lastPos);
5271        if (pos!=std::string::npos && pos>endStrng)
5272        {
5273          lastPos=endStrng;
5274        }
5275        sSplitString[ch]+=childString.substr(lastPos, (pos==std::string::npos)? std::string::npos : (pos-lastPos) );
5276        lastPos=pos;
5277      }
5278#endif
5279    } while ( tuRecurseChild.nextSection(rTu) ) ;
5280
5281    UInt uiCbfAny=0;
5282    for(UInt ch = 0; ch < numValidComp; ch++)
5283    {
5284      UInt uiYUVCbf = 0;
5285      for( UInt ui = 0; ui < 4; ++ui )
5286      {
5287        uiYUVCbf |= pcCU->getCbf( uiAbsPartIdx + ui * uiQPartNumSubdiv, ComponentID(ch),  uiTrMode + 1 );
5288      }
5289      UChar *pBase=pcCU->getCbf( ComponentID(ch) );
5290      const UInt flags=uiYUVCbf << uiTrMode;
5291      for( UInt ui = 0; ui < 4 * uiQPartNumSubdiv; ++ui )
5292      {
5293        pBase[uiAbsPartIdx + ui] |= flags;
5294      }
5295      uiCbfAny|=uiYUVCbf;
5296    }
5297
5298    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
5299    m_pcEntropyCoder->resetBits();
5300
5301    // when compID isn't a channel, code Cbfs:
5302    xEncodeInterResidualQT( MAX_NUM_COMPONENT, rTu );
5303    for(UInt ch = 0; ch < numValidComp; ch++)
5304    {
5305      xEncodeInterResidualQT( ComponentID(ch), rTu );
5306    }
5307
5308    uiSubdivBits = m_pcEntropyCoder->getNumberOfWrittenBits();
5309    dSubdivCost  = m_pcRdCost->calcRdCost( uiSubdivBits, uiSubdivDist );
5310
5311    if (!bCheckFull || (uiCbfAny && (dSubdivCost < dSingleCost)))
5312    {
5313      rdCost += dSubdivCost;
5314      ruiBits += uiSubdivBits;
5315      ruiDist += uiSubdivDist;
5316#if DEBUG_STRING
5317      for(UInt ch = 0; ch < numValidComp; ch++)
5318      {
5319        DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[ch])
5320        DEBUG_STRING_APPEND(sDebug, sSplitString[ch])
5321      }
5322#endif
5323    }
5324    else
5325    {
5326      rdCost  += dSingleCost;
5327      ruiBits += uiSingleBits;
5328      ruiDist += uiSingleDist;
5329
5330      //restore state to unsplit
5331
5332      pcCU->setTrIdxSubParts( uiTrMode, uiAbsPartIdx, uiDepth );
5333
5334      for(UInt ch = 0; ch < numValidComp; ch++)
5335      {
5336        const ComponentID compID=ComponentID(ch);
5337
5338        DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[ch])
5339        if (rTu.ProcessComponentSection(compID))
5340        {
5341          DEBUG_STRING_APPEND(sDebug, sSingleStringComp[compID])
5342
5343          const Bool splitIntoSubTUs   = rTu.getRect(compID).width != rTu.getRect(compID).height;
5344          const UInt numberOfSections  = splitIntoSubTUs ? 2 : 1;
5345          const UInt partIdxesPerSubTU = rTu.GetAbsPartIdxNumParts(compID) >> (splitIntoSubTUs ? 1 : 0);
5346
5347          for (UInt subTUIndex = 0; subTUIndex < numberOfSections; subTUIndex++)
5348          {
5349            const UInt  uisubTUPartIdx = uiAbsPartIdx + (subTUIndex * partIdxesPerSubTU);
5350
5351            if (splitIntoSubTUs)
5352            {
5353              const UChar combinedCBF = (bestsubTUCBF[compID][subTUIndex] << subTUDepth) | (bestCBF[compID] << uiTrMode);
5354              pcCU->setCbfPartRange(combinedCBF, compID, uisubTUPartIdx, partIdxesPerSubTU);
5355            }
5356            else
5357            {
5358              pcCU->setCbfPartRange((bestCBF[compID] << uiTrMode), compID, uisubTUPartIdx, partIdxesPerSubTU);
5359            }
5360
5361            pcCU->setCrossComponentPredictionAlphaPartRange(bestCrossCPredictionAlpha[compID][subTUIndex], compID, uisubTUPartIdx, partIdxesPerSubTU);
5362            pcCU->setTransformSkipPartRange(uiBestTransformMode[compID][subTUIndex], compID, uisubTUPartIdx, partIdxesPerSubTU);
5363            pcCU->setExplicitRdpcmModePartRange(bestExplicitRdpcmModeUnSplit[compID][subTUIndex], compID, uisubTUPartIdx, partIdxesPerSubTU);
5364          }
5365        }
5366      }
5367
5368      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_TEST ] );
5369    }
5370  }
5371  else
5372  {
5373    rdCost  += dSingleCost;
5374    ruiBits += uiSingleBits;
5375    ruiDist += uiSingleDist;
5376#if DEBUG_STRING
5377    for(UInt ch = 0; ch < numValidComp; ch++)
5378    {
5379      const ComponentID compID=ComponentID(ch);
5380      DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[compID])
5381
5382      if (rTu.ProcessComponentSection(compID))
5383      {
5384        DEBUG_STRING_APPEND(sDebug, sSingleStringComp[compID])
5385      }
5386    }
5387#endif
5388  }
5389  DEBUG_STRING_APPEND(sDebug, debug_reorder_data_inter_token[MAX_NUM_COMPONENT])
5390}
5391
5392
5393
5394Void TEncSearch::xEncodeInterResidualQT( const ComponentID compID, TComTU &rTu )
5395{
5396  TComDataCU* pcCU=rTu.getCU();
5397  const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU();
5398  const UInt uiCurrTrMode = rTu.GetTransformDepthRel();
5399  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5400  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5401
5402  const Bool bSubdiv = uiCurrTrMode != uiTrMode;
5403
5404  const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
5405
5406  if (compID==MAX_NUM_COMPONENT)  // we are not processing a channel, instead we always recurse and code the CBFs
5407  {
5408    if( uiLog2TrSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() && uiLog2TrSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
5409    {
5410      if((pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N))
5411      {
5412        assert(bSubdiv); // Inferred splitting rule - see derivation and use of interSplitFlag in the specification.
5413      }
5414      else
5415      {
5416        m_pcEntropyCoder->encodeTransformSubdivFlag( bSubdiv, 5 - uiLog2TrSize );
5417      }
5418    }
5419
5420    assert( !pcCU->isIntra(uiAbsPartIdx) );
5421
5422    const Bool bFirstCbfOfCU = uiCurrTrMode == 0;
5423
5424    for (UInt ch=COMPONENT_Cb; ch<pcCU->getPic()->getNumberValidComponents(); ch++)
5425    {
5426      const ComponentID compIdInner=ComponentID(ch);
5427      if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compIdInner) )
5428      {
5429        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compIdInner, uiCurrTrMode - 1 ) )
5430        {
5431          m_pcEntropyCoder->encodeQtCbf( rTu, compIdInner, !bSubdiv );
5432        }
5433      }
5434      else
5435      {
5436        assert( pcCU->getCbf( uiAbsPartIdx, compIdInner, uiCurrTrMode ) == pcCU->getCbf( uiAbsPartIdx, compIdInner, uiCurrTrMode - 1 ) );
5437      }
5438    }
5439
5440    if (!bSubdiv)
5441    {
5442      m_pcEntropyCoder->encodeQtCbf( rTu, COMPONENT_Y, true );
5443    }
5444  }
5445
5446  if( !bSubdiv )
5447  {
5448    if (compID != MAX_NUM_COMPONENT) // we have already coded the CBFs, so now we code coefficients
5449    {
5450      if (rTu.ProcessComponentSection(compID))
5451      {
5452        if (isChroma(compID) && (pcCU->getCbf(uiAbsPartIdx, COMPONENT_Y, uiTrMode) != 0))
5453        {
5454          m_pcEntropyCoder->encodeCrossComponentPrediction(rTu, compID);
5455        }
5456
5457        if (pcCU->getCbf(uiAbsPartIdx, compID, uiTrMode) != 0)
5458        {
5459          const UInt uiQTTempAccessLayer = pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5460          TCoeff *pcCoeffCurr = m_ppcQTTempCoeff[compID][uiQTTempAccessLayer] + rTu.getCoefficientOffset(compID);
5461          m_pcEntropyCoder->encodeCoeffNxN( rTu, pcCoeffCurr, compID );
5462        }
5463      }
5464    }
5465  }
5466  else
5467  {
5468    if( compID==MAX_NUM_COMPONENT || pcCU->getCbf( uiAbsPartIdx, compID, uiCurrTrMode ) )
5469    {
5470      TComTURecurse tuRecurseChild(rTu, false);
5471      do
5472      {
5473        xEncodeInterResidualQT( compID, tuRecurseChild );
5474      } while (tuRecurseChild.nextSection(rTu));
5475    }
5476  }
5477}
5478
5479
5480
5481
5482Void TEncSearch::xSetInterResidualQTData( TComYuv* pcResi, Bool bSpatial, TComTU &rTu ) // TODO: turn this into two functions for bSpatial=true and false.
5483{
5484  TComDataCU* pcCU=rTu.getCU();
5485  const UInt uiCurrTrMode=rTu.GetTransformDepthRel();
5486  const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU();
5487  assert( pcCU->getDepth( 0 ) == pcCU->getDepth( uiAbsPartIdx ) );
5488  const UInt uiTrMode = pcCU->getTransformIdx( uiAbsPartIdx );
5489  const TComSPS *sps=pcCU->getSlice()->getSPS();
5490
5491  if( uiCurrTrMode == uiTrMode )
5492  {
5493    const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
5494    const UInt uiQTTempAccessLayer = sps->getQuadtreeTULog2MaxSize() - uiLog2TrSize;
5495
5496    if( bSpatial )
5497    {
5498      // Data to be copied is in the spatial domain, i.e., inverse-transformed.
5499
5500      for(UInt i=0; i<pcResi->getNumberValidComponents(); i++)
5501      {
5502        const ComponentID compID=ComponentID(i);
5503        if (rTu.ProcessComponentSection(compID))
5504        {
5505          const TComRectangle &rectCompTU(rTu.getRect(compID));
5506          m_pcQTTempTComYuv[uiQTTempAccessLayer].copyPartToPartComponentMxN    ( compID, pcResi, rectCompTU );
5507        }
5508      }
5509    }
5510    else
5511    {
5512      for (UInt ch=0; ch < getNumberValidComponents(sps->getChromaFormatIdc()); ch++)
5513      {
5514        const ComponentID compID   = ComponentID(ch);
5515        if (rTu.ProcessComponentSection(compID))
5516        {
5517          const TComRectangle &rectCompTU(rTu.getRect(compID));
5518          const UInt numCoeffInBlock    = rectCompTU.width * rectCompTU.height;
5519          const UInt offset             = rTu.getCoefficientOffset(compID);
5520          TCoeff* dest                  = pcCU->getCoeff(compID)                        + offset;
5521          const TCoeff* src             = m_ppcQTTempCoeff[compID][uiQTTempAccessLayer] + offset;
5522          ::memcpy( dest, src, sizeof(TCoeff)*numCoeffInBlock );
5523
5524#if ADAPTIVE_QP_SELECTION
5525          TCoeff* pcArlCoeffSrc            = m_ppcQTTempArlCoeff[compID][uiQTTempAccessLayer] + offset;
5526          TCoeff* pcArlCoeffDst            = pcCU->getArlCoeff(compID)                        + offset;
5527          ::memcpy( pcArlCoeffDst, pcArlCoeffSrc, sizeof( TCoeff ) * numCoeffInBlock );
5528#endif
5529        }
5530      }
5531    }
5532  }
5533  else
5534  {
5535
5536    TComTURecurse tuRecurseChild(rTu, false);
5537    do
5538    {
5539      xSetInterResidualQTData( pcResi, bSpatial, tuRecurseChild );
5540    } while (tuRecurseChild.nextSection(rTu));
5541  }
5542}
5543
5544
5545
5546
5547UInt TEncSearch::xModeBitsIntra( TComDataCU* pcCU, UInt uiMode, UInt uiPartOffset, UInt uiDepth, const ChannelType chType )
5548{
5549  // Reload only contexts required for coding intra mode information
5550  m_pcRDGoOnSbacCoder->loadIntraDirMode( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST], chType );
5551
5552  // Temporarily set the intra dir being tested, and only
5553  // for absPartIdx, since encodeIntraDirModeLuma/Chroma only use
5554  // the entry at absPartIdx.
5555
5556  UChar &rIntraDirVal=pcCU->getIntraDir( chType )[uiPartOffset];
5557  UChar origVal=rIntraDirVal;
5558  rIntraDirVal = uiMode;
5559  //pcCU->setIntraDirSubParts ( chType, uiMode, uiPartOffset, uiDepth + uiInitTrDepth );
5560
5561  m_pcEntropyCoder->resetBits();
5562  if (isLuma(chType))
5563  {
5564    m_pcEntropyCoder->encodeIntraDirModeLuma ( pcCU, uiPartOffset);
5565  }
5566  else
5567  {
5568    m_pcEntropyCoder->encodeIntraDirModeChroma ( pcCU, uiPartOffset);
5569  }
5570
5571  rIntraDirVal = origVal; // restore
5572
5573  return m_pcEntropyCoder->getNumberOfWrittenBits();
5574}
5575
5576
5577
5578
5579UInt TEncSearch::xUpdateCandList( UInt uiMode, Double uiCost, UInt uiFastCandNum, UInt * CandModeList, Double * CandCostList )
5580{
5581  UInt i;
5582  UInt shift=0;
5583
5584  while ( shift<uiFastCandNum && uiCost<CandCostList[ uiFastCandNum-1-shift ] )
5585  {
5586    shift++;
5587  }
5588
5589  if( shift!=0 )
5590  {
5591    for(i=1; i<shift; i++)
5592    {
5593      CandModeList[ uiFastCandNum-i ] = CandModeList[ uiFastCandNum-1-i ];
5594      CandCostList[ uiFastCandNum-i ] = CandCostList[ uiFastCandNum-1-i ];
5595    }
5596    CandModeList[ uiFastCandNum-shift ] = uiMode;
5597    CandCostList[ uiFastCandNum-shift ] = uiCost;
5598    return 1;
5599  }
5600
5601  return 0;
5602}
5603
5604
5605
5606
5607
5608/** add inter-prediction syntax elements for a CU block
5609 * \param pcCU
5610 * \param uiQp
5611 * \param uiTrMode
5612 * \param ruiBits
5613 * \returns Void
5614 */
5615Void  TEncSearch::xAddSymbolBitsInter( TComDataCU* pcCU, UInt& ruiBits )
5616{
5617  if(pcCU->getMergeFlag( 0 ) && pcCU->getPartitionSize( 0 ) == SIZE_2Nx2N && !pcCU->getQtRootCbf( 0 ))
5618  {
5619    pcCU->setSkipFlagSubParts( true, 0, pcCU->getDepth(0) );
5620
5621    m_pcEntropyCoder->resetBits();
5622    if(pcCU->getSlice()->getPPS()->getTransquantBypassEnabledFlag())
5623    {
5624      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
5625    }
5626    m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
5627    m_pcEntropyCoder->encodeMergeIndex(pcCU, 0, true);
5628
5629    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5630  }
5631  else
5632  {
5633    m_pcEntropyCoder->resetBits();
5634
5635    if(pcCU->getSlice()->getPPS()->getTransquantBypassEnabledFlag())
5636    {
5637      m_pcEntropyCoder->encodeCUTransquantBypassFlag(pcCU, 0, true);
5638    }
5639
5640    m_pcEntropyCoder->encodeSkipFlag ( pcCU, 0, true );
5641    m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
5642    m_pcEntropyCoder->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
5643    m_pcEntropyCoder->encodePredInfo( pcCU, 0 );
5644
5645    Bool codeDeltaQp = false;
5646    Bool codeChromaQpAdj = false;
5647    m_pcEntropyCoder->encodeCoeff   ( pcCU, 0, pcCU->getDepth(0), codeDeltaQp, codeChromaQpAdj );
5648
5649    ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
5650  }
5651}
5652
5653
5654
5655
5656
5657/**
5658 * \brief Generate half-sample interpolated block
5659 *
5660 * \param pattern Reference picture ROI
5661 * \param biPred    Flag indicating whether block is for biprediction
5662 */
5663Void TEncSearch::xExtDIFUpSamplingH( TComPattern* pattern )
5664{
5665  Int width      = pattern->getROIYWidth();
5666  Int height     = pattern->getROIYHeight();
5667  Int srcStride  = pattern->getPatternLStride();
5668
5669  Int intStride = m_filteredBlockTmp[0].getStride(COMPONENT_Y);
5670  Int dstStride = m_filteredBlock[0][0].getStride(COMPONENT_Y);
5671  Pel *intPtr;
5672  Pel *dstPtr;
5673  Int filterSize = NTAPS_LUMA;
5674  Int halfFilterSize = (filterSize>>1);
5675  Pel *srcPtr = pattern->getROIY() - halfFilterSize*srcStride - 1;
5676
5677  const ChromaFormat chFmt = m_filteredBlock[0][0].getChromaFormat();
5678
5679  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[0].getAddr(COMPONENT_Y), intStride, width+1, height+filterSize, 0, false, chFmt, pattern->getBitDepthY());
5680  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[2].getAddr(COMPONENT_Y), intStride, width+1, height+filterSize, 2, false, chFmt, pattern->getBitDepthY());
5681
5682  intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + halfFilterSize * intStride + 1;
5683  dstPtr = m_filteredBlock[0][0].getAddr(COMPONENT_Y);
5684  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+0, height+0, 0, false, true, chFmt, pattern->getBitDepthY());
5685
5686  intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride + 1;
5687  dstPtr = m_filteredBlock[2][0].getAddr(COMPONENT_Y);
5688  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+0, height+1, 2, false, true, chFmt, pattern->getBitDepthY());
5689
5690  intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + halfFilterSize * intStride;
5691  dstPtr = m_filteredBlock[0][2].getAddr(COMPONENT_Y);
5692  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+1, height+0, 0, false, true, chFmt, pattern->getBitDepthY());
5693
5694  intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5695  dstPtr = m_filteredBlock[2][2].getAddr(COMPONENT_Y);
5696  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width+1, height+1, 2, false, true, chFmt, pattern->getBitDepthY());
5697}
5698
5699
5700
5701
5702
5703/**
5704 * \brief Generate quarter-sample interpolated blocks
5705 *
5706 * \param pattern    Reference picture ROI
5707 * \param halfPelRef Half-pel mv
5708 * \param biPred     Flag indicating whether block is for biprediction
5709 */
5710Void TEncSearch::xExtDIFUpSamplingQ( TComPattern* pattern, TComMv halfPelRef )
5711{
5712  Int width      = pattern->getROIYWidth();
5713  Int height     = pattern->getROIYHeight();
5714  Int srcStride  = pattern->getPatternLStride();
5715
5716  Pel *srcPtr;
5717  Int intStride = m_filteredBlockTmp[0].getStride(COMPONENT_Y);
5718  Int dstStride = m_filteredBlock[0][0].getStride(COMPONENT_Y);
5719  Pel *intPtr;
5720  Pel *dstPtr;
5721  Int filterSize = NTAPS_LUMA;
5722
5723  Int halfFilterSize = (filterSize>>1);
5724
5725  Int extHeight = (halfPelRef.getVer() == 0) ? height + filterSize : height + filterSize-1;
5726
5727  const ChromaFormat chFmt = m_filteredBlock[0][0].getChromaFormat();
5728
5729  // Horizontal filter 1/4
5730  srcPtr = pattern->getROIY() - halfFilterSize * srcStride - 1;
5731  intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y);
5732  if (halfPelRef.getVer() > 0)
5733  {
5734    srcPtr += srcStride;
5735  }
5736  if (halfPelRef.getHor() >= 0)
5737  {
5738    srcPtr += 1;
5739  }
5740  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 1, false, chFmt, pattern->getBitDepthY());
5741
5742  // Horizontal filter 3/4
5743  srcPtr = pattern->getROIY() - halfFilterSize*srcStride - 1;
5744  intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y);
5745  if (halfPelRef.getVer() > 0)
5746  {
5747    srcPtr += srcStride;
5748  }
5749  if (halfPelRef.getHor() > 0)
5750  {
5751    srcPtr += 1;
5752  }
5753  m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 3, false, chFmt, pattern->getBitDepthY());
5754
5755  // Generate @ 1,1
5756  intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5757  dstPtr = m_filteredBlock[1][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, 1, false, true, chFmt, pattern->getBitDepthY());
5763
5764  // Generate @ 3,1
5765  intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5766  dstPtr = m_filteredBlock[3][1].getAddr(COMPONENT_Y);
5767  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5768
5769  if (halfPelRef.getVer() != 0)
5770  {
5771    // Generate @ 2,1
5772    intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5773    dstPtr = m_filteredBlock[2][1].getAddr(COMPONENT_Y);
5774    if (halfPelRef.getVer() == 0)
5775    {
5776      intPtr += intStride;
5777    }
5778    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true, chFmt, pattern->getBitDepthY());
5779
5780    // Generate @ 2,3
5781    intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5782    dstPtr = m_filteredBlock[2][3].getAddr(COMPONENT_Y);
5783    if (halfPelRef.getVer() == 0)
5784    {
5785      intPtr += intStride;
5786    }
5787    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true, chFmt, pattern->getBitDepthY());
5788  }
5789  else
5790  {
5791    // Generate @ 0,1
5792    intPtr = m_filteredBlockTmp[1].getAddr(COMPONENT_Y) + halfFilterSize * intStride;
5793    dstPtr = m_filteredBlock[0][1].getAddr(COMPONENT_Y);
5794    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true, chFmt, pattern->getBitDepthY());
5795
5796    // Generate @ 0,3
5797    intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + halfFilterSize * intStride;
5798    dstPtr = m_filteredBlock[0][3].getAddr(COMPONENT_Y);
5799    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true, chFmt, pattern->getBitDepthY());
5800  }
5801
5802  if (halfPelRef.getHor() != 0)
5803  {
5804    // Generate @ 1,2
5805    intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5806    dstPtr = m_filteredBlock[1][2].getAddr(COMPONENT_Y);
5807    if (halfPelRef.getHor() > 0)
5808    {
5809      intPtr += 1;
5810    }
5811    if (halfPelRef.getVer() >= 0)
5812    {
5813      intPtr += intStride;
5814    }
5815    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, pattern->getBitDepthY());
5816
5817    // Generate @ 3,2
5818    intPtr = m_filteredBlockTmp[2].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5819    dstPtr = m_filteredBlock[3][2].getAddr(COMPONENT_Y);
5820    if (halfPelRef.getHor() > 0)
5821    {
5822      intPtr += 1;
5823    }
5824    if (halfPelRef.getVer() > 0)
5825    {
5826      intPtr += intStride;
5827    }
5828    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5829  }
5830  else
5831  {
5832    // Generate @ 1,0
5833    intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride + 1;
5834    dstPtr = m_filteredBlock[1][0].getAddr(COMPONENT_Y);
5835    if (halfPelRef.getVer() >= 0)
5836    {
5837      intPtr += intStride;
5838    }
5839    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, pattern->getBitDepthY());
5840
5841    // Generate @ 3,0
5842    intPtr = m_filteredBlockTmp[0].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride + 1;
5843    dstPtr = m_filteredBlock[3][0].getAddr(COMPONENT_Y);
5844    if (halfPelRef.getVer() > 0)
5845    {
5846      intPtr += intStride;
5847    }
5848    m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5849  }
5850
5851  // Generate @ 1,3
5852  intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5853  dstPtr = m_filteredBlock[1][3].getAddr(COMPONENT_Y);
5854  if (halfPelRef.getVer() == 0)
5855  {
5856    intPtr += intStride;
5857  }
5858  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, pattern->getBitDepthY());
5859
5860  // Generate @ 3,3
5861  intPtr = m_filteredBlockTmp[3].getAddr(COMPONENT_Y) + (halfFilterSize-1) * intStride;
5862  dstPtr = m_filteredBlock[3][3].getAddr(COMPONENT_Y);
5863  m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, pattern->getBitDepthY());
5864}
5865
5866
5867
5868
5869
5870//! set wp tables
5871Void  TEncSearch::setWpScalingDistParam( TComDataCU* pcCU, Int iRefIdx, RefPicList eRefPicListCur )
5872{
5873  if ( iRefIdx<0 )
5874  {
5875    m_cDistParam.bApplyWeight = false;
5876    return;
5877  }
5878
5879  TComSlice       *pcSlice  = pcCU->getSlice();
5880  WPScalingParam  *wp0 , *wp1;
5881
5882  m_cDistParam.bApplyWeight = ( pcSlice->getSliceType()==P_SLICE && pcSlice->testWeightPred() ) || ( pcSlice->getSliceType()==B_SLICE && pcSlice->testWeightBiPred() ) ;
5883
5884  if ( !m_cDistParam.bApplyWeight )
5885  {
5886    return;
5887  }
5888
5889  Int iRefIdx0 = ( eRefPicListCur == REF_PIC_LIST_0 ) ? iRefIdx : (-1);
5890  Int iRefIdx1 = ( eRefPicListCur == REF_PIC_LIST_1 ) ? iRefIdx : (-1);
5891
5892  getWpScaling( pcCU, iRefIdx0, iRefIdx1, wp0 , wp1 );
5893
5894  if ( iRefIdx0 < 0 )
5895  {
5896    wp0 = NULL;
5897  }
5898  if ( iRefIdx1 < 0 )
5899  {
5900    wp1 = NULL;
5901  }
5902
5903  m_cDistParam.wpCur  = NULL;
5904
5905  if ( eRefPicListCur == REF_PIC_LIST_0 )
5906  {
5907    m_cDistParam.wpCur = wp0;
5908  }
5909  else
5910  {
5911    m_cDistParam.wpCur = wp1;
5912  }
5913}
5914
5915#if SVC_EXTENSION
5916#if REF_IDX_ME_ZEROMV
5917Void TEncSearch::xPatternSearchFracDIFMv0( TComPattern* pcPatternKey,
5918                                           Pel* piRefY,
5919                                           Int iRefStride,
5920                                           TComMv* pcMvInt,
5921                                           TComMv& rcMvHalf,
5922                                           TComMv& rcMvQter,
5923#if SCALABLE_REXT
5924                                           Distortion& ruiCost     )
5925#else
5926                                           UInt& ruiCost     )
5927#endif
5928{
5929  assert(pcMvInt->getHor() == 0 && pcMvInt->getVer() == 0);
5930  Int         iOffset    = pcMvInt->getHor() + pcMvInt->getVer() * iRefStride;
5931  m_pcRdCost->setDistParam( pcPatternKey, piRefY + iOffset, iRefStride, 1, m_cDistParam, m_pcEncCfg->getUseHADME() );
5932  m_pcRdCost->setCostScale ( 2 );
5933  setDistParamComp(COMPONENT_Y);
5934  ruiCost = m_cDistParam.DistFunc( &m_cDistParam );  //SATD
5935  ruiCost += m_pcRdCost->getCostOfVectorWithPredictor( pcMvInt->getHor(), pcMvInt->getVer() );  //SATD rdCost
5936  rcMvHalf.setZero();
5937  rcMvQter.setZero();
5938}
5939#endif
5940
5941#if ENCODER_FAST_MODE
5942Bool TEncSearch::predInterSearchILRUni( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv*& rpcPredYuv, TComYuv*& rpcResiYuv, TComYuv*& rpcRecoYuv, UInt refLayerId )
5943{
5944  rpcPredYuv->clear();
5945  rpcRecoYuv->clear();
5946
5947  Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
5948
5949  TComMv        cMv[2];
5950  TComMv        cMvPred[2][33];
5951  TComMv        cMvTemp[2][33];
5952  TComMv        TempMv;
5953
5954  Int           iRefIdx[2]={0,0};
5955
5956  Int           aaiMvpIdx[2][33];
5957  Int           aaiMvpNum[2][33];
5958
5959  UInt          uiMbBits[3] = {1, 1, 0};
5960  UInt          uiLastMode = 0;
5961
5962#if SCALABLE_REXT
5963  Distortion    uiCost[2]   = { MAX_UINT, MAX_UINT };     //uni, rdCost
5964  Distortion    uiCostTemp;
5965  Distortion    biPDistTemp = MAX_INT;
5966#else
5967  UInt          uiCost[2]   = { MAX_UINT, MAX_UINT };     //uni, rdCost
5968  UInt          uiCostTemp;
5969  UInt          biPDistTemp = MAX_INT;
5970#endif
5971  UInt          uiBitsTemp;
5972
5973  PartSize      ePartSize = pcCU->getPartitionSize( 0 );  //2Nx2N
5974  Int           iPartIdx  = 0;                            //one PU in CU
5975  UInt          uiPartAddr;
5976  Int           iRoiWidth, iRoiHeight;
5977  Bool          bILRSearched = false;
5978
5979  xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);
5980  pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
5981
5982  for( Int iRefList = 0; iRefList < iNumPredDir; iRefList++)  //list
5983  {
5984    if(bILRSearched)
5985    {
5986      continue;
5987    }
5988
5989    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
5990
5991    Int  iRefIdxTemp = -1;
5992    Bool foundILR    = false;
5993
5994    for( Int refIdx = 0; refIdx < pcCU->getSlice()->getNumRefIdx(eRefPicList); refIdx++ )
5995    {
5996      TComPic* refPic = pcCU->getSlice()->getRefPic(eRefPicList, refIdx);
5997
5998      // ILRP has to be for the sample prediction type
5999      if( refPic->isILR(pcCU->getPic()->getLayerId()) && refPic->getLayerId() == refLayerId && pcCU->getSlice()->getVPS()->isSamplePredictionType( pcCU->getPic()->getLayerIdx(), pcCU->getSlice()->getVPS()->getLayerIdxInVps(refLayerId) ) )
6000      {
6001        iRefIdxTemp = refIdx;
6002        foundILR    = true;
6003        bILRSearched = true;
6004        break;
6005      }
6006    }
6007
6008    if(!foundILR)  //no ILR in eRefPiclist
6009    {
6010      continue; 
6011    }   
6012
6013    uiBitsTemp = uiMbBits[iRefList];
6014    if ( pcCU->getSlice()->getNumRefIdx(eRefPicList) > 1 ) 
6015    { 
6016      uiBitsTemp += iRefIdxTemp+1; 
6017      if ( iRefIdxTemp == pcCU->getSlice()->getNumRefIdx(eRefPicList)-1 )
6018      {
6019        uiBitsTemp--;
6020      }
6021    }
6022
6023    xEstimateMvPredAMVP( pcCU, pcOrgYuv, iPartIdx, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], false, &biPDistTemp);
6024    aaiMvpIdx[iRefList][iRefIdxTemp] = pcCU->getMVPIdx(eRefPicList, uiPartAddr);
6025    aaiMvpNum[iRefList][iRefIdxTemp] = pcCU->getMVPNum(eRefPicList, uiPartAddr);
6026
6027    uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS];
6028
6029    xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
6030    xCheckBestMVP(pcCU, eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp);
6031
6032    if( uiCostTemp < uiCost[iRefList] )
6033    {
6034      uiCost[iRefList] = uiCostTemp;
6035
6036      cMv[iRefList]     = cMvTemp[iRefList][iRefIdxTemp];
6037      iRefIdx[iRefList] = iRefIdxTemp;
6038
6039      pcCU->getCUMvField(eRefPicList)->setAllMv( cMv[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
6040      pcCU->getCUMvField(eRefPicList)->setAllRefIdx( iRefIdx[iRefList], ePartSize, uiPartAddr, 0, iPartIdx );
6041    }
6042  }
6043
6044  if( uiCost[0] == MAX_UINT && uiCost[1] == MAX_UINT )  //no ILR in both list0 and list1
6045  {
6046    return false;
6047  }
6048
6049  //  Clear Motion Field
6050  pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
6051  pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField( TComMvField(), ePartSize, uiPartAddr, 0, iPartIdx ); 
6052  pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx ); 
6053  pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd    ( TComMv(),      ePartSize, uiPartAddr, 0, iPartIdx );
6054
6055  pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6056  pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6057  pcCU->setMVPIdxSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6058  pcCU->setMVPNumSubParts( -1, REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
6059
6060  if( uiCost[0] <= uiCost[1] )  //list0 ILR
6061  {
6062    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMv    ( cMv[0], ePartSize, uiPartAddr, 0, iPartIdx );
6063    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllRefIdx( iRefIdx[0], ePartSize, uiPartAddr, 0, iPartIdx );
6064
6065    TempMv = cMv[0] - cMvPred[0][iRefIdx[0]]; 
6066    pcCU->getCUMvField(REF_PIC_LIST_0)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
6067
6068    pcCU->setInterDirSubParts( 1, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
6069
6070    pcCU->setMVPIdxSubParts( aaiMvpIdx[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6071    pcCU->setMVPNumSubParts( aaiMvpNum[0][iRefIdx[0]], REF_PIC_LIST_0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
6072  }
6073  else if( uiCost[1] < uiCost[0] )  //list1 ILR
6074  {
6075    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMv    ( cMv[1], ePartSize, uiPartAddr, 0, iPartIdx );
6076    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllRefIdx( iRefIdx[1], ePartSize, uiPartAddr, 0, iPartIdx );
6077
6078    TempMv = cMv[1] - cMvPred[1][iRefIdx[1]]; 
6079    pcCU->getCUMvField(REF_PIC_LIST_1)->setAllMvd( TempMv, ePartSize, uiPartAddr, 0, iPartIdx );
6080
6081    pcCU->setInterDirSubParts( 2, uiPartAddr, iPartIdx, pcCU->getDepth(0) );
6082
6083    pcCU->setMVPIdxSubParts( aaiMvpIdx[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr)); 
6084    pcCU->setMVPNumSubParts( aaiMvpNum[1][iRefIdx[1]], REF_PIC_LIST_1, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr));
6085  }
6086  else
6087  {
6088    assert(0);
6089  }
6090
6091  pcCU->setMergeFlagSubParts( false, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) );
6092
6093  motionCompensation ( pcCU, rpcPredYuv, REF_PIC_LIST_X, iPartIdx );
6094  setWpScalingDistParam( pcCU, -1, REF_PIC_LIST_X );
6095
6096  return true;
6097}
6098#endif
6099#endif //SVC_EXTENSION
6100
6101//! \}
Note: See TracBrowser for help on using the repository browser.