source: 3DVCSoftware/branches/0.1-poznan-univ/source/Lib/TLibEncoder/TEncGOP.cpp @ 83

Last change on this file since 83 was 2, checked in by hhi, 13 years ago

inital import

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