source: 3DVCSoftware/branches/0.2-poznan-univ/source/Lib/TLibEncoder/TEncGOP.cpp

Last change on this file was 12, checked in by poznan-univ, 13 years ago

Poznan Tools

  • Depth base motion vector prediction
  • Property svn:eol-style set to native
File size: 38.7 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
36/** \file     TEncPic.cpp
37    \brief    GOP encoder class
38*/
39
40#include "TEncTop.h"
41#include "TEncGOP.h"
42#include "TEncAnalyze.h"
43#include "../libmd5/MD5.h"
44#include "../TLibCommon/SEI.h"
45
46#include <time.h>
47
48#include "../../App/TAppEncoder/TAppEncTop.h"
49
50// ====================================================================================================================
51// Constructor / destructor / initialization / destroy
52// ====================================================================================================================
53
54TEncPic::TEncPic()
55{
56  m_pcCfg               = NULL;
57  m_pcSliceEncoder      = NULL;
58  m_pcListPic           = NULL;
59
60  m_pcEntropyCoder      = NULL;
61  m_pcCavlcCoder        = NULL;
62  m_pcSbacCoder         = NULL;
63  m_pcBinCABAC          = NULL;
64#if DEPTH_MAP_GENERATION
65  m_pcDepthMapGenerator = NULL;
66#endif
67#if HHI_INTER_VIEW_RESIDUAL_PRED
68  m_pcResidualGenerator = NULL;
69#endif
70
71#if DCM_DECODING_REFRESH
72  m_bRefreshPending     = 0;
73  m_uiPOCCDR            = 0;
74#endif
75
76  return;
77}
78
79TEncPic::~TEncPic()
80{
81}
82
83/** Create list to contain pointers to LCU start addresses of slice.
84 * \param iWidth, iHeight are picture width, height. iMaxCUWidth, iMaxCUHeight are LCU width, height.
85 */
86Void  TEncPic::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight )
87{
88  UInt uiWidthInCU       = ( iWidth %iMaxCUWidth  ) ? iWidth /iMaxCUWidth  + 1 : iWidth /iMaxCUWidth;
89  UInt uiHeightInCU      = ( iHeight%iMaxCUHeight ) ? iHeight/iMaxCUHeight + 1 : iHeight/iMaxCUHeight;
90  UInt uiNumCUsInFrame   = uiWidthInCU * uiHeightInCU;
91  m_uiStoredStartCUAddrForEncodingSlice = new UInt [uiNumCUsInFrame+1];
92  m_uiStoredStartCUAddrForEncodingEntropySlice = new UInt [uiNumCUsInFrame+1];
93}
94
95Void  TEncPic::destroy()
96{
97  delete [] m_uiStoredStartCUAddrForEncodingSlice; m_uiStoredStartCUAddrForEncodingSlice = NULL;
98  delete [] m_uiStoredStartCUAddrForEncodingEntropySlice; m_uiStoredStartCUAddrForEncodingEntropySlice = NULL;
99}
100
101Void TEncPic::init ( TEncTop* pcTEncTop )
102{
103  m_pcEncTop     = pcTEncTop;
104  m_pcCfg                = pcTEncTop;
105  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
106  m_pcListPic            = pcTEncTop->getListPic();
107
108  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
109  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
110  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
111  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
112  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
113  m_pcBitCounter         = pcTEncTop->getBitCounter();
114#if DEPTH_MAP_GENERATION
115  m_pcDepthMapGenerator  = pcTEncTop->getDepthMapGenerator();
116#endif
117#if HHI_INTER_VIEW_RESIDUAL_PRED
118  m_pcResidualGenerator  = pcTEncTop->getResidualGenerator();
119#endif
120
121  // Adaptive Loop filter
122  m_pcAdaptiveLoopFilter = pcTEncTop->getAdaptiveLoopFilter();
123  //--Adaptive Loop filter
124#if MTK_SAO
125  m_pcSAO                = pcTEncTop->getSAO();
126#endif
127  m_pcRdCost             = pcTEncTop->getRdCost();
128
129}
130
131// ====================================================================================================================
132// Public member functions
133// ====================================================================================================================
134
135Void TEncPic::compressPic( TComBitstream* pcBitstreamOut, TComPicYuv cPicOrg, TComPic* pcPic, TComPicYuv* pcPicYuvRecOut,
136               TComPic* pcOrgRefList[2][MAX_REF_PIC_NUM], Bool&  rbSeqFirst, TComList<TComPic*>& rcListPic  )
137{
138  TComSlice*      pcSlice;
139
140      //-- For time output for each slice
141      long iBeforeTime = clock();
142
143      //  Bitstream reset
144      pcBitstreamOut->resetBits();
145      pcBitstreamOut->rewindStreamPacket();
146
147      //  Slice data initialization
148      pcPic->clearSliceBuffer();
149      assert(pcPic->getNumAllocatedSlice() == 1);
150      m_pcSliceEncoder->setSliceIdx(0);
151      pcPic->setCurrSliceIdx(0);
152      m_pcSliceEncoder->initEncSlice ( pcPic, pcSlice );
153      pcSlice->setSliceIdx(0);
154
155      //  Set SPS
156      pcSlice->setSPS( m_pcEncTop->getSPS() );
157      pcSlice->setPPS( m_pcEncTop->getPPS() );
158      pcSlice->setPPSId( pcSlice->getPPS()->getPPSId() );
159
160  // set mutliview parameters
161      pcSlice->initMultiviewSlice( pcPic->getCodedScale(), pcPic->getCodedOffset() );
162
163#if DCM_DECODING_REFRESH
164      // Set the nal unit type
165      if( pcSlice->getPOC() == 0 )
166        pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_IDR );
167      else
168        pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE );
169
170      //pcSlice->setNalUnitType(getNalUnitType(uiPOCCurr));
171      // Do decoding refresh marking if any
172      pcSlice->decodingRefreshMarking(m_uiPOCCDR, m_bRefreshPending, rcListPic);
173#endif
174
175// GT FIX
176  std::vector<TComPic*> apcSpatRefPics = m_pcEncTop->getEncTop()->getSpatialRefPics( pcPic->getViewIdx(), pcSlice->getPOC(), m_pcEncTop->isDepthCoder() );
177  TComPic * const pcTexturePic = m_pcEncTop->isDepthCoder() ? m_pcEncTop->getEncTop()->getPicFromView( pcPic->getViewIdx(), pcSlice->getPOC(), false ) : NULL;
178  assert( ! m_pcEncTop->isDepthCoder() || pcTexturePic != NULL );
179  pcSlice->setTexturePic( pcTexturePic );
180
181  pcSlice->setRefPicListFromGOPSTring( rcListPic, apcSpatRefPics );
182
183#if HHI_VSO
184  m_pcEncTop->getEncTop()->setMVDPic(pcPic->getViewIdx(), pcSlice->getPOC(), pcPic->getMVDReferenceInfo() );
185
186
187  Bool bUseVSO = m_pcEncTop->getUseVSO();
188  m_pcRdCost->setUseVSO( bUseVSO );
189
190  if ( bUseVSO )
191  {
192    Int iVSOMode = m_pcEncTop->getVSOMode();
193    m_pcRdCost->setVSOMode( iVSOMode  );
194#if HHI_VSO_DIST_INT
195    m_pcRdCost->setAllowNegDist( m_pcEncTop->getAllowNegDist() );
196#endif
197
198    if ( iVSOMode == 4 )
199    {
200      m_pcEncTop->getEncTop()->setupRenModel( pcSlice->getPOC(), pcPic->getViewIdx(), m_pcEncTop->isDepthCoder() ? 1 : 0 );
201    }
202    else
203  {
204    m_pcRdCost->setRefDataFromMVDInfo( pcPic->getMVDReferenceInfo() );
205  }
206  }
207#endif
208
209#if HHI_INTERVIEW_SKIP
210  if ( m_pcEncTop->getInterViewSkip() )
211  {
212    m_pcEncTop->getEncTop()->getUsedPelsMap( pcPic->getViewIdx(), pcPic->getPOC(), pcPic->getUsedPelsMap() );
213  }
214#endif
215
216      pcSlice->setNoBackPredFlag( false );
217#if DCM_COMB_LIST
218      if ( pcSlice->getSliceType() == B_SLICE && !pcSlice->getRefPicListCombinationFlag())
219#else
220      if ( pcSlice->getSliceType() == B_SLICE )
221#endif
222      {
223        if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
224        {
225          pcSlice->setNoBackPredFlag( true );
226          int i;
227          for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
228          {
229            if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
230            {
231              pcSlice->setNoBackPredFlag( false );
232              break;
233            }
234          }
235        }
236      }
237
238#if DCM_COMB_LIST
239      if(pcSlice->getNoBackPredFlag())
240      {
241        pcSlice->setNumRefIdx(REF_PIC_LIST_C, -1);
242      }
243      pcSlice->generateCombinedList();
244#endif
245
246      /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
247      //  Slice compression
248      if (m_pcCfg->getUseASR())
249      {
250        m_pcSliceEncoder->setSearchRange(pcSlice);
251      }
252#ifdef ROUNDING_CONTROL_BIPRED
253      Bool b = true;
254      if (m_pcCfg->getUseRoundingControlBipred())
255      {
256        if (m_pcCfg->getCodedPictureBufferSize()==1)
257          b = ((pcSlice->getPOC()&1)==0);
258        else
259          b = (pcSlice->isReferenced() == 0);
260      }
261
262#if HIGH_ACCURACY_BI
263      pcSlice->setRounding(false);
264#else
265      pcSlice->setRounding(b);
266#endif
267#endif
268
269      UInt uiStartCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
270      UInt uiStartCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
271      pcSlice->setSliceCurStartCUAddr( uiStartCUAddrSlice ); // Setting "start CU addr" for current slice
272      memset(m_uiStoredStartCUAddrForEncodingSlice, 0, sizeof(UInt) * (pcPic->getPicSym()->getNumberOfCUsInFrame()+1));
273
274      UInt uiStartCUAddrEntropySliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
275      UInt uiStartCUAddrEntropySlice    = 0; // used to keep track of current Entropy slice's starting CU addr.
276      pcSlice->setEntropySliceCurStartCUAddr( uiStartCUAddrEntropySlice ); // Setting "start CU addr" for current Entropy slice
277      memset(m_uiStoredStartCUAddrForEncodingEntropySlice, 0, sizeof(UInt) * (pcPic->getPicSym()->getNumberOfCUsInFrame()+1));
278
279      UInt uiNextCUAddr = 0;
280      m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx++]                = uiNextCUAddr;
281      m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = uiNextCUAddr;
282
283#if DEPTH_MAP_GENERATION
284      // init view component and predict virtual depth map
285      m_pcDepthMapGenerator->initViewComponent( pcPic );
286      m_pcDepthMapGenerator->predictDepthMap  ( pcPic );
287#if HHI_INTER_VIEW_MOTION_PRED
288      m_pcDepthMapGenerator->covertOrgDepthMap( pcPic );
289#endif
290#if HHI_INTER_VIEW_RESIDUAL_PRED
291      m_pcResidualGenerator->initViewComponent( pcPic );
292#endif
293#endif
294
295#if POZNAN_MP   
296#if POZNAN_MP_USE_DEPTH_MAP_GENERATION
297          pcSlice->getMP()->setDepthMapGenerator(m_pcDepthMapGenerator);
298#else
299      std::vector<TComPic*> apcSpatDepthRefPics = m_pcEncTop->getEncTop()->getSpatialRefPics( pcPic->getViewIdx(), pcSlice->getPOC(), true );
300          pcSlice->getMP()->setDepthRefPicsList(&apcSpatDepthRefPics);
301#endif
302          std::vector<TComPic*> apcSpatDataRefPics = m_pcEncTop->getEncTop()->getSpatialRefPics( pcPic->getViewIdx(), pcSlice->getPOC(), m_pcEncTop->isDepthCoder() );
303          pcSlice->getMP()->setRefPicsList(&apcSpatDataRefPics);
304          pcSlice->getMP()->pairMultiview(pcPic);
305#endif
306
307      while(uiNextCUAddr<pcPic->getPicSym()->getNumberOfCUsInFrame()) // determine slice boundaries
308      {
309        pcSlice->setNextSlice       ( false );
310        pcSlice->setNextEntropySlice( false );
311        assert(pcPic->getNumAllocatedSlice() == uiStartCUAddrSliceIdx);
312        m_pcSliceEncoder->precompressSlice( pcPic );
313        m_pcSliceEncoder->compressSlice   ( pcPic );
314
315        Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextEntropySlice());
316        if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE))
317        {
318          uiStartCUAddrSlice                                              = pcSlice->getSliceCurEndCUAddr();
319          // Reconstruction slice
320          m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx++]  = uiStartCUAddrSlice;
321          // Entropy slice
322          if (uiStartCUAddrEntropySliceIdx>0 && m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx-1] != uiStartCUAddrSlice)
323          {
324            m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = uiStartCUAddrSlice;
325          }
326
327          if (uiStartCUAddrSlice < pcPic->getPicSym()->getNumberOfCUsInFrame())
328          {
329            pcPic->allocateNewSlice();
330            pcPic->setCurrSliceIdx                  ( uiStartCUAddrSliceIdx-1 );
331            m_pcSliceEncoder->setSliceIdx           ( uiStartCUAddrSliceIdx-1 );
332            pcSlice = pcPic->getSlice               ( uiStartCUAddrSliceIdx-1 );
333            pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
334            pcSlice->setSliceIdx                    ( uiStartCUAddrSliceIdx-1 );
335            pcSlice->setSliceCurStartCUAddr         ( uiStartCUAddrSlice      );
336            pcSlice->setEntropySliceCurStartCUAddr  ( uiStartCUAddrSlice      );
337            pcSlice->setSliceBits(0);
338          }
339        }
340        else if (pcSlice->isNextEntropySlice() || (bNoBinBitConstraintViolated && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE))
341        {
342          uiStartCUAddrEntropySlice                                                     = pcSlice->getEntropySliceCurEndCUAddr();
343          m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = uiStartCUAddrEntropySlice;
344          pcSlice->setEntropySliceCurStartCUAddr( uiStartCUAddrEntropySlice );
345        }
346        else
347        {
348          uiStartCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
349          uiStartCUAddrEntropySlice                                                     = pcSlice->getEntropySliceCurEndCUAddr();
350        }
351
352        uiNextCUAddr = (uiStartCUAddrSlice > uiStartCUAddrEntropySlice) ? uiStartCUAddrSlice : uiStartCUAddrEntropySlice;
353      }
354      m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx++]                = pcSlice->getSliceCurEndCUAddr();
355      m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = pcSlice->getSliceCurEndCUAddr();
356
357      pcSlice = pcPic->getSlice(0);
358#if MTK_SAO  // PRE_DF
359      SAOParam cSaoParam;
360#endif
361
362#if HHI_INTER_VIEW_RESIDUAL_PRED
363      // set residual picture
364      m_pcResidualGenerator->setRecResidualPic( pcPic );
365#endif
366#if DEPTH_MAP_GENERATION
367      // update virtual depth map
368      m_pcDepthMapGenerator->updateDepthMap( pcPic );
369#endif
370
371      //-- Loop filter
372      m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), m_pcCfg->getLoopFilterAlphaC0Offget(), m_pcCfg->getLoopFilterBetaOffget());
373      m_pcLoopFilter->loopFilterPic( pcPic );
374
375#if MTK_NONCROSS_INLOOP_FILTER
376      pcSlice = pcPic->getSlice(0);
377
378      if(pcSlice->getSPS()->getUseALF())
379      {
380        if(pcSlice->getSPS()->getLFCrossSliceBoundaryFlag())
381        {
382          m_pcAdaptiveLoopFilter->setUseNonCrossAlf(false);
383        }
384        else
385        {
386          UInt uiNumSlices = uiStartCUAddrSliceIdx-1;
387          m_pcAdaptiveLoopFilter->setUseNonCrossAlf( (uiNumSlices > 1)  );
388          if(m_pcAdaptiveLoopFilter->getUseNonCrossAlf())
389          {
390            m_pcAdaptiveLoopFilter->setNumSlicesInPic( uiNumSlices );
391            m_pcAdaptiveLoopFilter->createSlice();
392
393            //set the startLCU and endLCU addr. to ALF slices
394            for(UInt i=0; i< uiNumSlices ; i++)
395            {
396              (*m_pcAdaptiveLoopFilter)[i].create(pcPic, i,
397                                                  m_uiStoredStartCUAddrForEncodingSlice[i],
398                                                  m_uiStoredStartCUAddrForEncodingSlice[i+1]-1
399                                                  );
400
401            }
402          }
403        }
404      }
405#endif
406      /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
407      // Set entropy coder
408      m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
409
410      /* write various header sets.
411       * The header sets are written into a separate bitstream buffer to
412       * allow SEI messages that are calculated after the picture has been
413       * encoded to be sent before the picture.
414       */
415      TComBitstream bs_SPS_PPS_SEI;
416      bs_SPS_PPS_SEI.create(512); /* TODO: this should dynamically resize */
417      if ( rbSeqFirst )
418      {
419        m_pcEntropyCoder->setBitstream(&bs_SPS_PPS_SEI);
420
421        m_pcEntropyCoder->encodeSPS( pcSlice->getSPS() );
422        bs_SPS_PPS_SEI.write( 1, 1 );
423        bs_SPS_PPS_SEI.writeAlignZero();
424        // generate start code
425        bs_SPS_PPS_SEI.write( 1, 32);
426
427        m_pcEntropyCoder->encodePPS( pcSlice->getPPS() );
428        bs_SPS_PPS_SEI.write( 1, 1 );
429        bs_SPS_PPS_SEI.writeAlignZero();
430        // generate start code
431        bs_SPS_PPS_SEI.write( 1, 32);
432        rbSeqFirst = false;
433      }
434
435      /* use the main bitstream buffer for storing the marshalled picture */
436      m_pcEntropyCoder->setBitstream(pcBitstreamOut);
437
438      uiStartCUAddrSliceIdx = 0;
439      uiStartCUAddrSlice    = 0;
440      pcBitstreamOut->allocateMemoryForSliceLocations( pcPic->getPicSym()->getNumberOfCUsInFrame() ); // Assuming number of slices <= number of LCU. Needs to be changed for sub-LCU slice coding.
441      pcBitstreamOut->setSliceCount( 0 );                                      // intialize number of slices to zero, used while converting RBSP to NALU
442
443      uiStartCUAddrEntropySliceIdx = 0;
444      uiStartCUAddrEntropySlice    = 0;
445      uiNextCUAddr                 = 0;
446      pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
447      while (uiNextCUAddr < pcPic->getPicSym()->getNumberOfCUsInFrame()) // Iterate over all slices
448      {
449        pcSlice->setNextSlice       ( false );
450        pcSlice->setNextEntropySlice( false );
451        if (uiNextCUAddr == m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx])
452        {
453          pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
454          pcPic->setCurrSliceIdx(uiStartCUAddrSliceIdx);
455          m_pcSliceEncoder->setSliceIdx(uiStartCUAddrSliceIdx);
456          assert(uiStartCUAddrSliceIdx == pcSlice->getSliceIdx());
457          // Reconstruction slice
458          pcSlice->setSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
459          pcSlice->setSliceCurEndCUAddr  ( m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx+1 ] );
460          // Entropy slice
461          pcSlice->setEntropySliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
462          pcSlice->setEntropySliceCurEndCUAddr  ( m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx+1 ] );
463
464          pcSlice->setNextSlice       ( true );
465
466          uiStartCUAddrSliceIdx++;
467          uiStartCUAddrEntropySliceIdx++;
468        }
469        else if (uiNextCUAddr == m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx])
470        {
471          // Entropy slice
472          pcSlice->setEntropySliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
473          pcSlice->setEntropySliceCurEndCUAddr  ( m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx+1 ] );
474
475          pcSlice->setNextEntropySlice( true );
476
477          uiStartCUAddrEntropySliceIdx++;
478        }
479
480        // Get ready for writing slice header (other than the first one in the picture)
481        if (uiNextCUAddr!=0)
482        {
483          m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
484          m_pcEntropyCoder->setBitstream      ( pcBitstreamOut          );
485          m_pcEntropyCoder->resetEntropy      ();
486        }
487
488      // write SliceHeader
489      m_pcEntropyCoder->encodeSliceHeader ( pcSlice                 );
490
491      // is it needed?
492      if ( pcSlice->getSymbolMode() )
493      {
494        m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
495        m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
496        m_pcEntropyCoder->resetEntropy    ();
497      }
498
499        if (uiNextCUAddr==0)  // Compute ALF params and write only for first slice header
500        {
501          // adaptive loop filter
502#if MTK_SAO
503          if ( pcSlice->getSPS()->getUseALF() || (pcSlice->getSPS()->getUseSAO()) )
504#else
505          if ( pcSlice->getSPS()->getUseALF())
506#endif
507          {
508            ALFParam cAlfParam;
509#if TSB_ALF_HEADER
510            m_pcAdaptiveLoopFilter->setNumCUsInFrame(pcPic);
511#endif
512            m_pcAdaptiveLoopFilter->allocALFParam(&cAlfParam);
513
514            // set entropy coder for RD
515            if ( pcSlice->getSymbolMode() )
516            {
517              m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
518            }
519            else
520            {
521              m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
522            }
523            m_pcEntropyCoder->resetEntropy    ();
524            m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
525
526            m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder );
527#if MTK_SAO  // PostDF
528            {
529              if (pcSlice->getSPS()->getUseSAO())
530              {
531                m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcCfg->getUseSBACRD() ?  m_pcEncTop->getRDGoOnSbacCoder() : NULL);
532                m_pcSAO->SAOProcess(pcPic->getSlice(0)->getLambda());
533                m_pcSAO->copyQaoData(&cSaoParam);
534                m_pcSAO->endSaoEnc();
535              }
536            }
537#endif
538            UInt uiMaxAlfCtrlDepth;
539
540            UInt64 uiDist, uiBits;
541#if MTK_SAO
542            if ( pcSlice->getSPS()->getUseALF())
543#endif
544              m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, pcPic->getSlice(0)->getLambda(), uiDist, uiBits, uiMaxAlfCtrlDepth );
545#if MTK_SAO
546            else
547              cAlfParam.cu_control_flag = 0;
548#endif
549            m_pcAdaptiveLoopFilter->endALFEnc();
550
551            // set entropy coder for writing
552            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
553            if ( pcSlice->getSymbolMode() )
554            {
555              m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
556            }
557            else
558            {
559              m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
560            }
561            m_pcEntropyCoder->resetEntropy    ();
562            m_pcEntropyCoder->setBitstream    ( pcBitstreamOut );
563            if (cAlfParam.cu_control_flag)
564            {
565              m_pcEntropyCoder->setAlfCtrl( true );
566              m_pcEntropyCoder->setMaxAlfCtrlDepth(uiMaxAlfCtrlDepth);
567              if (pcSlice->getSymbolMode() == 0)
568              {
569                m_pcCavlcCoder->setAlfCtrl(true);
570                m_pcCavlcCoder->setMaxAlfCtrlDepth(uiMaxAlfCtrlDepth); //D0201
571              }
572            }
573            else
574            {
575              m_pcEntropyCoder->setAlfCtrl(false);
576            }
577#if MTK_SAO
578            if (pcSlice->getSPS()->getUseSAO())
579            {
580              m_pcEntropyCoder->encodeSaoParam(&cSaoParam);
581            }
582            if (pcSlice->getSPS()->getUseALF())
583#endif
584            m_pcEntropyCoder->encodeAlfParam(&cAlfParam);
585
586#if TSB_ALF_HEADER
587            if(cAlfParam.cu_control_flag)
588            {
589              m_pcEntropyCoder->encodeAlfCtrlParam(&cAlfParam);
590            }
591#endif
592            m_pcAdaptiveLoopFilter->freeALFParam(&cAlfParam);
593          }
594        }
595
596        // File writing
597        m_pcSliceEncoder->encodeSlice( pcPic, pcBitstreamOut );
598
599        //  End of bitstream & byte align
600        pcBitstreamOut->write( 1, 1 );
601        pcBitstreamOut->writeAlignZero();
602
603        UInt uiBoundingAddrSlice, uiBoundingAddrEntropySlice;
604        uiBoundingAddrSlice        = m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx];
605        uiBoundingAddrEntropySlice = m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx];
606        uiNextCUAddr               = min(uiBoundingAddrSlice, uiBoundingAddrEntropySlice);
607        if (uiNextCUAddr < pcPic->getPicSym()->getNumberOfCUsInFrame())   // if more slices to be encoded insert start code
608        {
609          UInt uiSliceCount = pcBitstreamOut->getSliceCount();
610          pcBitstreamOut->setSliceByteLocation( uiSliceCount, (pcBitstreamOut->getNumberOfWrittenBits()>>3) );
611          pcBitstreamOut->setSliceCount( uiSliceCount+1 );
612          pcBitstreamOut->write( 1, 32);
613        }
614      } // end iteration over slices
615
616
617#if MTK_NONCROSS_INLOOP_FILTER
618      if(pcSlice->getSPS()->getUseALF())
619      {
620        if(m_pcAdaptiveLoopFilter->getUseNonCrossAlf())
621          m_pcAdaptiveLoopFilter->destroySlice();
622      }
623#endif
624
625
626      pcBitstreamOut->flushBuffer();
627      pcBitstreamOut->convertRBSPToPayload(0);
628
629#if POZNAN_MP
630          pcSlice->getMP()->disable();
631#endif
632
633/*#if AMVP_BUFFERCOMPRESS
634      pcPic->compressMotion(); // moved to end of access unit
635#endif */
636      pcBitstreamOut->freeMemoryAllocatedForSliceLocations();
637
638      //-- For time output for each slice
639      Double dEncTime = (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
640
641      xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), pcBitstreamOut->getNumberOfWrittenBits(), dEncTime );
642
643#if FIXED_ROUNDING_FRAME_MEMORY
644      pcPic->getPicYuvRec()->xFixedRoundingPic();
645#endif
646
647      if (m_pcCfg->getPictureDigestEnabled()) {
648        /* calculate MD5sum for entire reconstructed picture */
649        SEIpictureDigest sei_recon_picture_digest;
650        sei_recon_picture_digest.method = SEIpictureDigest::MD5;
651        calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
652        printf("[MD5:%s] ", digestToString(sei_recon_picture_digest.digest));
653
654        TComBitstream seiBs;
655        seiBs.create(1024);
656        /* write the SEI messages */
657        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
658        m_pcEntropyCoder->setBitstream(&seiBs);
659        m_pcEntropyCoder->encodeSEI(sei_recon_picture_digest);
660        /* and trailing bits */
661        seiBs.write(1, 1);
662        seiBs.writeAlignZero();
663        seiBs.flushBuffer();
664        seiBs.convertRBSPToPayload(0);
665
666        /* append the SEI message after any SPS/PPS */
667        /* the following loop is a work around current limitations in
668         * TComBitstream that won't be fixed before HM-3.0 */
669        UChar *seiData = reinterpret_cast<UChar *>(seiBs.getStartStream());
670        for (Int i = 0; i < seiBs.getNumberOfWrittenBits()/8; i++)
671        {
672          bs_SPS_PPS_SEI.write(seiData[i], 8);
673        }
674        bs_SPS_PPS_SEI.write(1, 32);
675        seiBs.destroy();
676      }
677
678      /* insert the bs_SPS_PPS_SEI before the pcBitstreamOut */
679      bs_SPS_PPS_SEI.flushBuffer();
680      pcBitstreamOut->insertAt(bs_SPS_PPS_SEI, 0);
681
682      bs_SPS_PPS_SEI.destroy();
683      pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
684
685      pcPic->setReconMark   ( true );
686
687}
688
689Void TEncPic::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
690{
691  TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
692  Bool bCalcDist = false;
693
694  m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), m_pcCfg->getLoopFilterAlphaC0Offget(), m_pcCfg->getLoopFilterBetaOffget());
695  m_pcLoopFilter->loopFilterPic( pcPic );
696
697  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
698  m_pcEntropyCoder->resetEntropy    ();
699  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
700
701  // Adaptive Loop filter
702  if( pcSlice->getSPS()->getUseALF() )
703  {
704    ALFParam cAlfParam;
705#if TSB_ALF_HEADER
706    m_pcAdaptiveLoopFilter->setNumCUsInFrame(pcPic);
707#endif
708    m_pcAdaptiveLoopFilter->allocALFParam(&cAlfParam);
709
710    m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder);
711
712    UInt uiMaxAlfCtrlDepth;
713    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, pcSlice->getLambda(), ruiDist, ruiBits, uiMaxAlfCtrlDepth );
714    m_pcAdaptiveLoopFilter->endALFEnc();
715    m_pcAdaptiveLoopFilter->freeALFParam(&cAlfParam);
716  }
717
718  m_pcEntropyCoder->resetEntropy    ();
719  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
720
721  if (!bCalcDist)
722    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
723}
724
725// ====================================================================================================================
726// Protected member functions
727// ====================================================================================================================
728
729UInt64 TEncPic::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
730{
731  Int     x, y;
732  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
733  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
734#if IBDI_DISTORTION
735  Int  iShift = g_uiBitIncrement;
736  Int  iOffset = 1<<(g_uiBitIncrement-1);
737#else
738  UInt  uiShift = g_uiBitIncrement<<1;
739#endif
740  Int   iTemp;
741
742  Int   iStride = pcPic0->getStride();
743  Int   iWidth  = pcPic0->getWidth();
744  Int   iHeight = pcPic0->getHeight();
745
746  UInt64  uiTotalDiff = 0;
747
748  for( y = 0; y < iHeight; y++ )
749  {
750    for( x = 0; x < iWidth; x++ )
751    {
752#if IBDI_DISTORTION
753      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
754#else
755      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
756#endif
757    }
758    pSrc0 += iStride;
759    pSrc1 += iStride;
760  }
761
762  iHeight >>= 1;
763  iWidth  >>= 1;
764  iStride >>= 1;
765
766  pSrc0  = pcPic0->getCbAddr();
767  pSrc1  = pcPic1->getCbAddr();
768
769  for( y = 0; y < iHeight; y++ )
770  {
771    for( x = 0; x < iWidth; x++ )
772    {
773#if IBDI_DISTORTION
774      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
775#else
776      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
777#endif
778    }
779    pSrc0 += iStride;
780    pSrc1 += iStride;
781  }
782
783  pSrc0  = pcPic0->getCrAddr();
784  pSrc1  = pcPic1->getCrAddr();
785
786  for( y = 0; y < iHeight; y++ )
787  {
788    for( x = 0; x < iWidth; x++ )
789    {
790#if IBDI_DISTORTION
791      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
792#else
793      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
794#endif
795    }
796    pSrc0 += iStride;
797    pSrc1 += iStride;
798  }
799
800  return uiTotalDiff;
801}
802
803Void TEncPic::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, UInt uibits, Double dEncTime )
804{
805  Int     x, y;
806  UInt64 uiSSDY  = 0;
807  UInt64 uiSSDU  = 0;
808  UInt64 uiSSDV  = 0;
809
810  Double  dYPSNR  = 0.0;
811  Double  dUPSNR  = 0.0;
812  Double  dVPSNR  = 0.0;
813
814  //===== calculate PSNR =====
815  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
816  Pel*  pRec    = pcPicD->getLumaAddr();
817#if POZNAN_CU_SKIP_PSNR
818  Pel*  pAvail  = NULL;
819  if(pcPic ->getPicYuvAvail())
820    pAvail  = pcPic ->getPicYuvAvail()->getLumaAddr();
821  UInt64 iPixelsCnt = 0;
822#endif
823  Int   iStride = pcPicD->getStride();
824
825  Int   iWidth;
826  Int   iHeight;
827
828  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
829  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
830
831  Int   iSize   = iWidth*iHeight;
832
833  UInt   maxval = 255 * (1<<(g_uiBitDepth + g_uiBitIncrement -8));
834  Double fRefValueY = (double) maxval * maxval * iSize;
835  Double fRefValueC = fRefValueY / 4.0;
836
837#if POZNAN_CU_SKIP_PSNR
838  if(pAvail)
839  {
840  for( y = 0; y < iHeight; y++ )
841  {
842    for( x = 0; x < iWidth; x++ )
843    {
844        if(pAvail[x]==0) //If pixel was codded
845        {
846          Int iDiff = (Int)( pOrg[x] - pRec[x] );
847          uiSSDY   += iDiff * iDiff;
848          iPixelsCnt++;
849        }
850      }
851      pOrg += iStride;
852      pRec += iStride;
853      pAvail+=iStride;
854    }
855   
856    fRefValueY = (double) maxval * maxval * iPixelsCnt;
857  }
858  else
859#endif
860  {
861    for( y = 0; y < iHeight; y++ )
862    {
863      for( x = 0; x < iWidth; x++ )
864      {
865      Int iDiff = (Int)( pOrg[x] - pRec[x] );
866      uiSSDY   += iDiff * iDiff;
867    }
868    pOrg += iStride;
869    pRec += iStride;
870  }
871  }
872
873#if HHI_VSO
874  if ( m_pcRdCost->getUseRenModel() )
875  {
876    TRenModel*  pcRenModel = m_pcEncTop->getEncTop()->getRenModel();
877    Int64 iDistVSOY, iDistVSOU, iDistVSOV;
878    pcRenModel->getTotalSSE( iDistVSOY, iDistVSOU, iDistVSOV );
879    dYPSNR = ( iDistVSOY ? 10.0 * log10( fRefValueY / (Double) iDistVSOY ) : 99.99 );
880    dUPSNR = ( iDistVSOU ? 10.0 * log10( fRefValueC / (Double) iDistVSOU ) : 99.99 );
881    dVPSNR = ( iDistVSOV ? 10.0 * log10( fRefValueC / (Double) iDistVSOV ) : 99.99 );
882  }
883  else
884#endif
885  {
886#if POZNAN_CU_SKIP_PSNR
887  if(pAvail)
888  {
889    iHeight >>= 1;
890    iWidth  >>= 1;
891    iStride >>= 1;
892 
893    pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
894    pRec  = pcPicD->getCbAddr();
895    pAvail  = pcPic ->getPicYuvAvail()->getLumaAddr();
896    iPixelsCnt = 0;
897
898    for( y = 0; y < iHeight; y++ )
899    {
900      for( x = 0; x < iWidth; x++ )
901      {
902        if(pAvail[x<<1]==0||pAvail[(x<<1)+1]==0||
903           pAvail[(x+iStride)<<1]==0||pAvail[((x+iStride)<<1)+1]==0) //If pixel was codded
904        {
905          Int iDiff = (Int)( pOrg[x] - pRec[x] );
906          uiSSDU   += iDiff * iDiff;
907          iPixelsCnt++;
908        }
909      }
910      pOrg += iStride;
911      pRec += iStride;
912        pAvail+= (iStride<<2);
913    }
914
915    fRefValueC = (double) maxval * maxval * iPixelsCnt;
916
917    pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
918    pRec  = pcPicD->getCrAddr();
919    pAvail  = pcPic ->getPicYuvAvail()->getLumaAddr();
920    for( y = 0; y < iHeight; y++ )
921    {
922      for( x = 0; x < iWidth; x++ )
923      {
924        if(pAvail[x<<1]==0||pAvail[(x<<1)+1]==0||
925           pAvail[(x+iStride)<<1]==0||pAvail[((x+iStride)<<1)+1]==0) //If pixel was codded
926        {
927          Int iDiff = (Int)( pOrg[x] - pRec[x] );
928          uiSSDV   += iDiff * iDiff;
929        }
930      }
931      pOrg += iStride;
932      pRec += iStride;
933        pAvail+= iStride<<2;
934    }
935  }
936  else
937#endif
938  {
939  iHeight >>= 1;
940  iWidth  >>= 1;
941  iStride >>= 1;
942
943  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
944  pRec  = pcPicD->getCbAddr();
945
946  for( y = 0; y < iHeight; y++ )
947  {
948    for( x = 0; x < iWidth; x++ )
949    {
950      Int iDiff = (Int)( pOrg[x] - pRec[x] );
951      uiSSDU   += iDiff * iDiff;
952    }
953    pOrg += iStride;
954    pRec += iStride;
955  }
956
957  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
958  pRec  = pcPicD->getCrAddr();
959
960  for( y = 0; y < iHeight; y++ )
961  {
962    for( x = 0; x < iWidth; x++ )
963    {
964      Int iDiff = (Int)( pOrg[x] - pRec[x] );
965      uiSSDV   += iDiff * iDiff;
966    }
967    pOrg += iStride;
968    pRec += iStride;
969  }
970  }
971
972  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
973  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
974  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
975  }
976  // fix: total bits should consider slice size bits (32bit)
977  uibits += 32;
978
979#if RVM_VCEGAM10
980  m_vRVM_RP.push_back( uibits );
981#endif
982
983  //===== add PSNR =====
984  m_pcEncTop->m_cAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
985  TComSlice*  pcSlice = pcPic->getSlice(0);
986  if (pcSlice->isIntra())
987  {
988    m_pcEncTop->m_cAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
989  }
990  if (pcSlice->isInterP())
991  {
992    m_pcEncTop->m_cAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
993  }
994  if (pcSlice->isInterB())
995  {
996    m_pcEncTop->m_cAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
997  }
998  if(pcPic->getViewIdx()!=-1)
999  {
1000    if(! m_pcEncTop->isDepthCoder())
1001    {
1002      printf("\nView \t\t%2d\t POC %4d ( %c-SLICE, QP %d ) %10d bits ",
1003      pcSlice->getViewIdx(),
1004      pcSlice->getPOC(),
1005      pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
1006      pcSlice->getSliceQp(),
1007      uibits );
1008    }
1009    else
1010    {
1011      printf("\nDepth View \t%2d\t POC %4d ( %c-SLICE, QP %d ) %10d bits ",
1012            pcSlice->getViewIdx(),
1013            pcSlice->getPOC(),
1014            pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
1015            pcSlice->getSliceQp(),
1016            uibits );
1017    }
1018  }
1019  else
1020  {
1021    printf("\nPOC %4d ( %c-SLICE, QP %d ) %10d bits ",
1022           pcSlice->getPOC(),
1023           pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
1024           pcSlice->getSliceQp(),
1025           uibits );
1026  }
1027
1028  printf( "[Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]  ", dYPSNR, dUPSNR, dVPSNR );
1029  printf ("[ET %5.0f ] ", dEncTime );
1030
1031  for (Int iRefList = 0; iRefList < 2; iRefList++)
1032  {
1033    printf ("[L%d ", iRefList);
1034    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
1035    {
1036      if( pcSlice->getViewIdx() != pcSlice->getRefViewIdx( RefPicList(iRefList), iRefIndex ) )
1037      {
1038        printf( "V%d", pcSlice->getRefViewIdx( RefPicList(iRefList), iRefIndex ) );
1039        if( pcSlice->getPOC() != pcSlice->getRefPOC( RefPicList(iRefList), iRefIndex ) )
1040          printf( "(%d)", pcSlice->getRefPOC( RefPicList(iRefList), iRefIndex ) );
1041        printf( " " );
1042      }
1043      else
1044        printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
1045    }
1046    printf ("] ");
1047  }
1048#if DCM_COMB_LIST
1049  if(pcSlice->getNumRefIdx(REF_PIC_LIST_C)>0 && !pcSlice->getNoBackPredFlag())
1050  {
1051    printf ("[LC ");
1052    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(REF_PIC_LIST_C); iRefIndex++)
1053    {
1054      printf ("%d ", pcSlice->getRefPOC((RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex)));
1055    }
1056    printf ("] ");
1057  }
1058#endif
1059
1060  fflush(stdout);
1061}
1062
1063#if DCM_DECODING_REFRESH
1064/** Function for deciding the nal_unit_type.
1065 * \param uiPOCCurr POC of the current picture
1066 * \returns the nal_unit type of the picture
1067 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
1068 */
1069NalUnitType TEncPic::getNalUnitType(UInt uiPOCCurr)
1070{
1071  if (uiPOCCurr == 0)
1072  {
1073    return NAL_UNIT_CODED_SLICE_IDR;
1074  }
1075#if 0
1076  if (uiPOCCurr % m_pcCfg->getIntraPeriod() == 0)
1077  {
1078    if (m_pcCfg->getDecodingRefreshType() == 1)
1079    {
1080      return NAL_UNIT_CODED_SLICE_CDR;
1081    }
1082    else if (m_pcCfg->getDecodingRefreshType() == 2)
1083    {
1084      return NAL_UNIT_CODED_SLICE_IDR;
1085    }
1086  }
1087#endif
1088  return NAL_UNIT_CODED_SLICE;
1089}
1090#endif
1091
1092#if RVM_VCEGAM10
1093Double TEncPic::xCalculateRVM()
1094{
1095  Double dRVM = 0;
1096
1097  //if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFrameToBeEncoded() > RVM_VCEGAM10_M * 2 )
1098  {
1099    // calculate RVM only for lowdelay configurations
1100    std::vector<Double> vRL , vB;
1101    size_t N = m_vRVM_RP.size();
1102    vRL.resize( N );
1103    vB.resize( N );
1104
1105    Int i;
1106    Double dRavg = 0 , dBavg = 0;
1107    vB[RVM_VCEGAM10_M] = 0;
1108    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
1109    {
1110      vRL[i] = 0;
1111      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
1112        vRL[i] += m_vRVM_RP[j];
1113      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
1114      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
1115      dRavg += m_vRVM_RP[i];
1116      dBavg += vB[i];
1117    }
1118
1119    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
1120    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
1121
1122    double dSigamB = 0;
1123    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
1124    {
1125      Double tmp = vB[i] - dBavg;
1126      dSigamB += tmp * tmp;
1127    }
1128    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
1129
1130    double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
1131
1132    dRVM = dSigamB / dRavg * f;
1133  }
1134
1135  return( dRVM );
1136}
1137#endif
1138
Note: See TracBrowser for help on using the repository browser.