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

Last change on this file since 1487 was 1487, checked in by fujitsu, 8 years ago

Added support of scalable range extension profiles. Also corrected few issues such as the confWindow wrong initialization. Code is controlled by the macro SCALABLE_REXT.

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