Ticket #42: TEncGOP.2.cpp

File TEncGOP.2.cpp, 32.3 KB (added by anonymous, 11 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        m_pcEntropyCoder->encodeAlfParam(&cAlfParam);
497
498#if HHI_ALF
499        if( pcSlice->getSPS()->getALFSeparateQt() && cAlfParam.cu_control_flag )
500        {
501          m_pcAdaptiveLoopFilter->encodeQuadTree ( &cAlfParam, m_pcEntropyCoder, uiMaxAlfCtrlDepth );
502          m_pcAdaptiveLoopFilter->destroyQuadTree( &cAlfParam );
503        }
504#endif
505
506        m_pcAdaptiveLoopFilter->freeALFParam(&cAlfParam);
507      }
508
509#if HHI_INTERP_FILTER     
510      // MOMS prefilter reconstructed pic
511      if ( pcPic->getSlice()->isReferenced() && pcSlice->getUseMOMS() )
512      {
513        TComCoeffCalcMOMS cCoeffCalc;
514        cCoeffCalc.calcCoeffs( pcPic->getPicYuvRec(), pcPic->getPicYuvRecFilt(), pcPic->getSlice()->getInterpFilterType() );
515      }
516#endif
517
518      // File writing
519      m_pcSliceEncoder->encodeSlice( pcPic, pcBitstreamOut );
520#ifdef QC_SIFO
521      if( pcSlice->getUseSIFO() )
522        m_pcSIFOEncoder->ComputeFiltersAndOffsets(pcPic);
523#endif
524          if( pcSlice->getSymbolMode() == 3 )
525        getSliceEncoder()->getCUEncoder()->getCABAC4V2V()->setCntFlag(0);
526
527      //  End of bitstream & byte align
528#if ! HHI_NAL_UNIT_SYNTAX
529      if( pcSlice->getSymbolMode() )
530#endif
531      {
532        pcBitstreamOut->write( 1, 1 );
533        pcBitstreamOut->writeAlignZero();
534      }
535
536      pcBitstreamOut->flushBuffer();
537#if HHI_NAL_UNIT_SYNTAX
538      pcBitstreamOut->convertRBSPToPayload( uiPosBefore );
539#endif
540      // de-scaling of picture
541      xDeScalePic( pcPic, &pcPicD );
542
543      // save original picture
544      cPicOrg.copyToPic( pcPic->getPicYuvOrg() );
545
546      //-- For time output for each slice
547      Double dEncTime = (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
548
549      xCalculateAddPSNR( pcPic, &pcPicD, pcBitstreamOut->getNumberOfWrittenBits(), dEncTime );
550
551      // free original picture
552      cPicOrg.destroy();
553
554      //  Reconstruction buffer update
555      pcPicD.copyToPic(pcPicYuvRecOut);
556
557      pcPicD.destroy();
558
559      pcPic->setReconMark   ( true );
560
561      m_bFirst = false;
562      m_iNumPicCoded++;
563    }
564
565    // generalized B info.
566    if ( m_pcCfg->getHierarchicalCoding() == false && iDepth != 0 )
567      break;
568  }
569
570  pcOut->destroy();
571  delete pcOut;
572
573  assert ( m_iNumPicCoded == iNumPicRcvd );
574}
575
576Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded)
577{
578  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
579
580  //--CFG_KDY
581  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
582  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
583  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
584  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
585
586  //-- all
587  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
588  m_gcAnalyzeAll.printOut('a');
589
590  printf( "\n\nI Slices--------------------------------------------------------\n" );
591  m_gcAnalyzeI.printOut('i');
592
593  printf( "\n\nP Slices--------------------------------------------------------\n" );
594  m_gcAnalyzeP.printOut('p');
595
596  printf( "\n\nB Slices--------------------------------------------------------\n" );
597  m_gcAnalyzeB.printOut('b');
598
599#if _SUMMARY_OUT_
600  m_gcAnalyzeAll.printSummaryOut();
601#endif
602#if _SUMMARY_PIC_
603  m_gcAnalyzeI.printSummary('I');
604  m_gcAnalyzeP.printSummary('P');
605  m_gcAnalyzeB.printSummary('B');
606#endif
607}
608
609Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
610{
611  TComSlice* pcSlice = pcPic->getSlice();
612  Bool bCalcDist = false;
613
614  m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), m_pcCfg->getLoopFilterAlphaC0Offget(), m_pcCfg->getLoopFilterBetaOffget());
615  m_pcLoopFilter->loopFilterPic( pcPic );
616
617  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
618  m_pcEntropyCoder->resetEntropy    ();
619  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
620
621  // Adaptive Loop filter
622  if( pcSlice->getSPS()->getUseALF() )
623  {
624    ALFParam cAlfParam;
625    m_pcAdaptiveLoopFilter->allocALFParam(&cAlfParam);
626
627#if HHI_ALF
628    m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcEncTop->getRDGoOnSbacCoder() );
629#else
630    m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder);
631#endif
632
633    UInt uiMaxAlfCtrlDepth;
634    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, pcPic->getSlice()->getLambda(), ruiDist, ruiBits, uiMaxAlfCtrlDepth );
635    m_pcAdaptiveLoopFilter->endALFEnc();
636    m_pcAdaptiveLoopFilter->freeALFParam(&cAlfParam);
637  }
638
639  m_pcEntropyCoder->resetEntropy    ();
640  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
641
642  if (!bCalcDist)
643  ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
644}
645
646// ====================================================================================================================
647// Protected member functions
648// ====================================================================================================================
649
650Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut )
651{
652  assert( iNumPicRcvd > 0 );
653  Int i;
654
655  //  Set hierarchical B info.
656  m_iGopSize    = m_pcCfg->getGOPSize();
657  for( i=1 ; ; i++)
658  {
659    m_iHrchDepth = i;
660    if((m_iGopSize >> i)==0)
661    {
662      break;
663    }
664  }
665
666  //  Exception for the first frame
667  if ( iPOCLast == 0 )
668  {
669    m_iGopSize    = 1;
670    m_iHrchDepth  = 1;
671  }
672
673  if (m_iGopSize == 0)
674  {
675    m_iHrchDepth = 1;
676  }
677
678  return;
679}
680
681Void TEncGOP::xGetBuffer( TComList<TComPic*>&       rcListPic,
682                          TComList<TComPicYuv*>&    rcListPicYuvRecOut,
683                          TComList<TComBitstream*>& rcListBitstreamOut,
684                          Int                       iNumPicRcvd,
685                          Int                       iTimeOffset,
686                          TComPic*&                 rpcPic,
687                          TComPicYuv*&              rpcPicYuvRecOut,
688                          TComBitstream*&           rpcBitstreamOut,
689                          UInt                      uiPOCCurr )
690{
691  Int i;
692  //  Rec. output
693  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
694  for ( i = 0; i < iNumPicRcvd - iTimeOffset + 1; i++ )
695  {
696    iterPicYuvRec--;
697  }
698
699  rpcPicYuvRecOut = *(iterPicYuvRec);
700
701  //  Bitstream output
702  TComList<TComBitstream*>::iterator  iterBitstream = rcListBitstreamOut.begin();
703  for ( i = 0; i < m_iNumPicCoded; i++ )
704  {
705    iterBitstream++;
706  }
707  rpcBitstreamOut = *(iterBitstream);
708
709  //  Current pic.
710  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
711  while (iterPic != rcListPic.end())
712  {
713    rpcPic = *(iterPic);
714    if (rpcPic->getPOC() == (Int)uiPOCCurr)
715    {
716      break;
717    }
718    iterPic++;
719  }
720
721  assert (rpcPic->getPOC() == (Int)uiPOCCurr);
722
723  return;
724}
725
726Void TEncGOP::xScalePic( TComPic* pcPic )
727{
728  Int     x, y;
729
730  //===== calculate PSNR =====
731  Pel*  pRec    = pcPic->getPicYuvOrg()->getLumaAddr();
732  Int   iStride = pcPic->getStride();
733  Int   iWidth  = pcPic->getPicYuvOrg()->getWidth();
734  Int   iHeight = pcPic->getPicYuvOrg()->getHeight();
735
736  for( y = 0; y < iHeight; y++ )
737  {
738    for( x = 0; x < iWidth; x++ )
739    {
740      pRec[x] <<= g_uiBitIncrement;
741    }
742    pRec += iStride;
743  }
744
745  iHeight >>= 1;
746  iWidth  >>= 1;
747  iStride >>= 1;
748  pRec  = pcPic->getPicYuvOrg()->getCbAddr();
749
750  for( y = 0; y < iHeight; y++ )
751  {
752    for( x = 0; x < iWidth; x++ )
753    {
754      pRec[x] <<= g_uiBitIncrement;
755    }
756    pRec += iStride;
757  }
758
759  pRec  = pcPic->getPicYuvOrg()->getCrAddr();
760
761  for( y = 0; y < iHeight; y++ )
762  {
763    for( x = 0; x < iWidth; x++ )
764    {
765      pRec[x] <<= g_uiBitIncrement;
766    }
767    pRec += iStride;
768  }
769}
770
771Void TEncGOP::xDeScalePic( TComPic* pcPic, TComPicYuv* pcPicD )
772{
773  Int     x, y;
774  Int     offset = (g_uiBitIncrement>0)?(1<<(g_uiBitIncrement-1)):0;
775
776  //===== calculate PSNR =====
777  Pel*  pRecD   = pcPicD->getLumaAddr();
778  Pel*  pRec    = pcPic->getPicYuvRec()->getLumaAddr();
779  Int   iStride = pcPic->getStride();
780  Int   iWidth  = pcPic->getPicYuvOrg()->getWidth();
781  Int   iHeight = pcPic->getPicYuvOrg()->getHeight();
782
783  for( y = 0; y < iHeight; y++ )
784  {
785    for( x = 0; x < iWidth; x++ )
786    {
787#if IBDI_NOCLIP_RANGE
788      pRecD[x] = ( pRec[x] + offset ) >> g_uiBitIncrement;
789#else
790      pRecD[x] = ClipMax( ( pRec[x] + offset ) >> g_uiBitIncrement );
791#endif
792    }
793    pRecD += iStride;
794    pRec += iStride;
795  }
796
797  iHeight >>= 1;
798  iWidth  >>= 1;
799  iStride >>= 1;
800  pRecD = pcPicD->getCbAddr();
801  pRec  = pcPic->getPicYuvRec()->getCbAddr();
802
803  for( y = 0; y < iHeight; y++ )
804  {
805    for( x = 0; x < iWidth; x++ )
806    {
807#if IBDI_NOCLIP_RANGE
808      pRecD[x] = ( pRec[x] + offset ) >> g_uiBitIncrement;
809#else
810      pRecD[x] = ClipMax( ( pRec[x] + offset ) >> g_uiBitIncrement );
811#endif
812    }
813    pRecD += iStride;
814    pRec += iStride;
815  }
816
817  pRecD = pcPicD->getCrAddr();
818  pRec  = pcPic->getPicYuvRec()->getCrAddr();
819
820  for( y = 0; y < iHeight; y++ )
821  {
822    for( x = 0; x < iWidth; x++ )
823    {
824#if IBDI_NOCLIP_RANGE
825      pRecD[x] = ( pRec[x] + offset ) >> g_uiBitIncrement;
826#else
827      pRecD[x] = ClipMax( ( pRec[x] + offset ) >> g_uiBitIncrement );
828#endif
829    }
830    pRecD += iStride;
831    pRec += iStride;
832  }
833}
834
835UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
836{
837  Int     x, y;
838  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
839  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
840  UInt  uiShift = g_uiBitIncrement<<1;
841  Int   iTemp;
842
843  Int   iStride = pcPic0->getStride();
844  Int   iWidth  = pcPic0->getWidth();
845  Int   iHeight = pcPic0->getHeight();
846
847  UInt64  uiTotalDiff = 0;
848
849  for( y = 0; y < iHeight; y++ )
850  {
851    for( x = 0; x < iWidth; x++ )
852    {
853      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
854    }
855    pSrc0 += iStride;
856    pSrc1 += iStride;
857  }
858
859  iHeight >>= 1;
860  iWidth  >>= 1;
861  iStride >>= 1;
862
863  pSrc0  = pcPic0->getCbAddr();
864  pSrc1  = pcPic1->getCbAddr();
865
866  for( y = 0; y < iHeight; y++ )
867  {
868    for( x = 0; x < iWidth; x++ )
869    {
870      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
871    }
872    pSrc0 += iStride;
873    pSrc1 += iStride;
874  }
875
876  pSrc0  = pcPic0->getCrAddr();
877  pSrc1  = pcPic1->getCrAddr();
878
879  for( y = 0; y < iHeight; y++ )
880  {
881    for( x = 0; x < iWidth; x++ )
882    {
883      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
884    }
885    pSrc0 += iStride;
886    pSrc1 += iStride;
887  }
888
889  return uiTotalDiff;
890}
891
892Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, UInt uibits, Double dEncTime )
893{
894  Int     x, y;
895  UInt    uiSSDY  = 0;
896  UInt    uiSSDU  = 0;
897  UInt    uiSSDV  = 0;
898
899  Double  dYPSNR  = 0.0;
900  Double  dUPSNR  = 0.0;
901  Double  dVPSNR  = 0.0;
902
903  //===== calculate PSNR =====
904  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
905  Pel*  pRec    = pcPicD->getLumaAddr();
906  Int   iStride = pcPicD->getStride();
907
908  Int   iWidth;
909  Int   iHeight;
910
911  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
912  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
913
914  Int   iSize   = iWidth*iHeight;
915
916  for( y = 0; y < iHeight; y++ )
917  {
918    for( x = 0; x < iWidth; x++ )
919    {
920      Int iDiff = (Int)( pOrg[x] - pRec[x] );
921      uiSSDY   += iDiff * iDiff;
922    }
923    pOrg += iStride;
924    pRec += iStride;
925  }
926
927  iHeight >>= 1;
928  iWidth  >>= 1;
929  iStride >>= 1;
930  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
931  pRec  = pcPicD->getCbAddr();
932
933  for( y = 0; y < iHeight; y++ )
934  {
935    for( x = 0; x < iWidth; x++ )
936    {
937      Int iDiff = (Int)( pOrg[x] - pRec[x] );
938      uiSSDU   += iDiff * iDiff;
939    }
940    pOrg += iStride;
941    pRec += iStride;
942  }
943
944  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
945  pRec  = pcPicD->getCrAddr();
946
947  for( y = 0; y < iHeight; y++ )
948  {
949    for( x = 0; x < iWidth; x++ )
950    {
951      Int iDiff = (Int)( pOrg[x] - pRec[x] );
952      uiSSDV   += iDiff * iDiff;
953    }
954    pOrg += iStride;
955    pRec += iStride;
956  }
957
958  Double fRefValueY = 255.0 * 255.0 * (Double)iSize;
959  Double fRefValueC = fRefValueY / 4.0;
960  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
961  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
962  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
963
964  // fix: total bits should consider slice size bits (32bit)
965  uibits += 32;
966
967  //===== add PSNR =====
968  m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
969  if (pcPic->getSlice()->isIntra())
970  {
971    m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
972  }
973  if (pcPic->getSlice()->isInterP())
974  {
975    m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
976  }
977  if (pcPic->getSlice()->isInterB())
978  {
979    m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
980  }
981
982  //===== output =====
983  TComSlice*  pcSlice = pcPic->getSlice();
984  printf("\nPOC %4d ( %c-SLICE, QP %d ) %10d bits ",
985    pcSlice->getPOC(),
986    pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B',
987    pcSlice->getSliceQp(),
988    uibits );
989  printf( "[Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]  ", dYPSNR, dUPSNR, dVPSNR );
990  printf ("[ET %5.0f ] ", dEncTime );
991
992  for (Int iRefList = 0; iRefList < 2; iRefList++)
993  {
994    printf ("[L%d ", iRefList);
995    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
996    {
997      UInt uiOrgNumRefIdx;
998      uiOrgNumRefIdx = pcSlice->getNumRefIdx(RefPicList(iRefList))-pcSlice->getAddRefCnt(RefPicList(iRefList));
999      UInt uiNewRefIdx= iRefIndex-uiOrgNumRefIdx;
1000
1001      if (iRefIndex >= uiOrgNumRefIdx)
1002      {
1003        if ( pcSlice->getEffectMode(RefPicList(iRefList), uiNewRefIdx)==EFF_WP_SO ||
1004             pcSlice->getEffectMode(RefPicList(iRefList), uiNewRefIdx)==EFF_WP_O )
1005        {
1006          printf ("%dw ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
1007        }
1008      }
1009      else
1010      {
1011        printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
1012      }
1013    }
1014    printf ("] ");
1015  }
1016
1017  fflush(stdout);
1018}
1019