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

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

infer parameters in SPS after activation, fixing chroma scaling for non 4:2:0

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