source: 3DVCSoftware/branches/0.2-poznan-univ/source/Lib/TLibEncoder/TEncCu.cpp @ 10

Last change on this file since 10 was 5, checked in by hhi, 13 years ago

Clean version with cfg-files

  • Property svn:eol-style set to native
File size: 57.8 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2011, 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 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
35/** \file     TEncCU.cpp
36    \brief    CU encoder class
37*/
38
39#include <stdio.h>
40#include "TEncTop.h"
41#include "TEncCu.h"
42#include "TEncAnalyze.h"
43
44// ====================================================================================================================
45// Constructor / destructor / create / destroy
46// ====================================================================================================================
47
48/**
49 \param    uiTotalDepth  total number of allowable depth
50 \param    uiMaxWidth    largest CU width
51 \param    uiMaxHeight   largest CU height
52 */
53Void TEncCu::create(UChar uhTotalDepth, UInt uiMaxWidth, UInt uiMaxHeight)
54{
55  Int i;
56
57  m_uhTotalDepth   = uhTotalDepth + 1;
58  m_ppcBestCU      = new TComDataCU*[m_uhTotalDepth-1];
59  m_ppcTempCU      = new TComDataCU*[m_uhTotalDepth-1];
60
61  m_ppcPredYuvBest = new TComYuv*[m_uhTotalDepth-1];
62  m_ppcResiYuvBest = new TComYuv*[m_uhTotalDepth-1];
63  m_ppcRecoYuvBest = new TComYuv*[m_uhTotalDepth-1];
64  m_ppcPredYuvTemp = new TComYuv*[m_uhTotalDepth-1];
65  m_ppcResiYuvTemp = new TComYuv*[m_uhTotalDepth-1];
66  m_ppcRecoYuvTemp = new TComYuv*[m_uhTotalDepth-1];
67  m_ppcOrigYuv     = new TComYuv*[m_uhTotalDepth-1];
68  m_ppcResPredTmp  = new TComYuv*[m_uhTotalDepth-1];
69
70#if HHI_MPI
71  m_puhDepthSaved  = new UChar[1ll<<( ( m_uhTotalDepth - 1 )<<1 )];
72  m_puhWidthSaved  = new UChar[1ll<<( ( m_uhTotalDepth - 1 )<<1 )];
73  m_puhHeightSaved = new UChar[1ll<<( ( m_uhTotalDepth - 1 )<<1 )];
74#endif
75  UInt uiNumPartitions;
76  for( i=0 ; i<m_uhTotalDepth-1 ; i++)
77  {
78    uiNumPartitions = 1<<( ( m_uhTotalDepth - i - 1 )<<1 );
79    UInt uiWidth  = uiMaxWidth  >> i;
80    UInt uiHeight = uiMaxHeight >> i;
81
82    m_ppcBestCU[i] = new TComDataCU; m_ppcBestCU[i]->create( uiNumPartitions, uiWidth, uiHeight, false );
83    m_ppcTempCU[i] = new TComDataCU; m_ppcTempCU[i]->create( uiNumPartitions, uiWidth, uiHeight, false );
84
85    m_ppcPredYuvBest[i] = new TComYuv; m_ppcPredYuvBest[i]->create(uiWidth, uiHeight);
86    m_ppcResiYuvBest[i] = new TComYuv; m_ppcResiYuvBest[i]->create(uiWidth, uiHeight);
87    m_ppcRecoYuvBest[i] = new TComYuv; m_ppcRecoYuvBest[i]->create(uiWidth, uiHeight);
88
89    m_ppcPredYuvTemp[i] = new TComYuv; m_ppcPredYuvTemp[i]->create(uiWidth, uiHeight);
90    m_ppcResiYuvTemp[i] = new TComYuv; m_ppcResiYuvTemp[i]->create(uiWidth, uiHeight);
91    m_ppcRecoYuvTemp[i] = new TComYuv; m_ppcRecoYuvTemp[i]->create(uiWidth, uiHeight);
92
93    m_ppcOrigYuv    [i] = new TComYuv; m_ppcOrigYuv    [i]->create(uiWidth, uiHeight);
94
95    m_ppcResPredTmp [i] = new TComYuv; m_ppcResPredTmp [i]->create(uiWidth, uiHeight);
96  }
97
98  // initialize partition order.
99  UInt* piTmp = &g_auiZscanToRaster[0];
100  initZscanToRaster( m_uhTotalDepth, 1, 0, piTmp);
101  initRasterToZscan( uiMaxWidth, uiMaxHeight, m_uhTotalDepth );
102
103  // initialize conversion matrix from partition index to pel
104  initRasterToPelXY( uiMaxWidth, uiMaxHeight, m_uhTotalDepth );
105}
106
107Void TEncCu::destroy()
108{
109  Int i;
110
111#if HHI_MPI
112  delete[] m_puhDepthSaved;  m_puhDepthSaved  = NULL;
113  delete[] m_puhWidthSaved;  m_puhWidthSaved  = NULL;
114  delete[] m_puhHeightSaved; m_puhHeightSaved = NULL;
115#endif
116  for( i=0 ; i<m_uhTotalDepth-1 ; i++)
117  {
118    if(m_ppcBestCU[i])
119    {
120      m_ppcBestCU[i]->destroy();      delete m_ppcBestCU[i];      m_ppcBestCU[i] = NULL;
121    }
122    if(m_ppcTempCU[i])
123    {
124      m_ppcTempCU[i]->destroy();      delete m_ppcTempCU[i];      m_ppcTempCU[i] = NULL;
125    }
126    if(m_ppcPredYuvBest[i])
127    {
128      m_ppcPredYuvBest[i]->destroy(); delete m_ppcPredYuvBest[i]; m_ppcPredYuvBest[i] = NULL;
129    }
130    if(m_ppcResiYuvBest[i])
131    {
132      m_ppcResiYuvBest[i]->destroy(); delete m_ppcResiYuvBest[i]; m_ppcResiYuvBest[i] = NULL;
133    }
134    if(m_ppcRecoYuvBest[i])
135    {
136      m_ppcRecoYuvBest[i]->destroy(); delete m_ppcRecoYuvBest[i]; m_ppcRecoYuvBest[i] = NULL;
137    }
138    if(m_ppcPredYuvTemp[i])
139    {
140      m_ppcPredYuvTemp[i]->destroy(); delete m_ppcPredYuvTemp[i]; m_ppcPredYuvTemp[i] = NULL;
141    }
142    if(m_ppcResiYuvTemp[i])
143    {
144      m_ppcResiYuvTemp[i]->destroy(); delete m_ppcResiYuvTemp[i]; m_ppcResiYuvTemp[i] = NULL;
145    }
146    if(m_ppcRecoYuvTemp[i])
147    {
148      m_ppcRecoYuvTemp[i]->destroy(); delete m_ppcRecoYuvTemp[i]; m_ppcRecoYuvTemp[i] = NULL;
149    }
150    if(m_ppcOrigYuv[i])
151    {
152      m_ppcOrigYuv[i]->destroy();     delete m_ppcOrigYuv[i];     m_ppcOrigYuv[i] = NULL;
153    }
154    if(m_ppcResPredTmp[i])
155    {
156      m_ppcResPredTmp [i]->destroy(); delete m_ppcResPredTmp[i];  m_ppcResPredTmp[i] = NULL;
157    }
158  }
159  if(m_ppcBestCU)
160  {
161    delete [] m_ppcBestCU;
162    m_ppcBestCU = NULL;
163  }
164  if(m_ppcTempCU)
165  {
166    delete [] m_ppcTempCU;
167    m_ppcTempCU = NULL;
168  }
169
170  if(m_ppcPredYuvBest)
171  {
172    delete [] m_ppcPredYuvBest;
173    m_ppcPredYuvBest = NULL;
174  }
175  if(m_ppcResiYuvBest)
176  {
177    delete [] m_ppcResiYuvBest;
178    m_ppcResiYuvBest = NULL;
179  }
180  if(m_ppcRecoYuvBest)
181  {
182    delete [] m_ppcRecoYuvBest;
183    m_ppcRecoYuvBest = NULL;
184  }
185  if(m_ppcPredYuvTemp)
186  {
187    delete [] m_ppcPredYuvTemp;
188    m_ppcPredYuvTemp = NULL;
189  }
190  if(m_ppcResiYuvTemp)
191  {
192    delete [] m_ppcResiYuvTemp;
193    m_ppcResiYuvTemp = NULL;
194  }
195  if(m_ppcRecoYuvTemp)
196  {
197    delete [] m_ppcRecoYuvTemp;
198    m_ppcRecoYuvTemp = NULL;
199  }
200  if(m_ppcOrigYuv)
201  {
202    delete [] m_ppcOrigYuv;
203    m_ppcOrigYuv = NULL;
204  }
205  if(m_ppcResPredTmp)
206  {
207    delete [] m_ppcResPredTmp;
208    m_ppcResPredTmp = NULL;
209  }
210}
211
212/** \param    pcEncTop      pointer of encoder class
213 */
214Void TEncCu::init( TEncTop* pcEncTop )
215{
216  m_pcEncCfg           = pcEncTop;
217  m_pcEncTop           = pcEncTop;
218  m_pcPredSearch       = pcEncTop->getPredSearch();
219  m_pcTrQuant          = pcEncTop->getTrQuant();
220  m_pcBitCounter       = pcEncTop->getBitCounter();
221  m_pcRdCost           = pcEncTop->getRdCost();
222
223  m_pcEntropyCoder     = pcEncTop->getEntropyCoder();
224  m_pcCavlcCoder       = pcEncTop->getCavlcCoder();
225  m_pcSbacCoder       = pcEncTop->getSbacCoder();
226  m_pcBinCABAC         = pcEncTop->getBinCABAC();
227
228  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
229  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
230
231  m_bUseSBACRD        = pcEncTop->getUseSBACRD();
232}
233
234// ====================================================================================================================
235// Public member functions
236// ====================================================================================================================
237
238/** \param  rpcCU pointer of CU data class
239 */
240Void TEncCu::compressCU( TComDataCU*& rpcCU )
241{
242  // single-QP coding mode
243  if ( rpcCU->getSlice()->getSPS()->getUseDQP() == false )
244  {
245    // initialize CU data
246    m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
247    m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
248
249    // analysis of CU
250    xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 );
251  }
252  // multiple-QP coding mode
253  else
254  {
255    Int iQP  = rpcCU->getSlice()->getSliceQp();
256    Int idQP = m_pcEncCfg->getMaxDeltaQP();
257    Int i;
258    Int iBestQP = iQP;
259    Double fBestCost = MAX_DOUBLE;
260
261    rpcCU->getSlice()->setSliceQp( iQP );
262    m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
263    m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
264    m_ppcBestCU[0]->setQPSubParts( iQP, 0, 0 );
265    m_ppcTempCU[0]->setQPSubParts( iQP, 0, 0 );
266
267    // first try
268    xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 );
269
270    // for non-zero residual case
271    if ( !( m_ppcBestCU[0]->isSkipped( 0 ) && m_ppcBestCU[0]->getDepth( 0 ) == 0 ) )
272    {
273      // add dQP bits
274      m_pcEntropyCoder->resetBits();
275      m_pcEntropyCoder->encodeQP( m_ppcBestCU[0], 0, false );
276      m_ppcBestCU[0]->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
277
278
279#if HHI_VSO
280      if ( m_pcRdCost->getUseLambdaScaleVSO() )
281      {
282        m_ppcBestCU[0]->getTotalCost() = m_pcRdCost->calcRdCostVSO( m_ppcBestCU[0]->getTotalBits(), m_ppcBestCU[0]->getTotalDistortion() );
283      }
284      else
285#endif
286      {
287        m_ppcBestCU[0]->getTotalCost()  = m_pcRdCost->calcRdCost( m_ppcBestCU[0]->getTotalBits(), m_ppcBestCU[0]->getTotalDistortion() );
288      }
289
290      fBestCost = m_ppcBestCU[0]->getTotalCost();
291
292      // try every case
293      for ( i=iQP-idQP; i<=iQP+idQP; i++ )
294      {
295        if ( i == iQP ) continue;
296
297        rpcCU->getSlice()->setSliceQp( i );
298        m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
299        m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
300        m_ppcBestCU[0]->setQPSubParts( i, 0, 0 );
301        m_ppcTempCU[0]->setQPSubParts( i, 0, 0 );
302
303        xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 );
304
305        // add dQP bits
306        rpcCU->getSlice()->setSliceQp( iQP );
307        m_pcEntropyCoder->resetBits();
308        m_pcEntropyCoder->encodeQP( m_ppcBestCU[0], 0, false );
309        m_ppcBestCU[0]->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
310
311#if HHI_VSO
312        if (m_pcRdCost->getUseLambdaScaleVSO())
313        {
314          m_ppcBestCU[0]->getTotalCost()  = m_pcRdCost->calcRdCostVSO( m_ppcBestCU[0]->getTotalBits(), m_ppcBestCU[0]->getTotalDistortion() );
315        }
316        else
317#endif
318        {
319          m_ppcBestCU[0]->getTotalCost()  = m_pcRdCost->calcRdCost( m_ppcBestCU[0]->getTotalBits(), m_ppcBestCU[0]->getTotalDistortion() );
320        }
321
322        if ( fBestCost > m_ppcBestCU[0]->getTotalCost() )
323        {
324          fBestCost = m_ppcBestCU[0]->getTotalCost();
325          iBestQP   = i;
326        }
327      }
328
329      // perform best case
330      rpcCU->getSlice()->setSliceQp( iBestQP );
331      m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
332      m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );
333      m_ppcBestCU[0]->setQPSubParts( iBestQP, 0, 0 );
334      m_ppcTempCU[0]->setQPSubParts( iBestQP, 0, 0 );
335
336      xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 );
337
338      // add dQP bits
339      rpcCU->getSlice()->setSliceQp( iQP );
340      m_pcEntropyCoder->resetBits();
341      m_pcEntropyCoder->encodeQP( m_ppcBestCU[0], 0, false );
342      m_ppcBestCU[0]->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
343
344#if HHI_VSO
345      if (m_pcRdCost->getUseLambdaScaleVSO())
346      {
347        m_ppcBestCU[0]->getTotalCost()  = m_pcRdCost->calcRdCostVSO( m_ppcBestCU[0]->getTotalBits(), m_ppcBestCU[0]->getTotalDistortion() );
348      }
349      else
350#endif
351      {
352        m_ppcBestCU[0]->getTotalCost()  = m_pcRdCost->calcRdCost( m_ppcBestCU[0]->getTotalBits(), m_ppcBestCU[0]->getTotalDistortion() );
353      }
354    }
355  }
356}
357
358/** \param  pcCU  pointer of CU data class, bForceTerminate when set to true terminates slice (default is false).
359 */
360Void TEncCu::encodeCU ( TComDataCU* pcCU, Bool bForceTerminate )
361{
362#if SNY_DQP
363  if ( pcCU->getSlice()->getSPS()->getUseDQP() )
364  {
365    pcCU->setdQPFlag(true);
366  }
367#endif//SNY_DQP
368  // encode CU data
369  xEncodeCU( pcCU, 0, 0 );
370
371#if SNY_DQP
372  // dQP: only for LCU
373  if ( pcCU->getSlice()->getSPS()->getUseDQP() )
374  {
375    if ( pcCU->isSkipped( 0 ) && pcCU->getDepth( 0 ) == 0 )
376    {
377    }
378    else if ( pcCU->getdQPFlag())// non-skip
379    {
380
381      m_pcEntropyCoder->encodeQP( pcCU, 0 );
382      pcCU->setdQPFlag(false);
383    }
384  }
385#else
386  // dQP: only for LCU
387  if ( pcCU->getSlice()->getSPS()->getUseDQP() )
388  {
389    if ( pcCU->isSkipped( 0 ) && pcCU->getDepth( 0 ) == 0 )
390    {
391    }
392    else
393    {
394      m_pcEntropyCoder->encodeQP( pcCU, 0 );
395    }
396  }
397#endif//SNY_DQP
398
399  //--- write terminating bit ---
400  Bool bTerminateSlice = bForceTerminate;
401  UInt uiCUAddr = pcCU->getAddr();
402
403  if (uiCUAddr == (pcCU->getPic()->getNumCUsInFrame()-1) )
404    bTerminateSlice = true;
405
406  if (uiCUAddr == (pcCU->getSlice()->getSliceCurEndCUAddr()-1))
407    bTerminateSlice = true;
408
409  m_pcEntropyCoder->encodeTerminatingBit( bTerminateSlice ? 1 : 0 );
410
411  // Encode slice finish
412  if ( bTerminateSlice )
413  {
414    m_pcEntropyCoder->encodeSliceFinish();
415  }
416}
417
418// ====================================================================================================================
419// Protected member functions
420// ====================================================================================================================
421
422Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth )
423{
424  TComPic* pcPic = rpcBestCU->getPic();
425
426  // get Original YUV data from picture
427  m_ppcOrigYuv[uiDepth]->copyFromPicYuv( pcPic->getPicYuvOrg(), rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
428
429  // variables for fast encoder decision
430  TComDataCU* pcTempCU;
431  Bool    bEarlySkip  = false;
432  Bool    bTrySplit    = true;
433  Double  fRD_Skip    = MAX_DOUBLE;
434
435  static  Double  afCost[ MAX_CU_DEPTH ];
436  static  Int      aiNum [ MAX_CU_DEPTH ];
437
438  if ( rpcBestCU->getAddr() == 0 )
439  {
440    ::memset( afCost, 0, sizeof( afCost ) );
441    ::memset( aiNum,  0, sizeof( aiNum  ) );
442  }
443
444  Bool bBoundary = false;
445  UInt uiLPelX   = rpcBestCU->getCUPelX();
446  UInt uiRPelX   = uiLPelX + rpcBestCU->getWidth(0)  - 1;
447  UInt uiTPelY   = rpcBestCU->getCUPelY();
448  UInt uiBPelY   = uiTPelY + rpcBestCU->getHeight(0) - 1;
449
450#if ( HHI_INTERVIEW_SKIP)
451  Bool bFullyRenderedSec = true ;
452  if( m_pcEncCfg->getInterViewSkip() )
453  {
454    Pel* pUsedSamples ;
455    UInt uiStride ;
456    pUsedSamples =  pcPic->getUsedPelsMap()->getLumaAddr( rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
457    uiStride = pcPic->getUsedPelsMap()->getStride();
458
459    for ( Int y=0; y<m_ppcOrigYuv[uiDepth]->getHeight(); y++)
460    {
461      for ( Int x=0; x<m_ppcOrigYuv[uiDepth]->getWidth(); x++)
462      {
463        if( pUsedSamples[x] !=0 )
464        {
465          bFullyRenderedSec = false ;
466          break ;
467        }
468      }
469      if ( !bFullyRenderedSec )
470      {
471        break;
472      }
473      pUsedSamples += uiStride ;
474    }
475  }
476  else
477  {
478    bFullyRenderedSec = false ;
479  }
480#if HHI_INTERVIEW_SKIP_LAMBDA_SCALE
481  if( bFullyRenderedSec )
482  {
483    m_pcRdCost->setLambdaScale( m_pcEncCfg->getInterViewSkipLambdaScale() );
484  }
485  else
486  {
487    m_pcRdCost->setLambdaScale( 1 );
488  }
489  rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
490#endif
491
492#endif
493  if( ( uiRPelX < rpcBestCU->getSlice()->getSPS()->getWidth() ) && ( uiBPelY < rpcBestCU->getSlice()->getSPS()->getHeight() ) )
494  {
495    // do inter modes
496    if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
497    {
498#if HHI_INTER_VIEW_RESIDUAL_PRED
499      // check availability of residual prediction
500      Bool  bResPredAvailable   = false;
501      Bool  bResPredAllowed     =                    (!rpcBestCU->getSlice()->getSPS()->isDepth                () );
502      bResPredAllowed           = bResPredAllowed && ( rpcBestCU->getSlice()->getSPS()->getViewId              () );
503      bResPredAllowed           = bResPredAllowed && ( rpcBestCU->getSlice()->getSPS()->getMultiviewResPredMode() );
504      if( bResPredAllowed )
505      {
506        bResPredAvailable       = rpcBestCU->getResidualSamples( 0, m_ppcResPredTmp[uiDepth] );
507      }
508
509      for( UInt uiResPrdId = 0; uiResPrdId < ( bResPredAvailable ? 2 : 1 ); uiResPrdId++ )
510      {
511        Bool bResPredFlag  = ( uiResPrdId > 0 );
512#endif
513
514      // SKIP
515      pcTempCU = rpcTempCU;
516
517      if( pcPic->getSlice(0)->getSPS()->getUseMRG() )
518      {
519#if !HHI_MRG_SKIP
520#if HHI_INTER_VIEW_RESIDUAL_PRED
521        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
522#endif
523        xCheckRDCostAMVPSkip ( rpcBestCU, rpcTempCU );        rpcTempCU->initEstData();
524#endif
525#if HHI_INTER_VIEW_RESIDUAL_PRED
526        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
527#endif
528#if HHI_INTERVIEW_SKIP
529        xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, bFullyRenderedSec );            rpcTempCU->initEstData();
530#else
531        xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU );            rpcTempCU->initEstData();
532#endif
533      }
534      else
535      {
536#if HHI_INTER_VIEW_RESIDUAL_PRED
537        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
538#endif
539        xCheckRDCostAMVPSkip ( rpcBestCU, rpcTempCU );        rpcTempCU->initEstData();
540      }
541
542      // fast encoder decision for early skip
543      if ( m_pcEncCfg->getUseFastEnc() )
544      {
545        Int iIdx = g_aucConvertToBit[ rpcBestCU->getWidth(0) ];
546        if ( aiNum [ iIdx ] > 5 && fRD_Skip < EARLY_SKIP_THRES*afCost[ iIdx ]/aiNum[ iIdx ] )
547        {
548          bEarlySkip = true;
549          bTrySplit  = false;
550        }
551      }
552
553      // 2Nx2N, NxN
554      if ( !bEarlySkip )
555      {
556#if HHI_DISABLE_INTER_NxN_SPLIT
557#if HHI_INTER_VIEW_RESIDUAL_PRED
558        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
559#endif
560#if HHI_INTERVIEW_SKIP
561        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N, bFullyRenderedSec );  rpcTempCU->initEstData();
562#else
563        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData();
564#endif
565        if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth )
566        {
567#if HHI_INTER_VIEW_RESIDUAL_PRED
568          rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
569#endif
570#if HHI_INTERVIEW_SKIP
571          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N, bFullyRenderedSec );  rpcTempCU->initEstData();
572#else
573          xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN   );  rpcTempCU->initEstData();
574#endif
575        }
576#else
577#if HHI_INTER_VIEW_RESIDUAL_PRED
578        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
579#endif
580#if HHI_INTERVIEW_SKIP
581        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N, bFullyRenderedSec );  rpcTempCU->initEstData();
582#else
583        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData();
584#endif
585#if HHI_INTER_VIEW_RESIDUAL_PRED
586        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
587#endif
588#if HHI_INTERVIEW_SKIP
589        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN, bFullyRenderedSec   );  rpcTempCU->initEstData();
590#else
591        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_NxN   );  rpcTempCU->initEstData();
592#endif
593#endif
594      }
595
596#if HHI_RMP_SWITCH
597      if( pcPic->getSlice(0)->getSPS()->getUseRMP() )
598#endif
599      { // 2NxN, Nx2N
600#if HHI_INTER_VIEW_RESIDUAL_PRED
601        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
602#endif
603#if HHI_INTERVIEW_SKIP
604        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_Nx2N, bFullyRenderedSec  );  rpcTempCU->initEstData();
605#else
606        xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_Nx2N  );  rpcTempCU->initEstData();
607#endif
608#if HHI_INTER_VIEW_RESIDUAL_PRED
609        rpcTempCU->setResPredIndicator( bResPredAvailable, bResPredFlag );
610#endif
611#if HHI_INTERVIEW_SKIP
612        xCheckRDCostInter      ( rpcBestCU, rpcTempCU, SIZE_2NxN, bFullyRenderedSec  );  rpcTempCU->initEstData();
613#else
614        xCheckRDCostInter      ( rpcBestCU, rpcTempCU, SIZE_2NxN  );  rpcTempCU->initEstData();
615#endif
616      }
617
618#if HHI_INTER_VIEW_RESIDUAL_PRED
619    } // uiResPrdId
620#endif
621    }
622
623    // do normal intra modes
624    if ( !bEarlySkip )
625    {
626      // speedup for inter frames
627#if HHI_INTERVIEW_SKIP
628      if( ( rpcBestCU->getSlice()->getSliceType() == I_SLICE ||
629               rpcBestCU->getCbf( 0, TEXT_LUMA     ) != 0   ||
630               rpcBestCU->getCbf( 0, TEXT_CHROMA_U ) != 0   ||
631               rpcBestCU->getCbf( 0, TEXT_CHROMA_V ) != 0 ) && !bFullyRenderedSec ) // avoid very complex intra if it is unlikely
632#else
633      if( rpcBestCU->getSlice()->getSliceType() == I_SLICE ||
634         rpcBestCU->getCbf( 0, TEXT_LUMA     ) != 0   ||
635         rpcBestCU->getCbf( 0, TEXT_CHROMA_U ) != 0   ||
636         rpcBestCU->getCbf( 0, TEXT_CHROMA_V ) != 0     ) // avoid very complex intra if it is unlikely
637#endif
638      {
639        xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_2Nx2N ); rpcTempCU->initEstData();
640#if MTK_DISABLE_INTRA_NxN_SPLIT
641        if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth )
642#endif
643        {
644          if( rpcTempCU->getWidth(0) > ( 1 << rpcTempCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() ) )
645          {
646            xCheckRDCostIntra( rpcBestCU, rpcTempCU, SIZE_NxN   ); rpcTempCU->initEstData();
647          }
648        }
649      }
650    }
651
652    m_pcEntropyCoder->resetBits();
653    m_pcEntropyCoder->encodeSplitFlag( rpcBestCU, 0, uiDepth, true );
654    rpcBestCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
655
656#if HHI_VSO
657    if (m_pcRdCost->getUseLambdaScaleVSO())
658    {
659      rpcBestCU->getTotalCost()  = m_pcRdCost->calcRdCostVSO( rpcBestCU->getTotalBits(), rpcBestCU->getTotalDistortion() );
660    }
661    else
662#endif
663    {
664#if HHI_INTERVIEW_SKIP
665  if(  m_pcEncCfg->getInterViewSkip())
666      {
667        TComYuv*  pRec    = m_ppcRecoYuvBest[ uiDepth ];
668        TComYuv*  pOrg    = m_ppcOrigYuv    [ uiDepth ];
669        Pel*      pUsedY  = pcPic->getUsedPelsMap()->getLumaAddr( rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
670        Pel*      pUsedU  = pcPic->getUsedPelsMap()->getCbAddr  ( rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
671        Pel*      pUsedV  = pcPic->getUsedPelsMap()->getCrAddr  ( rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
672        Int       iUStrdY = pcPic->getUsedPelsMap()->getStride  ();
673        Int       iUStrdC = pcPic->getUsedPelsMap()->getCStride ();
674        UInt      uiWdt   = rpcBestCU->getWidth ( 0 );
675        UInt      uiHgt   = rpcBestCU->getHeight( 0 );
676        UInt      uiDist  = ( m_pcRdCost->getDistPart( pRec->getLumaAddr(), pRec->getStride(),  pOrg->getLumaAddr(), pOrg->getStride(),  pUsedY, iUStrdY, uiWdt,      uiHgt      )
677                            + m_pcRdCost->getDistPart( pRec->getCbAddr(),   pRec->getCStride(), pOrg->getCbAddr(),   pOrg->getCStride(), pUsedU, iUStrdC, uiWdt >> 1, uiHgt >> 1 )
678                            + m_pcRdCost->getDistPart( pRec->getCrAddr(),   pRec->getCStride(), pOrg->getCrAddr(),   pOrg->getCStride(), pUsedV, iUStrdC, uiWdt >> 1, uiHgt >> 1 ) );
679//        printf("\nD(as is) = %d,   D(new) = %d,  diff = %d", rpcBestCU->getTotalDistortion(), uiDist, Int(rpcBestCU->getTotalDistortion()-uiDist) );
680        rpcBestCU->getTotalDistortion() = uiDist;
681      }
682#endif
683      rpcBestCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcBestCU->getTotalBits(), rpcBestCU->getTotalDistortion() );
684    }
685   
686
687    // accumulate statistics for early skip
688    if ( m_pcEncCfg->getUseFastEnc() )
689    {
690      if ( rpcBestCU->isSkipped(0) )
691      {
692        Int iIdx = g_aucConvertToBit[ rpcBestCU->getWidth(0) ];
693        afCost[ iIdx ] += rpcBestCU->getTotalCost();
694        aiNum [ iIdx ] ++;
695      }
696    }
697#if HHI_MPI
698    if( rpcBestCU->getSlice()->getSPS()->getUseMVI() && rpcBestCU->getSlice()->getSliceType() != I_SLICE )
699    {
700      xCheckRDCostMvInheritance( rpcBestCU, rpcTempCU, uiDepth, false, false ); rpcTempCU->initEstData();
701      rpcTempCU->setSizeSubParts( g_uiMaxCUWidth>>uiDepth, g_uiMaxCUHeight>>uiDepth, 0, uiDepth );
702      rpcTempCU->setDepthSubParts( uiDepth, 0 );
703      xCheckRDCostMvInheritance( rpcBestCU, rpcTempCU, uiDepth, true, false );  rpcTempCU->initEstData();
704    }
705#endif
706  }
707  else
708  {
709    bBoundary = true;
710  }
711
712  // further split
713  if( bTrySplit && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth )
714  {
715#if HHI_VSO
716    // reset Model
717    if( m_pcRdCost->getUseRenModel() )
718    {
719      UInt  uiWidth     = m_ppcBestCU[uiDepth]->getWidth ( 0 );
720      UInt  uiHeight    = m_ppcBestCU[uiDepth]->getHeight( 0 );
721      Pel*  piSrc       = m_ppcOrigYuv[uiDepth]->getLumaAddr( 0 );
722      UInt  uiSrcStride = m_ppcOrigYuv[uiDepth]->getStride();
723      m_pcRdCost->setRenModelData( m_ppcBestCU[uiDepth], 0, piSrc, uiSrcStride, uiWidth, uiHeight );
724    }
725#endif
726
727    UChar       uhNextDepth         = uiDepth+1;
728    TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
729    TComDataCU* pcSubTempPartCU     = m_ppcTempCU[uhNextDepth];
730
731    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )
732    {
733      pcSubBestPartCU->initSubCU( rpcBestCU, uiPartUnitIdx, uhNextDepth );           // clear sub partition datas or init.
734      pcSubTempPartCU->initSubCU( rpcBestCU, uiPartUnitIdx, uhNextDepth );           // clear sub partition datas or init.
735
736      if( ( pcSubBestPartCU->getCUPelX() < pcSubBestPartCU->getSlice()->getSPS()->getWidth() ) && ( pcSubBestPartCU->getCUPelY() < pcSubBestPartCU->getSlice()->getSPS()->getHeight() ) )
737      {
738        if( m_bUseSBACRD )
739        {
740          if ( 0 == uiPartUnitIdx) //initialize RD with previous depth buffer
741          {
742            m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
743          }
744          else
745          {
746            m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
747          }
748        }
749
750        xCompressCU( pcSubBestPartCU, pcSubTempPartCU, uhNextDepth );
751
752#if HHI_VSO
753        if( m_pcRdCost->getUseRenModel() )
754        {
755          UInt  uiWidth     = pcSubBestPartCU->getWidth ( 0 );
756          UInt  uiHeight    = pcSubBestPartCU->getHeight( 0 );
757          Pel*  piSrc       = m_ppcRecoYuvBest[pcSubBestPartCU->getDepth(0)]->getLumaAddr( 0 );
758          UInt  uiSrcStride = m_ppcRecoYuvBest[pcSubBestPartCU->getDepth(0)]->getStride();
759          m_pcRdCost->setRenModelData( pcSubBestPartCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
760        }
761#endif
762        rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );         // Keep best part data to current temporary data.
763        xCopyYuv2Tmp( pcSubBestPartCU->getTotalNumPart()*uiPartUnitIdx, uhNextDepth );
764      }
765    }
766
767    if( !bBoundary )
768    {
769      m_pcEntropyCoder->resetBits();
770      m_pcEntropyCoder->encodeSplitFlag( rpcTempCU, 0, uiDepth, true );
771
772      rpcTempCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // split bits
773    }
774
775#if HHI_INTERVIEW_SKIP_LAMBDA_SCALE
776    if( bFullyRenderedSec )
777    {
778      m_pcRdCost->setLambdaScale( m_pcEncCfg->getInterViewSkipLambdaScale() );
779    }
780    else
781    {
782      m_pcRdCost->setLambdaScale( 1 );
783    }
784#endif
785#if HHI_VSO
786    if ( m_pcRdCost->getUseLambdaScaleVSO())
787    {
788      rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCostVSO( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
789    }
790    else
791#endif
792    {
793      rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
794    }
795
796    if( m_bUseSBACRD )
797    {
798      m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
799    }
800    xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth );                                          // RD compare current larger prediction
801
802#if HHI_VSO
803    if( m_pcRdCost->getUseRenModel() )
804    {
805      UInt  uiWidth     = rpcBestCU->getWidth ( 0 );
806      UInt  uiHeight    = rpcBestCU->getHeight( 0 );
807      Pel*  piSrc       = m_ppcRecoYuvBest[uiDepth]->getLumaAddr( 0 );
808      UInt  uiSrcStride = m_ppcRecoYuvBest[uiDepth]->getStride();
809      m_pcRdCost->setRenModelData( rpcBestCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
810    }
811#endif
812  }                                                                                  // with sub partitioned prediction.
813
814  rpcBestCU->copyToPic(uiDepth);                                                     // Copy Best data to Picture for next partition prediction.
815
816  if( bBoundary )
817    return;
818
819  xCopyYuv2Pic( rpcBestCU->getPic(), rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU(), uiDepth );   // Copy Yuv data to picture Yuv
820
821  // Assert if Best prediction mode is NONE
822  // Selected mode's RD-cost must be not MAX_DOUBLE.
823  assert( rpcBestCU->getPartitionSize ( 0 ) != SIZE_NONE  );
824  assert( rpcBestCU->getPredictionMode( 0 ) != MODE_NONE  );
825  assert( rpcBestCU->getTotalCost     (   ) != MAX_DOUBLE );
826}
827
828/** encode a CU block recursively
829 * \param pcCU
830 * \param uiAbsPartIdx
831 * \param uiDepth
832 * \returns Void
833 */
834Void TEncCu::xEncodeCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
835{
836  TComPic* pcPic = pcCU->getPic();
837
838  Bool bBoundary = false;
839  UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
840  UInt uiRPelX   = uiLPelX + (g_uiMaxCUWidth>>uiDepth)  - 1;
841  UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
842  UInt uiBPelY   = uiTPelY + (g_uiMaxCUHeight>>uiDepth) - 1;
843
844  if( ( uiRPelX < pcCU->getSlice()->getSPS()->getWidth() ) && ( uiBPelY < pcCU->getSlice()->getSPS()->getHeight() ) )
845  {
846#if HHI_MPI
847    if( pcCU->getTextureModeDepth( uiAbsPartIdx ) == -1 || uiDepth < pcCU->getTextureModeDepth( uiAbsPartIdx ) )
848#endif
849      m_pcEntropyCoder->encodeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
850  }
851  else
852  {
853    bBoundary = true;
854  }
855
856#if HHI_MPI
857  if( uiDepth == pcCU->getTextureModeDepth( uiAbsPartIdx ) )
858  {
859    xSaveDepthWidthHeight( pcCU );
860    pcCU->setSizeSubParts( g_uiMaxCUWidth>>uiDepth, g_uiMaxCUHeight>>uiDepth, uiAbsPartIdx, uiDepth );
861    pcCU->setDepthSubParts( uiDepth, uiAbsPartIdx );
862
863    if( ( uiRPelX < pcCU->getSlice()->getSPS()->getWidth() ) && ( uiBPelY < pcCU->getSlice()->getSPS()->getHeight() ) )
864      m_pcEntropyCoder->encodeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
865    if( !pcCU->getSlice()->isIntra() )
866    {
867      m_pcEntropyCoder->encodeSkipFlag( pcCU, uiAbsPartIdx );
868    }
869
870    if( pcCU->isSkipped( uiAbsPartIdx ) )
871    {
872#if HHI_MRG_SKIP
873      m_pcEntropyCoder->encodeMergeIndex( pcCU, uiAbsPartIdx, 0 );
874#else
875      if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 ) //if ( ref. frame list0 has at least 1 entry )
876      {
877        m_pcEntropyCoder->encodeMVPIdx( pcCU, uiAbsPartIdx, REF_PIC_LIST_0);
878      }
879      if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 ) //if ( ref. frame list1 has at least 1 entry )
880      {
881        m_pcEntropyCoder->encodeMVPIdx( pcCU, uiAbsPartIdx, REF_PIC_LIST_1);
882      }
883#endif
884      xRestoreDepthWidthHeight( pcCU );
885      return;
886    }
887
888    m_pcEntropyCoder->encodePredMode( pcCU, uiAbsPartIdx );
889
890    m_pcEntropyCoder->encodePartSize( pcCU, uiAbsPartIdx, uiDepth );
891
892    // prediction Info ( Intra : direction mode, Inter : Mv, reference idx )
893    m_pcEntropyCoder->encodePredInfo( pcCU, uiAbsPartIdx );
894    xRestoreDepthWidthHeight( pcCU );
895  }
896#endif
897
898  if( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < (g_uiMaxCUDepth-g_uiAddCUDepth) ) ) || bBoundary )
899  {
900    UInt uiQNumParts = ( pcPic->getNumPartInCU() >> (uiDepth<<1) )>>2;
901    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++, uiAbsPartIdx+=uiQNumParts )
902    {
903      uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
904      uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
905
906      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getWidth() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getHeight() ) )
907        xEncodeCU( pcCU, uiAbsPartIdx, uiDepth+1 );
908    }
909    return;
910  }
911
912#if TSB_ALF_HEADER
913#else
914  m_pcEntropyCoder->encodeAlfCtrlFlag( pcCU, uiAbsPartIdx );
915#endif
916
917#if HHI_MPI
918  if( !pcCU->getSlice()->isIntra() && pcCU->getTextureModeDepth( uiAbsPartIdx ) == -1 )
919#else
920  if( !pcCU->getSlice()->isIntra() )
921#endif
922  {
923    m_pcEntropyCoder->encodeSkipFlag( pcCU, uiAbsPartIdx );
924  }
925
926  if( pcCU->isSkipped( uiAbsPartIdx ) )
927  {
928#if HHI_MRG_SKIP
929    m_pcEntropyCoder->encodeMergeIndex( pcCU, uiAbsPartIdx, 0 );
930#else
931    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 ) //if ( ref. frame list0 has at least 1 entry )
932    {
933      m_pcEntropyCoder->encodeMVPIdx( pcCU, uiAbsPartIdx, REF_PIC_LIST_0);
934    }
935    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 ) //if ( ref. frame list1 has at least 1 entry )
936    {
937      m_pcEntropyCoder->encodeMVPIdx( pcCU, uiAbsPartIdx, REF_PIC_LIST_1);
938    }
939#endif
940#if HHI_INTER_VIEW_RESIDUAL_PRED
941    m_pcEntropyCoder->encodeResPredFlag( pcCU, uiAbsPartIdx, 0 );
942#endif
943    return;
944  }
945#if HHI_MPI
946  if( pcCU->getTextureModeDepth( uiAbsPartIdx ) == -1 )
947  {
948#endif
949    m_pcEntropyCoder->encodePredMode( pcCU, uiAbsPartIdx );
950
951    m_pcEntropyCoder->encodePartSize( pcCU, uiAbsPartIdx, uiDepth );
952
953    // prediction Info ( Intra : direction mode, Inter : Mv, reference idx )
954    m_pcEntropyCoder->encodePredInfo( pcCU, uiAbsPartIdx );
955
956#if HHI_INTER_VIEW_RESIDUAL_PRED
957    if( !pcCU->isIntra( uiAbsPartIdx ) )
958    {
959      m_pcEntropyCoder->encodeResPredFlag( pcCU, uiAbsPartIdx, 0 );
960    }
961#endif
962#if HHI_MPI
963  }
964#endif
965
966  // Encode Coefficients
967  m_pcEntropyCoder->encodeCoeff( pcCU, uiAbsPartIdx, uiDepth, pcCU->getWidth (uiAbsPartIdx), pcCU->getHeight(uiAbsPartIdx) );
968}
969
970Void TEncCu::xCheckRDCostSkip( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool bSkipRes )
971{
972  UChar uhDepth = rpcTempCU->getDepth( 0 );
973
974#if HHI_VSO
975  if( m_pcRdCost->getUseRenModel() )
976  {
977    UInt  uiWidth     = rpcTempCU->getWidth ( 0 );
978    UInt  uiHeight    = rpcTempCU->getHeight( 0 );
979    Pel*  piSrc       = m_ppcOrigYuv[uhDepth]->getLumaAddr( );
980    UInt  uiSrcStride = m_ppcOrigYuv[uhDepth]->getStride();
981    m_pcRdCost->setRenModelData( rpcTempCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
982  }
983#endif
984
985  rpcTempCU->setPredModeSubParts( MODE_SKIP,   0, uhDepth );
986  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N,  0, uhDepth );
987
988  m_pcPredSearch->predInterSkipSearch       ( rpcTempCU,
989                                             m_ppcOrigYuv    [uhDepth],
990                                             m_ppcPredYuvTemp[uhDepth],
991                                             m_ppcResiYuvTemp[uhDepth],
992                                             m_ppcRecoYuvTemp[uhDepth] );
993
994  m_pcPredSearch->encodeResAndCalcRdInterCU ( rpcTempCU,
995                                             m_ppcOrigYuv    [uhDepth],
996                                             m_ppcPredYuvTemp[uhDepth],
997                                             m_ppcResiYuvTemp[uhDepth],
998                                             m_ppcResiYuvBest[uhDepth],
999                                             m_ppcRecoYuvTemp[uhDepth],
1000                                             m_ppcResPredTmp [uhDepth],
1001                                             bSkipRes );
1002
1003  xCheckBestMode( rpcBestCU, rpcTempCU, uhDepth );
1004}
1005
1006/** check RD costs for a CU block encoded with merge
1007 * \param rpcBestCU
1008 * \param rpcTempCU
1009 * \returns Void
1010 */
1011#if HHI_INTERVIEW_SKIP
1012Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool bSkipRes )
1013#else
1014Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
1015#endif
1016{
1017  assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );
1018  TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
1019  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
1020  UInt uiNeighbourCandIdx[MRG_MAX_NUM_CANDS]; //MVs with same idx => same cand
1021
1022#if HHI_INTER_VIEW_RESIDUAL_PRED
1023  Bool  bResPrdAvail  = rpcTempCU->getResPredAvail( 0 );
1024  Bool  bResPrdFlag   = rpcTempCU->getResPredFlag ( 0 );
1025#endif
1026
1027  for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ++ui )
1028  {
1029    uhInterDirNeighbours[ui] = 0;
1030    uiNeighbourCandIdx[ui] = 0;
1031  }
1032  UChar uhDepth = rpcTempCU->getDepth( 0 );
1033
1034#if HHI_VSO
1035  if( m_pcRdCost->getUseRenModel() )
1036  {
1037    UInt  uiWidth     = rpcTempCU->getWidth ( 0 );
1038    UInt  uiHeight    = rpcTempCU->getHeight( 0 );
1039    Pel*  piSrc       = m_ppcOrigYuv[uhDepth]->getLumaAddr( );
1040    UInt  uiSrcStride = m_ppcOrigYuv[uhDepth]->getStride();
1041    m_pcRdCost->setRenModelData( rpcTempCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
1042  }
1043#endif
1044
1045  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
1046  rpcTempCU->getInterMergeCandidates( 0, 0, uhDepth, cMvFieldNeighbours,uhInterDirNeighbours, uiNeighbourCandIdx );
1047
1048  Bool bValidCands = false;
1049  for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; ++uiMergeCand )
1050  {
1051    if( uiNeighbourCandIdx[uiMergeCand] == ( uiMergeCand + 1 ) )
1052    {
1053#if HHI_MRG_SKIP
1054      TComYuv* pcPredYuvTemp = NULL;
1055#if HHI_INTERVIEW_SKIP
1056      for( UInt uiNoResidual = (bSkipRes ? 1:0); uiNoResidual < 2; ++uiNoResidual )
1057#else
1058      for( UInt uiNoResidual = 0; uiNoResidual < 2; ++uiNoResidual )
1059#endif
1060      {
1061#endif
1062      bValidCands = true;
1063      // set MC parameters
1064#if HHI_MRG_SKIP
1065      rpcTempCU->setPredModeSubParts( MODE_SKIP, 0, uhDepth ); // interprets depth relative to LCU level
1066#else
1067      rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth ); // interprets depth relative to LCU level
1068#endif
1069      rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
1070      rpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth ); // interprets depth relative to LCU level
1071      rpcTempCU->setMergeIndexSubParts( uiMergeCand, 0, 0, uhDepth ); // interprets depth relative to LCU level
1072      rpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth ); // interprets depth relative to LCU level
1073      for( UInt uiInner = 0; uiInner < MRG_MAX_NUM_CANDS; uiInner++ )
1074      {
1075        rpcTempCU->setNeighbourCandIdxSubParts( uiInner, uiNeighbourCandIdx[uiInner], 0, 0,uhDepth );
1076      }
1077      rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[0 + 2*uiMergeCand].getRefIdx(), SIZE_2Nx2N, 0, 0, 0 ); // interprets depth relative to rpcTempCU level
1078      rpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand].getMv(), cMvFieldNeighbours[1 + 2*uiMergeCand].getRefIdx(), SIZE_2Nx2N, 0, 0, 0 ); // interprets depth relative to rpcTempCU level
1079
1080#if HHI_INTER_VIEW_RESIDUAL_PRED
1081      rpcTempCU->setResPredAvailSubParts( bResPrdAvail, 0, 0, uhDepth );
1082      rpcTempCU->setResPredFlagSubParts ( bResPrdFlag,  0, 0, uhDepth );
1083#endif
1084
1085#if HHI_MRG_SKIP
1086      // do MC
1087#if HHI_INTERVIEW_SKIP
1088      if ( (uiNoResidual == 0) || bSkipRes ){
1089#else
1090      if ( uiNoResidual == 0 ){
1091#endif
1092        m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
1093        // save pred adress
1094        pcPredYuvTemp = m_ppcPredYuvTemp[uhDepth];
1095
1096      }
1097      else {
1098        if ( pcPredYuvTemp != m_ppcPredYuvTemp[uhDepth]) {
1099          //adress changes take best (old temp)
1100          pcPredYuvTemp = m_ppcPredYuvBest[uhDepth];
1101        }
1102      }
1103#if HHI_VSO
1104      if( m_pcRdCost->getUseRenModel() )
1105      { //Reset
1106        UInt  uiWidth     = rpcTempCU->getWidth ( 0 );
1107        UInt  uiHeight    = rpcTempCU->getHeight( 0 );
1108        Pel*  piSrc       = m_ppcOrigYuv[uhDepth]->getLumaAddr( );
1109        UInt  uiSrcStride = m_ppcOrigYuv[uhDepth]->getStride();
1110        m_pcRdCost->setRenModelData( rpcTempCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
1111      }
1112#endif
1113
1114      // estimate residual and encode everything
1115      m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,
1116                                                m_ppcOrigYuv    [uhDepth],
1117                                                pcPredYuvTemp,
1118                                                m_ppcResiYuvTemp[uhDepth],
1119                                                m_ppcResiYuvBest[uhDepth],
1120                                                m_ppcRecoYuvTemp[uhDepth],
1121                                                m_ppcResPredTmp [uhDepth],
1122                                                (uiNoResidual? true:false) );
1123      Bool bQtRootCbf = rpcTempCU->getQtRootCbf(0) == 1;
1124#else
1125      // do MC
1126      m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
1127
1128      // estimate residual and encode everything
1129      m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,
1130                                                 m_ppcOrigYuv    [uhDepth],
1131                                                 m_ppcPredYuvTemp[uhDepth],
1132                                                 m_ppcResiYuvTemp[uhDepth],
1133                                                 m_ppcResiYuvBest[uhDepth],
1134                                                 m_ppcRecoYuvTemp[uhDepth],
1135                                                 m_ppcResPredTmp [uhDepth],
1136                                                 false );
1137#endif
1138      xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth );
1139
1140      rpcTempCU->initEstData();
1141#if HHI_MRG_SKIP
1142      if (!bQtRootCbf)
1143        break;
1144      }
1145#endif
1146    }
1147  }
1148}
1149
1150#if HHI_INTERVIEW_SKIP
1151Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize, Bool bSkipRes)
1152#else
1153Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
1154#endif
1155{
1156  UChar uhDepth = rpcTempCU->getDepth( 0 );
1157
1158#if HHI_VSO
1159  if( m_pcRdCost->getUseRenModel() )
1160  {
1161    UInt  uiWidth     = rpcTempCU->getWidth ( 0 );
1162    UInt  uiHeight    = rpcTempCU->getHeight( 0 );
1163    Pel*  piSrc       = m_ppcOrigYuv[uhDepth]->getLumaAddr( );
1164    UInt  uiSrcStride = m_ppcOrigYuv[uhDepth]->getStride();
1165    m_pcRdCost->setRenModelData( rpcTempCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
1166  }
1167#endif
1168
1169  rpcTempCU->setDepthSubParts( uhDepth, 0 );
1170
1171#if HHI_INTER_VIEW_RESIDUAL_PRED
1172  Bool  bResPrdAvail  = rpcTempCU->getResPredAvail( 0 );
1173  Bool  bResPrdFlag   = rpcTempCU->getResPredFlag ( 0 );
1174#endif
1175  rpcTempCU->setPartSizeSubParts    ( SIZE_2Nx2N,   0,    uhDepth );
1176#if HHI_INTER_VIEW_RESIDUAL_PRED
1177  rpcTempCU->setResPredAvailSubParts( bResPrdAvail, 0, 0, uhDepth );
1178  rpcTempCU->setResPredFlagSubParts ( bResPrdFlag,  0, 0, uhDepth );
1179#endif
1180  rpcTempCU->setPartSizeSubParts    ( ePartSize,    0,    uhDepth );
1181  rpcTempCU->setPredModeSubParts    ( MODE_INTER,   0,    uhDepth );
1182
1183#if HHI_INTER_VIEW_RESIDUAL_PRED
1184  if( rpcTempCU->getResPredFlag( 0 ) )
1185  { // subtract residual prediction from original in motion search
1186    m_ppcOrigYuv[uhDepth]->add( m_ppcResPredTmp [uhDepth], rpcTempCU->getWidth( 0 ), rpcTempCU->getHeight( 0 ), true );
1187  }
1188#endif
1189#if HHI_INTERVIEW_SKIP
1190  m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth], bSkipRes );
1191#else
1192  m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
1193#endif
1194#if HHI_INTER_VIEW_RESIDUAL_PRED
1195  if( rpcTempCU->getResPredFlag( 0 ) )
1196  { // add residual prediction to original again
1197    m_ppcOrigYuv[uhDepth]->add( m_ppcResPredTmp [uhDepth], rpcTempCU->getWidth( 0 ), rpcTempCU->getHeight( 0 ) );
1198  }
1199#endif
1200
1201#if PART_MRG
1202  if (rpcTempCU->getWidth(0) > 8 && !rpcTempCU->getMergeFlag(0) && (ePartSize != SIZE_2Nx2N && ePartSize != SIZE_NxN))
1203  {
1204    return;
1205  }
1206#endif
1207#if HHI_INTERVIEW_SKIP
1208  m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], m_ppcResPredTmp [uhDepth],bSkipRes );
1209#else
1210  m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], m_ppcResPredTmp [uhDepth], false );
1211#endif
1212
1213#if HHI_VSO
1214  if( m_pcRdCost->getUseLambdaScaleVSO() )
1215  {
1216    rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCostVSO( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1217  }
1218  else
1219#endif
1220  {
1221    rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1222  }
1223
1224  xCheckBestMode( rpcBestCU, rpcTempCU, uhDepth );
1225}
1226
1227Void TEncCu::xCheckRDCostIntra( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize eSize )
1228{
1229  UInt uiDepth = rpcTempCU->getDepth( 0 );
1230
1231#if HHI_VSO
1232  if( m_pcRdCost->getUseRenModel() )
1233  {
1234    UInt  uiWidth     = rpcTempCU->getWidth ( 0 );
1235    UInt  uiHeight    = rpcTempCU->getHeight( 0 );
1236    Pel*  piSrc       = m_ppcOrigYuv[uiDepth]->getLumaAddr( );
1237    UInt  uiSrcStride = m_ppcOrigYuv[uiDepth]->getStride();
1238    m_pcRdCost->setRenModelData( rpcTempCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
1239  }
1240#endif
1241
1242  rpcTempCU->setPartSizeSubParts( eSize, 0, uiDepth );
1243  rpcTempCU->setPredModeSubParts( MODE_INTRA, 0, uiDepth );
1244
1245  Bool bSeparateLumaChroma = true; // choose estimation mode
1246  Dist uiPreCalcDistC      = 0;
1247  if( !bSeparateLumaChroma )
1248  {
1249    m_pcPredSearch->preestChromaPredMode( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth] );
1250  }
1251  m_pcPredSearch  ->estIntraPredQT      ( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], uiPreCalcDistC, bSeparateLumaChroma );
1252
1253#if LM_CHROMA
1254  m_ppcRecoYuvTemp[uiDepth]->copyToPicLuma(rpcTempCU->getPic()->getPicYuvRec(), rpcTempCU->getAddr(), rpcTempCU->getZorderIdxInCU() );
1255#endif
1256
1257  m_pcPredSearch  ->estIntraPredChromaQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], uiPreCalcDistC );
1258
1259  m_pcEntropyCoder->resetBits();
1260  m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, 0,          true );
1261  m_pcEntropyCoder->encodePredMode( rpcTempCU, 0,          true );
1262  m_pcEntropyCoder->encodePartSize( rpcTempCU, 0, uiDepth, true );
1263  m_pcEntropyCoder->encodePredInfo( rpcTempCU, 0,          true );
1264
1265  // Encode Coefficients
1266  m_pcEntropyCoder->encodeCoeff( rpcTempCU, 0, uiDepth, rpcTempCU->getWidth (0), rpcTempCU->getHeight(0) );
1267
1268  if( m_bUseSBACRD ) m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
1269
1270  rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
1271#if HHI_VSO
1272  if( m_pcRdCost->getUseLambdaScaleVSO())
1273  {
1274    rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCostVSO( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1275  }
1276  else
1277#endif
1278  {
1279    rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1280  }
1281
1282  xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth );
1283}
1284
1285// check whether current try is the best
1286Void TEncCu::xCheckBestMode( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UChar uhDepth )
1287{
1288  if( rpcTempCU->getTotalCost() < rpcBestCU->getTotalCost() )
1289  {
1290    TComYuv* pcYuv;
1291
1292    // Change Information data
1293    TComDataCU* pcCU = rpcBestCU;
1294    rpcBestCU = rpcTempCU;
1295    rpcTempCU = pcCU;
1296
1297    // Change Prediction data
1298    pcYuv = m_ppcPredYuvBest[uhDepth];
1299    m_ppcPredYuvBest[uhDepth] = m_ppcPredYuvTemp[uhDepth];
1300    m_ppcPredYuvTemp[uhDepth] = pcYuv;
1301
1302    // Change Reconstruction data
1303    pcYuv = m_ppcRecoYuvBest[uhDepth];
1304    m_ppcRecoYuvBest[uhDepth] = m_ppcRecoYuvTemp[uhDepth];
1305    m_ppcRecoYuvTemp[uhDepth] = pcYuv;
1306
1307    pcYuv = NULL;
1308    pcCU  = NULL;
1309
1310    if( m_bUseSBACRD )  // store temp best CI for next CU coding
1311      m_pppcRDSbacCoder[uhDepth][CI_TEMP_BEST]->store(m_pppcRDSbacCoder[uhDepth][CI_NEXT_BEST]);
1312  }
1313}
1314
1315Void TEncCu::xCheckRDCostAMVPSkip           ( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
1316{
1317  UChar uhDepth = rpcTempCU->getDepth(0);
1318
1319#if HHI_INTER_VIEW_RESIDUAL_PRED
1320  Bool  bResPrdAvail  = rpcTempCU->getResPredAvail( 0 );
1321  Bool  bResPrdFlag   = rpcTempCU->getResPredFlag ( 0 );
1322#endif
1323
1324  AMVPInfo cAMVPInfo0;
1325  cAMVPInfo0.iN = 0;
1326
1327  AMVPInfo cAMVPInfo1;
1328  cAMVPInfo1.iN = 0;
1329
1330  if (rpcTempCU->getAMVPMode(0) == AM_EXPL)
1331  {
1332    rpcTempCU->setPredModeSubParts( MODE_SKIP, 0, uhDepth );
1333    rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N,  0, uhDepth );
1334
1335    if ( rpcTempCU->getSlice()->isInterP() && rpcTempCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 )
1336    {
1337      rpcTempCU->fillMvpCand(0, 0, REF_PIC_LIST_0, 0, &cAMVPInfo0);
1338    }
1339    else if ( rpcTempCU->getSlice()->isInterB() &&
1340             rpcTempCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 &&
1341             rpcTempCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0  )
1342    {
1343      rpcTempCU->fillMvpCand(0, 0, REF_PIC_LIST_0, 0, &cAMVPInfo0);
1344      rpcTempCU->fillMvpCand(0, 0, REF_PIC_LIST_1, 0, &cAMVPInfo1);
1345    }
1346    else
1347    {
1348      assert( 0 );
1349    }
1350  }
1351
1352  Int iMVP0, iMVP1;
1353
1354  for (iMVP0 = (cAMVPInfo0.iN > 0? 0:-1); iMVP0 < cAMVPInfo0.iN; iMVP0++)
1355  {
1356    for (iMVP1 = (cAMVPInfo1.iN > 0? 0:-1); iMVP1 < cAMVPInfo1.iN; iMVP1++)
1357    {
1358      rpcTempCU->setPredModeSubParts( MODE_SKIP, 0, uhDepth );
1359      rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N,  0, uhDepth );
1360#if HHI_INTER_VIEW_RESIDUAL_PRED
1361      rpcTempCU->setResPredAvailSubParts( bResPrdAvail, 0, 0, uhDepth );
1362      rpcTempCU->setResPredFlagSubParts ( bResPrdFlag,  0, 0, uhDepth );
1363#endif
1364
1365      if (rpcTempCU->getSlice()->isInterB())
1366        rpcTempCU->setInterDirSubParts( 3, 0, 0, uhDepth );
1367
1368      rpcTempCU->setMVPIdxSubParts( iMVP0, REF_PIC_LIST_0, 0, 0, uhDepth );
1369      rpcTempCU->setMVPIdxSubParts( iMVP1, REF_PIC_LIST_1, 0, 0, uhDepth );
1370
1371      rpcTempCU->setMVPNumSubParts( cAMVPInfo0.iN, REF_PIC_LIST_0, 0, 0, uhDepth );
1372      rpcTempCU->setMVPNumSubParts( cAMVPInfo1.iN, REF_PIC_LIST_1, 0, 0, uhDepth );
1373
1374      xCopyAMVPInfo(&cAMVPInfo0, rpcTempCU->getCUMvField(REF_PIC_LIST_0)->getAMVPInfo());
1375      xCopyAMVPInfo(&cAMVPInfo1, rpcTempCU->getCUMvField(REF_PIC_LIST_1)->getAMVPInfo());
1376      xCheckRDCostSkip ( rpcBestCU, rpcTempCU, true );      rpcTempCU->initEstData();
1377    }
1378  }
1379}
1380
1381Void TEncCu::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst)
1382{
1383  pDst->iN = pSrc->iN;
1384  for (Int i = 0; i < pSrc->iN; i++)
1385  {
1386    pDst->m_acMvCand[i] = pSrc->m_acMvCand[i];
1387  }
1388}
1389
1390Void TEncCu::xCopyYuv2Pic(TComPic* rpcPic, UInt uiCUAddr, UInt uiAbsZorderIdx, UInt uiDepth)
1391{
1392  m_ppcRecoYuvBest[uiDepth]->copyToPicYuv( rpcPic->getPicYuvRec (), uiCUAddr, uiAbsZorderIdx );
1393}
1394
1395Void TEncCu::xCopyYuv2Tmp( UInt uiPartUnitIdx, UInt uiNextDepth )
1396{
1397  UInt uiCurrDepth = uiNextDepth - 1;
1398  m_ppcRecoYuvBest[uiNextDepth]->copyToPartYuv( m_ppcRecoYuvTemp[uiCurrDepth], uiPartUnitIdx );
1399}
1400
1401#if HHI_MPI
1402Void TEncCu::xCheckRDCostMvInheritance( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UChar uhTextureModeDepth, Bool bSkipResidual, Bool bRecursiveCall )
1403{
1404  assert( rpcTempCU->getSlice()->getSPS()->isDepth() );
1405  TComDataCU *pcTextureCU = rpcTempCU->getSlice()->getTexturePic()->getCU( rpcTempCU->getAddr() );
1406
1407  const UChar uhDepth  = rpcTempCU->getDepth( 0 );
1408  assert( bRecursiveCall == ( uhDepth != uhTextureModeDepth ) );
1409
1410  if( uhDepth == uhTextureModeDepth )
1411  {
1412    for( UInt ui = 0; ui < rpcTempCU->getTotalNumPart(); ui++ )
1413    {
1414      if( pcTextureCU->isIntra( rpcTempCU->getZorderIdxInCU() + ui ) )
1415      {
1416        return;
1417      }
1418    }
1419  }
1420
1421#if HHI_VSO
1422  if( m_pcRdCost->getUseRenModel() && !bRecursiveCall)
1423  {
1424    UInt  uiWidth     = m_ppcTempCU [uhDepth]->getWidth ( 0 );
1425    UInt  uiHeight    = m_ppcTempCU [uhDepth]->getHeight( 0 );
1426    Pel*  piSrc       = m_ppcOrigYuv[uhDepth]->getLumaAddr( 0 );
1427    UInt  uiSrcStride = m_ppcOrigYuv[uhDepth]->getStride();
1428    m_pcRdCost->setRenModelData( m_ppcTempCU[uhDepth], 0, piSrc, uiSrcStride, uiWidth, uiHeight );
1429  }
1430#endif
1431
1432  Bool bSplit = uhDepth < pcTextureCU->getDepth( rpcTempCU->getZorderIdxInCU() );
1433  if( bSplit )
1434  {
1435    const UChar       uhNextDepth   = uhDepth+1;
1436    TComDataCU* pcSubBestPartCU     = m_ppcBestCU[uhNextDepth];
1437    TComDataCU* pcSubTempPartCU     = m_ppcTempCU[uhNextDepth];
1438
1439    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )
1440    {
1441      pcSubBestPartCU->initSubCU( rpcBestCU, uiPartUnitIdx, uhNextDepth );           // clear sub partition datas or init.
1442      pcSubTempPartCU->initSubCU( rpcBestCU, uiPartUnitIdx, uhNextDepth );           // clear sub partition datas or init.
1443
1444      if( ( pcSubBestPartCU->getCUPelX() < pcSubBestPartCU->getSlice()->getSPS()->getWidth() ) && ( pcSubBestPartCU->getCUPelY() < pcSubBestPartCU->getSlice()->getSPS()->getHeight() ) )
1445      {
1446        if( m_bUseSBACRD )
1447        {
1448          if ( 0 == uiPartUnitIdx) //initialize RD with previous depth buffer
1449          {
1450            m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhDepth][CI_CURR_BEST]);
1451          }
1452          else
1453          {
1454            m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]);
1455          }
1456        }
1457
1458        xCheckRDCostMvInheritance( pcSubBestPartCU, pcSubTempPartCU, uhTextureModeDepth, bSkipResidual, true );
1459
1460        rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth );         // Keep best part data to current temporary data.
1461        xCopyYuv2Tmp( pcSubBestPartCU->getTotalNumPart()*uiPartUnitIdx, uhNextDepth );
1462      }
1463    }
1464
1465    if( uhDepth == uhTextureModeDepth )
1466    {
1467      xAddMVISignallingBits( rpcTempCU );
1468    }
1469
1470    if( m_bUseSBACRD )
1471    {
1472      m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->store(m_pppcRDSbacCoder[uhDepth][CI_TEMP_BEST]);
1473    }
1474  }
1475  else
1476  {
1477    rpcTempCU->setTextureModeDepthSubParts( uhTextureModeDepth, 0, uhDepth );
1478    rpcTempCU->copyTextureMotionDataFrom( pcTextureCU, uhDepth, rpcTempCU->getZorderIdxInCU() );
1479    rpcTempCU->setPartSizeSubParts( SIZE_NxN, 0, uhDepth );
1480    for( UInt ui = 0; ui < rpcTempCU->getTotalNumPart(); ui++ )
1481    {
1482      assert( rpcTempCU->getInterDir( ui ) != 0 );
1483      assert( rpcTempCU->getPredictionMode( ui ) != MODE_NONE );
1484    }
1485    rpcTempCU->setPredModeSubParts( bSkipResidual ? MODE_SKIP : MODE_INTER, 0, uhDepth );
1486    m_pcPredSearch->motionCompensation( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
1487
1488    // get Original YUV data from picture
1489    m_ppcOrigYuv[uhDepth]->copyFromPicYuv( rpcBestCU->getPic()->getPicYuvOrg(), rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
1490    m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], m_ppcResPredTmp [uhDepth], bSkipResidual );
1491
1492    if( uhDepth == uhTextureModeDepth )
1493    {
1494      xAddMVISignallingBits( rpcTempCU );
1495    }
1496  }
1497
1498#if HHI_VSO
1499  if( m_pcRdCost->getUseLambdaScaleVSO() )
1500  {
1501    rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCostVSO( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1502  }
1503  else
1504#endif
1505  {
1506    rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
1507  }
1508
1509  xCheckBestMode( rpcBestCU, rpcTempCU, uhDepth );
1510
1511#if HHI_VSO
1512  if( !bSplit && bRecursiveCall && m_pcRdCost->getUseRenModel() )
1513  {
1514    UInt  uiWidth     = rpcBestCU->getWidth ( 0 );
1515    UInt  uiHeight    = rpcBestCU->getHeight( 0 );
1516    Pel*  piSrc       = m_ppcRecoYuvBest[uhDepth]->getLumaAddr( 0 );
1517    UInt  uiSrcStride = m_ppcRecoYuvBest[uhDepth]->getStride();
1518    m_pcRdCost->setRenModelData( rpcBestCU, 0, piSrc, uiSrcStride, uiWidth, uiHeight );
1519  }
1520#endif
1521}
1522
1523Void TEncCu::xAddMVISignallingBits( TComDataCU* pcCU )
1524{
1525  const UChar uhDepth = pcCU->getTextureModeDepth( 0 );
1526  m_pcEntropyCoder->resetBits();
1527  xSaveDepthWidthHeight( pcCU );
1528  pcCU->setSizeSubParts( g_uiMaxCUWidth>>uhDepth, g_uiMaxCUHeight>>uhDepth, 0, uhDepth );
1529  pcCU->setDepthSubParts( uhDepth, 0 );
1530  pcCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth );
1531  pcCU->setMergeFlagSubParts( true, 0, 0, uhDepth );
1532  pcCU->setMergeIndexSubParts( 0, 0, 0, uhDepth );
1533
1534  {
1535    TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
1536    UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
1537    UInt uiNeighbourCandIdx[MRG_MAX_NUM_CANDS]; //MVs with same idx => same cand
1538
1539    for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ++ui )
1540    {
1541      uhInterDirNeighbours[ui] = 0;
1542      uiNeighbourCandIdx[ui] = 0;
1543    }
1544    pcCU->getInterMergeCandidates( 0, 0, uhDepth, cMvFieldNeighbours,uhInterDirNeighbours, uiNeighbourCandIdx );
1545    for( UInt uiMergeCand = 0; uiMergeCand < MRG_MAX_NUM_CANDS; uiMergeCand++ )
1546    {
1547      pcCU->setNeighbourCandIdxSubParts( uiMergeCand, uiNeighbourCandIdx[uiMergeCand], 0, 0,uhDepth );
1548    }
1549  }
1550
1551  // check for skip mode
1552  {
1553    Bool bAllZero = true;
1554    for( UInt ui = 0; ui < pcCU->getTotalNumPart(); ui++ )
1555    {
1556      if( pcCU->getCbf( ui, TEXT_LUMA ) || pcCU->getCbf( ui, TEXT_CHROMA_U ) || pcCU->getCbf( ui, TEXT_CHROMA_V ) )
1557      {
1558        bAllZero = false;
1559        break;
1560      }
1561    }
1562    if( bAllZero )
1563      pcCU->setPredModeSubParts( MODE_SKIP, 0, uhDepth );
1564  }
1565
1566
1567  m_pcEntropyCoder->encodeSplitFlag( pcCU, 0, uhDepth, true );
1568  m_pcEntropyCoder->encodeSkipFlag( pcCU, 0, true );
1569
1570  if( pcCU->isSkipped( 0 ) )
1571  {
1572#if HHI_MRG_SKIP
1573    m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, 0, true );
1574#else
1575    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_0 ) > 0 ) //if ( ref. frame list0 has at least 1 entry )
1576    {
1577      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_0, true );
1578    }
1579    if ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_1 ) > 0 ) //if ( ref. frame list1 has at least 1 entry )
1580    {
1581      m_pcEntropyCoder->encodeMVPIdx( pcCU, 0, REF_PIC_LIST_1, true );
1582    }
1583#endif
1584  }
1585  else
1586  {
1587    m_pcEntropyCoder->encodePredMode( pcCU, 0, true );
1588    m_pcEntropyCoder->encodePartSize( pcCU, 0, uhDepth, true );
1589    // prediction Info ( Intra : direction mode, Inter : Mv, reference idx )
1590    m_pcEntropyCoder->encodePredInfo( pcCU, 0, true );
1591  }
1592  xRestoreDepthWidthHeight( pcCU );
1593
1594  pcCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits();
1595}
1596
1597Void TEncCu::xSaveDepthWidthHeight( TComDataCU* pcCU )
1598{
1599  const Int iSizeInUchar  = sizeof( UChar ) * pcCU->getTotalNumPart();
1600  memcpy( m_puhDepthSaved, pcCU->getDepth(), iSizeInUchar );
1601  memcpy( m_puhWidthSaved, pcCU->getWidth(), iSizeInUchar );
1602  memcpy( m_puhHeightSaved, pcCU->getHeight(), iSizeInUchar );
1603}
1604
1605Void TEncCu::xRestoreDepthWidthHeight( TComDataCU* pcCU )
1606{
1607  const Int iSizeInUchar  = sizeof( UChar ) * pcCU->getTotalNumPart();
1608  memcpy( pcCU->getDepth(), m_puhDepthSaved, iSizeInUchar );
1609  memcpy( pcCU->getWidth(), m_puhWidthSaved, iSizeInUchar );
1610  memcpy( pcCU->getHeight(), m_puhHeightSaved, iSizeInUchar );
1611}
1612#endif
Note: See TracBrowser for help on using the repository browser.