source: 3DVCSoftware/branches/0.3-poznan-univ/source/Lib/TLibEncoder/TEncGOP.cpp @ 48

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

some bug fix on high level syntax
fixed some compiler warning issues under windows and linux

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