Ticket #42: TEncGOP.cpp

File TEncGOP.cpp, 32.3 KB (added by anonymous, 14 years ago)
Line 
1/* ====================================================================================================================
2
3  The copyright in this software is being made available under the License included below.
4  This software may be subject to other third party and   contributor rights, including patent rights, and no such
5  rights are granted under this license.
6
7  Copyright (c) 2010, SAMSUNG ELECTRONICS CO., LTD. and BRITISH BROADCASTING CORPORATION
8  All rights reserved.
9
10  Redistribution and use in source and binary forms, with or without modification, are permitted only for
11  the purpose of developing standards within the Joint Collaborative Team on Video Coding and for testing and
12  promoting such standards. The following conditions are required to be met:
13
14    * Redistributions of source code must retain the above copyright notice, this list of conditions and
15      the following disclaimer.
16    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
17      the following disclaimer in the documentation and/or other materials provided with the distribution.
18    * Neither the name of SAMSUNG ELECTRONICS CO., LTD. nor the name of the BRITISH BROADCASTING CORPORATION
19      may be used to endorse or promote products derived from this software without specific prior written permission.
20
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
22  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 * ====================================================================================================================
30*/
31
32/** \file     TEncGOP.cpp
33    \brief    GOP encoder class
34*/
35
36#include "TEncTop.h"
37#include "TEncGOP.h"
38#include "TEncAnalyze.h"
39
40#include <time.h>
41
42// ====================================================================================================================
43// Constructor / destructor / initialization / destroy
44// ====================================================================================================================
45
46TEncGOP::TEncGOP()
47{
48  m_iHrchDepth          = 0;
49  m_iGopSize            = 0;
50  m_iNumPicCoded        = 0; //Niko
51  m_bFirst              = true;
52
53  m_pcCfg               = NULL;
54  m_pcSliceEncoder      = NULL;
55#ifdef QC_SIFO
56  m_pcSIFOEncoder       = NULL;
57#endif
58  m_pcListPic           = NULL;
59
60  m_pcEntropyCoder      = NULL;
61  m_pcCavlcCoder        = NULL;
62  m_pcSbacCoder         = NULL;
63  m_pcBinCABAC          = NULL;
64  m_pcBinMultiCABAC     = NULL;
65  m_pcBinPIPE           = NULL;
66  m_pcBinMultiPIPE      = NULL;
67  m_pcBinV2VwLB         = NULL;
68
69  m_bSeqFirst           = true;
70
71  return;
72}
73
74TEncGOP::~TEncGOP()
75{
76}
77
78Void  TEncGOP::create()
79{
80}
81
82Void  TEncGOP::destroy()
83{
84}
85
86Void TEncGOP::init ( TEncTop* pcTEncTop )
87{
88  m_pcEncTop     = pcTEncTop;
89  m_pcCfg                = pcTEncTop;
90  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
91#ifdef QC_SIFO
92  m_pcSIFOEncoder        = pcTEncTop->getSIFOEncoder();
93#endif
94  m_pcListPic            = pcTEncTop->getListPic();
95
96  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
97  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
98  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
99  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
100  m_pcBinMultiCABAC      = pcTEncTop->getBinMultiCABAC();
101  m_pcBinPIPE            = pcTEncTop->getBinPIPE();
102  m_pcBinMultiPIPE       = pcTEncTop->getBinMultiPIPE();
103  m_pcBinV2VwLB          = pcTEncTop->getBinV2VwLB();
104  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
105  m_pcBitCounter         = pcTEncTop->getBitCounter();
106  m_pcBinCABAC4V2V       = pcTEncTop->getBinCABAC4V2V();
107  m_uiBalancedCPUs       = pcTEncTop->getBalancedCPUs();
108
109  // Adaptive Loop filter
110  m_pcAdaptiveLoopFilter = pcTEncTop->getAdaptiveLoopFilter();
111  //--Adaptive Loop filter
112}
113
114// ====================================================================================================================
115// Public member functions
116// ====================================================================================================================
117
118Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, TComList<TComBitstream*> rcListBitstreamOut )
119{
120  TComPic*        pcPic;
121  TComPicYuv*     pcPicYuvRecOut;
122  TComBitstream*  pcBitstreamOut;
123  TComPicYuv      cPicOrg;
124  TComPic*        pcOrgRefList[2][MAX_REF_PIC_NUM];
125//stats
126  TComBitstream*  pcOut = new TComBitstream;
127  pcOut->create( 500000 );
128
129  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut );
130
131  m_iNumPicCoded = 0;
132  for ( Int iDepth = 0; iDepth < m_iHrchDepth; iDepth++ )
133  {
134    Int iTimeOffset = ( 1 << (m_iHrchDepth - 1 - iDepth) );
135    Int iStep       = iTimeOffset << 1;
136
137    // generalized B info.
138    if ( (m_pcCfg->getHierarchicalCoding() == false) && (iDepth != 0) )
139    {
140      iTimeOffset   = 1;
141      iStep         = 1;
142    }
143
144    UInt uiColDir = 1;
145
146    for ( ; iTimeOffset <= iNumPicRcvd; iTimeOffset += iStep )
147    {
148      //-- For time output for each slice
149      long iBeforeTime = clock();
150
151      // generalized B info.
152      if ( (m_pcCfg->getHierarchicalCoding() == false) && (iDepth != 0) && (iTimeOffset == m_iGopSize) && (iPOCLast != 0) )
153      {
154        continue;
155      }
156
157      /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
158      UInt  uiPOCCurr = iPOCLast - (iNumPicRcvd - iTimeOffset);
159
160      xGetBuffer( rcListPic, rcListPicYuvRecOut, rcListBitstreamOut, iNumPicRcvd, iTimeOffset,  pcPic, pcPicYuvRecOut, pcBitstreamOut, uiPOCCurr );
161
162      // save original picture
163      cPicOrg.create( pcPic->getPicYuvOrg()->getWidth(), pcPic->getPicYuvOrg()->getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
164      pcPic->getPicYuvOrg()->copyToPic( &cPicOrg );
165
166      // scaling of picture
167      if ( g_uiBitIncrement )
168      {
169        xScalePic( pcPic );
170      }
171
172      //  Bitstream reset
173      pcBitstreamOut->resetBits();
174      pcBitstreamOut->rewindStreamPacket();
175
176      //  Slice data initialization
177      TComSlice*      pcSlice;
178      m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, uiPOCCurr, iNumPicRcvd, iTimeOffset, iDepth, pcSlice );
179
180      //  Set SPS
181      pcSlice->setSPS( m_pcEncTop->getSPS() );
182      pcSlice->setPPS( m_pcEncTop->getPPS() );
183
184      //  Set reference list
185      pcSlice->setRefPicList ( rcListPic );
186
187      //  Slice info. refinement
188      if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
189      {
190        pcSlice->setSliceType ( P_SLICE );
191        pcSlice->setDRBFlag   ( true );
192      }
193
194      // Generalized B
195      if ( m_pcCfg->getUseGPB() )
196      {
197        if (pcSlice->getSliceType() == P_SLICE)
198        {
199          pcSlice->setSliceType( B_SLICE ); // Change slice type by force
200
201          Int iNumRefIdx = pcSlice->getNumRefIdx(REF_PIC_LIST_0);
202          pcSlice->setNumRefIdx( REF_PIC_LIST_1, iNumRefIdx );
203
204          for (Int iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++)
205          {
206            pcSlice->setRefPic(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx), REF_PIC_LIST_1, iRefIdx);
207          }
208        }
209      }
210
211      // quality-based reference reordering (QBO)
212      if ( !pcSlice->isIntra() && pcSlice->getSPS()->getUseQBO() )
213      {
214        Int iMinIdx = 0, iMinQP, iRefIdx, iCnt;
215        TComPic* pRef;
216
217        // save original reference list & generate new reference list
218        for ( Int iList = 0; iList < 2; iList++ )
219        {
220          iMinQP = pcSlice->getSliceQp();
221
222          Int iNumRefIdx = pcSlice->getNumRefIdx( (RefPicList)iList );
223          for ( iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
224          {
225            pRef = pcSlice->getRefPic( (RefPicList)iList, iRefIdx );
226            pcOrgRefList[ (RefPicList)iList ][ iRefIdx ] = pRef;
227          }
228          for ( iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
229          {
230            pRef = pcSlice->getRefPic( (RefPicList)iList, iRefIdx );
231            if ( pRef->getSlice()->getSliceQp() <= iMinQP )
232            {
233              iMinIdx = iRefIdx;
234              break;
235            }
236          }
237
238          // set highest quality reference to zero index
239          pcSlice->setRefPic( pcOrgRefList[ (RefPicList)iList ][ iMinIdx ], (RefPicList)iList, 0 );
240
241          iCnt = 1;
242          for ( iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
243          {
244            if ( iRefIdx == iMinIdx ) continue;
245            pcSlice->setRefPic( pcOrgRefList[ (RefPicList)iList ][ iRefIdx ], (RefPicList)iList, iCnt++ );
246          }
247        }
248      }
249
250      if (pcSlice->getSliceType() == B_SLICE)
251      {
252        pcSlice->setColDir(uiColDir);
253      }
254
255      uiColDir = 1-uiColDir;
256
257      // Weighted prediction ----------------------------------------
258      m_pcSliceEncoder->generateRefPicNew(pcSlice);
259
260      //-------------------------------------------------------------
261      pcSlice->setRefPOCList();
262
263      /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
264      //  Slice compression
265      if (m_pcCfg->getUseASR())
266      {
267        m_pcSliceEncoder->setSearchRange(pcSlice);
268      }
269#ifdef ROUNDING_CONTROL
270          Bool b;
271          if (m_pcCfg->getGOPSize()==1)
272                  b = ((pcSlice->getPOC()&1)==0);       
273          else
274                  b = (pcSlice->isReferenced() == 0);   
275          pcSlice->setRounding(b);
276#endif
277#ifdef QC_SIFO
278      if( pcSlice->getUseSIFO() )
279      {
280        m_pcSIFOEncoder->initEncSIFO(pcSlice);  //use prev frame filters while compressing current frame
281        if(pcSlice->getSliceType() != I_SLICE)
282        {
283          m_pcSIFOEncoder->setFirstPassSubpelOffset(REF_PIC_LIST_0, pcSlice);
284          if(pcSlice->getSliceType() == B_SLICE)
285            m_pcSIFOEncoder->setFirstPassSubpelOffset(REF_PIC_LIST_1, pcSlice);
286        }
287      }
288#endif
289      m_pcSliceEncoder->precompressSlice( pcPic );
290      m_pcSliceEncoder->compressSlice   ( pcPic );
291
292      // quality-based reference reordering (QBO)
293      if ( !pcSlice->isIntra() && pcSlice->getSPS()->getUseQBO() )
294      {
295        // restore original reference list
296        for ( Int iList = 0; iList < 2; iList++ )
297        {
298          Int iNumRefIdx = pcSlice->getNumRefIdx( (RefPicList)iList );
299          for ( Int iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
300          {
301            pcSlice->setRefPic( pcOrgRefList[ (RefPicList)iList ][ iRefIdx ], (RefPicList)iList, iRefIdx );
302          }
303        }
304      }
305
306      //-- Loop filter
307      m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), m_pcCfg->getLoopFilterAlphaC0Offget(), m_pcCfg->getLoopFilterBetaOffget());
308      m_pcLoopFilter->loopFilterPic( pcPic );
309
310      /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
311      // Set entropy coder
312      m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
313      m_pcEntropyCoder->setBitstream      ( pcBitstreamOut          );
314
315      // write SPS
316      if ( m_bSeqFirst )
317      {
318        pcSlice->getSPS()->setBalancedCPUs( getBalancedCPUs() );
319        m_pcEntropyCoder->encodeSPS( pcSlice->getSPS() );
320#if HHI_NAL_UNIT_SYNTAX
321        pcBitstreamOut->write( 1, 1 );
322        pcBitstreamOut->writeAlignZero();
323        // generate start code
324        pcBitstreamOut->write( 1, 32);
325#endif
326
327        m_pcEntropyCoder->encodePPS( pcSlice->getPPS() );
328#if HHI_NAL_UNIT_SYNTAX
329        pcBitstreamOut->write( 1, 1 );
330        pcBitstreamOut->writeAlignZero();
331        // generate start code
332        pcBitstreamOut->write( 1, 32);
333#endif
334        m_bSeqFirst = false;
335      }
336
337#if HHI_NAL_UNIT_SYNTAX
338      UInt uiPosBefore = pcBitstreamOut->getNumberOfWrittenBits()>>3;
339#endif
340
341      // write SliceHeader
342      if( pcSlice->getSymbolMode() )
343      { 
344        pcSlice->setMultiCodeword( m_pcCfg->getMCWThreshold() > 0 && m_pcSliceEncoder->getTotalBits() >= (UInt64)m_pcCfg->getMCWThreshold() );
345      }
346      m_pcEntropyCoder->encodeSliceHeader ( pcSlice                 );
347#ifdef QC_SIFO
348      if( pcSlice->getUseSIFO() )
349        m_pcEntropyCoder->encodeSwitched_Filters(pcSlice,m_pcEncTop->getPredSearch());
350#endif
351
352      // is it needed?
353      if ( pcSlice->getSymbolMode() )
354      {
355        if( pcSlice->getSymbolMode() == 3 )
356        {
357          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinV2VwLB );
358          m_pcBinV2VwLB->setBalancedCPUs( getBalancedCPUs() );
359        }
360        else if( pcSlice->getSymbolMode() == 1 )
361        {
362          m_pcSbacCoder->init( pcSlice->getMultiCodeword() ? (TEncBinIf*)m_pcBinMultiCABAC : (TEncBinIf*)m_pcBinCABAC );
363        }
364        else if( pcSlice->getMultiCodeword() )
365        {
366          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinMultiPIPE );
367        }
368        else
369        {
370          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinPIPE );
371          m_pcBinPIPE ->initDelay( pcSlice->getMaxPIPEDelay() );
372        }
373        m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcPic->getSlice() );
374        m_pcEntropyCoder->resetEntropy    ();
375      }
376
377      /////////////////////////////////////////////////////////////////////////////////////////////////// Reconstructed image output
378      TComPicYuv pcPicD;
379      pcPicD.create( pcPic->getPicYuvOrg()->getWidth(), pcPic->getPicYuvOrg()->getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
380
381      // adaptive loop filter
382      if ( pcSlice->getSPS()->getUseALF() )
383      {
384        ALFParam cAlfParam;
385        m_pcAdaptiveLoopFilter->allocALFParam(&cAlfParam);
386
387        // set entropy coder for RD
388        if ( pcSlice->getSymbolMode() )
389        {
390        m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcPic->getSlice() );
391        }
392        else
393        {
394          m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcPic->getSlice() );
395        }
396
397        m_pcEntropyCoder->resetEntropy    ();
398        m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
399
400#if HHI_ALF
401        if ( pcSlice->getSymbolMode() )
402        {
403          m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcCfg->getUseSBACRD() ?  m_pcEncTop->getRDGoOnSbacCoder() : NULL );
404        }
405        else
406        {
407          m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder, NULL , NULL );
408        }
409#else
410        m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder );
411#endif
412
413        UInt uiMaxAlfCtrlDepth;
414
415        UInt64 uiDist, uiBits;
416        m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, pcPic->getSlice()->getLambda(), uiDist, uiBits, uiMaxAlfCtrlDepth );
417        m_pcAdaptiveLoopFilter->endALFEnc();
418
419        // set entropy coder for writing
420        if( pcSlice->getSymbolMode() == 3 )
421        {
422          getSliceEncoder()->getCUEncoder()->getCABAC4V2V()->clearStats();
423          getSliceEncoder()->getCUEncoder()->getCABAC4V2V()->setCntFlag(1);
424          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC4V2V );
425          m_pcEntropyCoder->setEntropyCoder( m_pcSbacCoder, pcPic->getSlice() );
426          m_pcEntropyCoder->resetEntropy();
427          m_pcEntropyCoder->setBitstream( (TComBitIf*)pcOut );
428          if( cAlfParam.cu_control_flag )
429          {
430            m_pcEntropyCoder->setAlfCtrl( true );
431            m_pcEntropyCoder->setMaxAlfCtrlDepth( uiMaxAlfCtrlDepth );
432          }
433          else
434            m_pcEntropyCoder->setAlfCtrl( false );
435          m_pcEntropyCoder->encodeAlfParam(&cAlfParam);
436#if HHI_ALF
437          if( pcSlice->getSPS()->getALFSeparateQt() && cAlfParam.cu_control_flag )
438          {
439            m_pcAdaptiveLoopFilter->encodeQuadTree ( &cAlfParam, m_pcEntropyCoder, uiMaxAlfCtrlDepth );
440          }
441#endif
442          pcPic->getSlice()->setSymbolMode(1);
443          m_pcSliceEncoder->setV2Vflag(1);
444          m_pcSliceEncoder->encodeSlice( pcPic, pcOut );
445
446          pcPic->getSlice()->setSymbolMode(3);
447          m_pcSliceEncoder->setV2Vflag(0);
448          // set v2v coder
449          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinV2VwLB );
450          if( !pcSlice->getMultiCodeword() )
451          {
452            m_pcBinV2VwLB->setState( m_pcBinCABAC4V2V->getState() );
453            m_pcBinV2VwLB->setpState( m_pcBinCABAC4V2V->getpState() );
454          }
455          m_pcBinV2VwLB->setBalancedCPUs( getBalancedCPUs() );
456        }
457        else if( pcSlice->getSymbolMode() == 1 )
458        {
459          m_pcSbacCoder->init( pcSlice->getMultiCodeword() ? (TEncBinIf*)m_pcBinMultiCABAC : (TEncBinIf*)m_pcBinCABAC );
460        }
461        else if( pcSlice->getMultiCodeword() )
462        {
463          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinMultiPIPE );
464        }
465        else
466        {
467          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinPIPE );
468          m_pcBinPIPE ->initDelay( pcSlice->getMaxPIPEDelay() );
469        }
470
471        if ( pcSlice->getSymbolMode() )
472        {
473          m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcPic->getSlice() );
474        }
475        else
476        {
477          m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcPic->getSlice() );
478        }
479
480        m_pcEntropyCoder->resetEntropy    ();
481        m_pcEntropyCoder->setBitstream    ( pcBitstreamOut );
482        if (cAlfParam.cu_control_flag)
483        {
484          m_pcEntropyCoder->setAlfCtrl( true );
485          m_pcEntropyCoder->setMaxAlfCtrlDepth(uiMaxAlfCtrlDepth);
486          if (pcSlice->getSymbolMode() == 0)
487          {
488          m_pcCavlcCoder->setAlfCtrl(true);
489          m_pcCavlcCoder->setMaxAlfCtrlDepth(uiMaxAlfCtrlDepth); //D0201
490          }
491        }
492        else
493        {
494          m_pcEntropyCoder->setAlfCtrl(false);
495        }
496
497        m_pcEntropyCoder->encodeAlfParam(&cAlfParam);
498
499#if HHI_ALF
500        if( pcSlice->getSPS()->getALFSeparateQt() && cAlfParam.cu_control_flag )
501        {
502          m_pcAdaptiveLoopFilter->encodeQuadTree ( &cAlfParam, m_pcEntropyCoder, uiMaxAlfCtrlDepth );
503          m_pcAdaptiveLoopFilter->destroyQuadTree( &cAlfParam );
504        }
505#endif
506
507        m_pcAdaptiveLoopFilter->freeALFParam(&cAlfParam);
508      }
509
510#if HHI_INTERP_FILTER     
511      // MOMS prefilter reconstructed pic
512      if ( pcPic->getSlice()->isReferenced() && pcSlice->getUseMOMS() )
513      {
514        TComCoeffCalcMOMS cCoeffCalc;
515        cCoeffCalc.calcCoeffs( pcPic->getPicYuvRec(), pcPic->getPicYuvRecFilt(), pcPic->getSlice()->getInterpFilterType() );
516      }
517#endif
518
519      // File writing
520      m_pcSliceEncoder->encodeSlice( pcPic, pcBitstreamOut );
521#ifdef QC_SIFO
522      if( pcSlice->getUseSIFO() )
523        m_pcSIFOEncoder->ComputeFiltersAndOffsets(pcPic);
524#endif
525          if( pcSlice->getSymbolMode() == 3 )
526        getSliceEncoder()->getCUEncoder()->getCABAC4V2V()->setCntFlag(0);
527
528      //  End of bitstream & byte align
529#if ! HHI_NAL_UNIT_SYNTAX
530      if( pcSlice->getSymbolMode() )
531#endif
532      {
533        pcBitstreamOut->write( 1, 1 );
534        pcBitstreamOut->writeAlignZero();
535      }
536
537      pcBitstreamOut->flushBuffer();
538#if HHI_NAL_UNIT_SYNTAX
539      pcBitstreamOut->convertRBSPToPayload( uiPosBefore );
540#endif
541      // de-scaling of picture
542      xDeScalePic( pcPic, &pcPicD );
543
544      // save original picture
545      cPicOrg.copyToPic( pcPic->getPicYuvOrg() );
546
547      //-- For time output for each slice
548      Double dEncTime = (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
549
550      xCalculateAddPSNR( pcPic, &pcPicD, pcBitstreamOut->getNumberOfWrittenBits(), dEncTime );
551
552      // free original picture
553      cPicOrg.destroy();
554
555      //  Reconstruction buffer update
556      pcPicD.copyToPic(pcPicYuvRecOut);
557
558      pcPicD.destroy();
559
560      pcPic->setReconMark   ( true );
561
562      m_bFirst = false;
563      m_iNumPicCoded++;
564    }
565
566    // generalized B info.
567    if ( m_pcCfg->getHierarchicalCoding() == false && iDepth != 0 )
568      break;
569  }
570
571  pcOut->destroy();
572  delete pcOut;
573
574  assert ( m_iNumPicCoded == iNumPicRcvd );
575}
576
577Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded)
578{
579  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
580
581  //--CFG_KDY
582  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
583  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
584  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
585  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
586
587  //-- all
588  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
589  m_gcAnalyzeAll.printOut('a');
590
591  printf( "\n\nI Slices--------------------------------------------------------\n" );
592  m_gcAnalyzeI.printOut('i');
593
594  printf( "\n\nP Slices--------------------------------------------------------\n" );
595  m_gcAnalyzeP.printOut('p');
596
597  printf( "\n\nB Slices--------------------------------------------------------\n" );
598  m_gcAnalyzeB.printOut('b');
599
600#if _SUMMARY_OUT_
601  m_gcAnalyzeAll.printSummaryOut();
602#endif
603#if _SUMMARY_PIC_
604  m_gcAnalyzeI.printSummary('I');
605  m_gcAnalyzeP.printSummary('P');
606  m_gcAnalyzeB.printSummary('B');
607#endif
608}
609
610Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
611{
612  TComSlice* pcSlice = pcPic->getSlice();
613  Bool bCalcDist = false;
614
615  m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), m_pcCfg->getLoopFilterAlphaC0Offget(), m_pcCfg->getLoopFilterBetaOffget());
616  m_pcLoopFilter->loopFilterPic( pcPic );
617
618  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
619  m_pcEntropyCoder->resetEntropy    ();
620  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
621
622  // Adaptive Loop filter
623  if( pcSlice->getSPS()->getUseALF() )
624  {
625    ALFParam cAlfParam;
626    m_pcAdaptiveLoopFilter->allocALFParam(&cAlfParam);
627
628#if HHI_ALF
629    m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcEncTop->getRDGoOnSbacCoder() );
630#else
631    m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder);
632#endif
633
634    UInt uiMaxAlfCtrlDepth;
635    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, pcPic->getSlice()->getLambda(), ruiDist, ruiBits, uiMaxAlfCtrlDepth );
636    m_pcAdaptiveLoopFilter->endALFEnc();
637    m_pcAdaptiveLoopFilter->freeALFParam(&cAlfParam);
638  }
639
640  m_pcEntropyCoder->resetEntropy    ();
641  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
642
643  if (!bCalcDist)
644  ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
645}
646
647// ====================================================================================================================
648// Protected member functions
649// ====================================================================================================================
650
651Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut )
652{
653  assert( iNumPicRcvd > 0 );
654  Int i;
655
656  //  Set hierarchical B info.
657  m_iGopSize    = m_pcCfg->getGOPSize();
658  for( i=1 ; ; i++)
659  {
660    m_iHrchDepth = i;
661    if((m_iGopSize >> i)==0)
662    {
663      break;
664    }
665  }
666
667  //  Exception for the first frame
668  if ( iPOCLast == 0 )
669  {
670    m_iGopSize    = 1;
671    m_iHrchDepth  = 1;
672  }
673
674  if (m_iGopSize == 0)
675  {
676    m_iHrchDepth = 1;
677  }
678
679  return;
680}
681
682Void TEncGOP::xGetBuffer( TComList<TComPic*>&       rcListPic,
683                          TComList<TComPicYuv*>&    rcListPicYuvRecOut,
684                          TComList<TComBitstream*>& rcListBitstreamOut,
685                          Int                       iNumPicRcvd,
686                          Int                       iTimeOffset,
687                          TComPic*&                 rpcPic,
688                          TComPicYuv*&              rpcPicYuvRecOut,
689                          TComBitstream*&           rpcBitstreamOut,
690                          UInt                      uiPOCCurr )
691{
692  Int i;
693  //  Rec. output
694  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
695  for ( i = 0; i < iNumPicRcvd - iTimeOffset + 1; i++ )
696  {
697    iterPicYuvRec--;
698  }
699
700  rpcPicYuvRecOut = *(iterPicYuvRec);
701
702  //  Bitstream output
703  TComList<TComBitstream*>::iterator  iterBitstream = rcListBitstreamOut.begin();
704  for ( i = 0; i < m_iNumPicCoded; i++ )
705  {
706    iterBitstream++;
707  }
708  rpcBitstreamOut = *(iterBitstream);
709
710  //  Current pic.
711  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
712  while (iterPic != rcListPic.end())
713  {
714    rpcPic = *(iterPic);
715    if (rpcPic->getPOC() == (Int)uiPOCCurr)
716    {
717      break;
718    }
719    iterPic++;
720  }
721
722  assert (rpcPic->getPOC() == (Int)uiPOCCurr);
723
724  return;
725}
726
727Void TEncGOP::xScalePic( TComPic* pcPic )
728{
729  Int     x, y;
730
731  //===== calculate PSNR =====
732  Pel*  pRec    = pcPic->getPicYuvOrg()->getLumaAddr();
733  Int   iStride = pcPic->getStride();
734  Int   iWidth  = pcPic->getPicYuvOrg()->getWidth();
735  Int   iHeight = pcPic->getPicYuvOrg()->getHeight();
736
737  for( y = 0; y < iHeight; y++ )
738  {
739    for( x = 0; x < iWidth; x++ )
740    {
741      pRec[x] <<= g_uiBitIncrement;
742    }
743    pRec += iStride;
744  }
745
746  iHeight >>= 1;
747  iWidth  >>= 1;
748  iStride >>= 1;
749  pRec  = pcPic->getPicYuvOrg()->getCbAddr();
750
751  for( y = 0; y < iHeight; y++ )
752  {
753    for( x = 0; x < iWidth; x++ )
754    {
755      pRec[x] <<= g_uiBitIncrement;
756    }
757    pRec += iStride;
758  }
759
760  pRec  = pcPic->getPicYuvOrg()->getCrAddr();
761
762  for( y = 0; y < iHeight; y++ )
763  {
764    for( x = 0; x < iWidth; x++ )
765    {
766      pRec[x] <<= g_uiBitIncrement;
767    }
768    pRec += iStride;
769  }
770}
771
772Void TEncGOP::xDeScalePic( TComPic* pcPic, TComPicYuv* pcPicD )
773{
774  Int     x, y;
775  Int     offset = (g_uiBitIncrement>0)?(1<<(g_uiBitIncrement-1)):0;
776
777  //===== calculate PSNR =====
778  Pel*  pRecD   = pcPicD->getLumaAddr();
779  Pel*  pRec    = pcPic->getPicYuvRec()->getLumaAddr();
780  Int   iStride = pcPic->getStride();
781  Int   iWidth  = pcPic->getPicYuvOrg()->getWidth();
782  Int   iHeight = pcPic->getPicYuvOrg()->getHeight();
783
784  for( y = 0; y < iHeight; y++ )
785  {
786    for( x = 0; x < iWidth; x++ )
787    {
788#if IBDI_NOCLIP_RANGE
789      pRecD[x] = ( pRec[x] + offset ) >> g_uiBitIncrement;
790#else
791      pRecD[x] = ClipMax( ( pRec[x] + offset ) >> g_uiBitIncrement );
792#endif
793    }
794    pRecD += iStride;
795    pRec += iStride;
796  }
797
798  iHeight >>= 1;
799  iWidth  >>= 1;
800  iStride >>= 1;
801  pRecD = pcPicD->getCbAddr();
802  pRec  = pcPic->getPicYuvRec()->getCbAddr();
803
804  for( y = 0; y < iHeight; y++ )
805  {
806    for( x = 0; x < iWidth; x++ )
807    {
808#if IBDI_NOCLIP_RANGE
809      pRecD[x] = ( pRec[x] + offset ) >> g_uiBitIncrement;
810#else
811      pRecD[x] = ClipMax( ( pRec[x] + offset ) >> g_uiBitIncrement );
812#endif
813    }
814    pRecD += iStride;
815    pRec += iStride;
816  }
817
818  pRecD = pcPicD->getCrAddr();
819  pRec  = pcPic->getPicYuvRec()->getCrAddr();
820
821  for( y = 0; y < iHeight; y++ )
822  {
823    for( x = 0; x < iWidth; x++ )
824    {
825#if IBDI_NOCLIP_RANGE
826      pRecD[x] = ( pRec[x] + offset ) >> g_uiBitIncrement;
827#else
828      pRecD[x] = ClipMax( ( pRec[x] + offset ) >> g_uiBitIncrement );
829#endif
830    }
831    pRecD += iStride;
832    pRec += iStride;
833  }
834}
835
836UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
837{
838  Int     x, y;
839  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
840  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
841  UInt  uiShift = g_uiBitIncrement<<1;
842  Int   iTemp;
843
844  Int   iStride = pcPic0->getStride();
845  Int   iWidth  = pcPic0->getWidth();
846  Int   iHeight = pcPic0->getHeight();
847
848  UInt64  uiTotalDiff = 0;
849
850  for( y = 0; y < iHeight; y++ )
851  {
852    for( x = 0; x < iWidth; x++ )
853    {
854      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
855    }
856    pSrc0 += iStride;
857    pSrc1 += iStride;
858  }
859
860  iHeight >>= 1;
861  iWidth  >>= 1;
862  iStride >>= 1;
863
864  pSrc0  = pcPic0->getCbAddr();
865  pSrc1  = pcPic1->getCbAddr();
866
867  for( y = 0; y < iHeight; y++ )
868  {
869    for( x = 0; x < iWidth; x++ )
870    {
871      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
872    }
873    pSrc0 += iStride;
874    pSrc1 += iStride;
875  }
876
877  pSrc0  = pcPic0->getCrAddr();
878  pSrc1  = pcPic1->getCrAddr();
879
880  for( y = 0; y < iHeight; y++ )
881  {
882    for( x = 0; x < iWidth; x++ )
883    {
884      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
885    }
886    pSrc0 += iStride;
887    pSrc1 += iStride;
888  }
889
890  return uiTotalDiff;
891}
892
893Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, UInt uibits, Double dEncTime )
894{
895  Int     x, y;
896  UInt    uiSSDY  = 0;
897  UInt    uiSSDU  = 0;
898  UInt    uiSSDV  = 0;
899
900  Double  dYPSNR  = 0.0;
901  Double  dUPSNR  = 0.0;
902  Double  dVPSNR  = 0.0;
903
904  //===== calculate PSNR =====
905  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
906  Pel*  pRec    = pcPicD->getLumaAddr();
907  Int   iStride = pcPicD->getStride();
908
909  Int   iWidth;
910  Int   iHeight;
911
912  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
913  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
914
915  Int   iSize   = iWidth*iHeight;
916
917  for( y = 0; y < iHeight; y++ )
918  {
919    for( x = 0; x < iWidth; x++ )
920    {
921      Int iDiff = (Int)( pOrg[x] - pRec[x] );
922      uiSSDY   += iDiff * iDiff;
923    }
924    pOrg += iStride;
925    pRec += iStride;
926  }
927
928  iHeight >>= 1;
929  iWidth  >>= 1;
930  iStride >>= 1;
931  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
932  pRec  = pcPicD->getCbAddr();
933
934  for( y = 0; y < iHeight; y++ )
935  {
936    for( x = 0; x < iWidth; x++ )
937    {
938      Int iDiff = (Int)( pOrg[x] - pRec[x] );
939      uiSSDU   += iDiff * iDiff;
940    }
941    pOrg += iStride;
942    pRec += iStride;
943  }
944
945  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
946  pRec  = pcPicD->getCrAddr();
947
948  for( y = 0; y < iHeight; y++ )
949  {
950    for( x = 0; x < iWidth; x++ )
951    {
952      Int iDiff = (Int)( pOrg[x] - pRec[x] );
953      uiSSDV   += iDiff * iDiff;
954    }
955    pOrg += iStride;
956    pRec += iStride;
957  }
958
959  Double fRefValueY = 255.0 * 255.0 * (Double)iSize;
960  Double fRefValueC = fRefValueY / 4.0;
961  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
962  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
963  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
964
965  // fix: total bits should consider slice size bits (32bit)
966  uibits += 32;
967
968  //===== add PSNR =====
969  m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
970  if (pcPic->getSlice()->isIntra())
971  {
972    m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
973  }
974  if (pcPic->getSlice()->isInterP())
975  {
976    m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
977  }
978  if (pcPic->getSlice()->isInterB())
979  {
980    m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
981  }
982
983  //===== output =====
984  TComSlice*  pcSlice = pcPic->getSlice();
985  printf("\nPOC %4d ( %c-SLICE, QP %d ) %10d bits ",
986    pcSlice->getPOC(),
987    pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
988    pcSlice->getSliceQp(),
989    uibits );
990  printf( "[Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]  ", dYPSNR, dUPSNR, dVPSNR );
991  printf ("[ET %5.0f ] ", dEncTime );
992
993  for (Int iRefList = 0; iRefList < 2; iRefList++)
994  {
995    printf ("[L%d ", iRefList);
996    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
997    {
998      UInt uiOrgNumRefIdx;
999      uiOrgNumRefIdx = pcSlice->getNumRefIdx(RefPicList(iRefList))-pcSlice->getAddRefCnt(RefPicList(iRefList));
1000      UInt uiNewRefIdx= iRefIndex-uiOrgNumRefIdx;
1001
1002      if (iRefIndex >= uiOrgNumRefIdx)
1003      {
1004        if ( pcSlice->getEffectMode(RefPicList(iRefList), uiNewRefIdx)==EFF_WP_SO ||
1005             pcSlice->getEffectMode(RefPicList(iRefList), uiNewRefIdx)==EFF_WP_O )
1006        {
1007          printf ("%dw ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
1008        }
1009      }
1010      else
1011      {
1012        printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
1013      }
1014    }
1015    printf ("] ");
1016  }
1017
1018  fflush(stdout);
1019}
1020