source: SHVCSoftware/branches/SHM-1.1-dev/source/Lib/TLibEncoder/TEncGOP.cpp @ 687

Last change on this file since 687 was 39, checked in by seregin, 12 years ago

adding braces for compliant formating

File size: 93.0 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2012, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncGOP.cpp
35    \brief    GOP encoder class
36*/
37
38#include <list>
39#include <algorithm>
40#include <functional>
41
42#include "TEncTop.h"
43#include "TEncGOP.h"
44#include "TEncAnalyze.h"
45#include "libmd5/MD5.h"
46#include "TLibCommon/SEI.h"
47#include "TLibCommon/NAL.h"
48#include "NALwrite.h"
49#include <time.h>
50#include <math.h>
51
52using namespace std;
53//! \ingroup TLibEncoder
54//! \{
55
56// ====================================================================================================================
57// Constructor / destructor / initialization / destroy
58// ====================================================================================================================
59Int getLSB(Int poc, Int maxLSB)
60{
61  if (poc >= 0)
62  {
63    return poc % maxLSB;
64  }
65  else
66  {
67    return (maxLSB - ((-poc) % maxLSB)) % maxLSB;
68  }
69}
70
71TEncGOP::TEncGOP()
72{
73  m_iLastIDR            = 0;
74  m_iGopSize            = 0;
75  m_iNumPicCoded        = 0; //Niko
76  m_bFirst              = true;
77 
78  m_pcCfg               = NULL;
79  m_pcSliceEncoder      = NULL;
80  m_pcListPic           = NULL;
81 
82  m_pcEntropyCoder      = NULL;
83  m_pcCavlcCoder        = NULL;
84  m_pcSbacCoder         = NULL;
85  m_pcBinCABAC          = NULL;
86 
87  m_bSeqFirst           = true;
88 
89  m_bRefreshPending     = 0;
90  m_pocCRA            = 0;
91#if LTRP_IN_SPS
92  m_numLongTermRefPicSPS = 0;
93  ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
94  ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
95#endif
96#if BUFFERING_PERIOD_AND_TIMING_SEI
97  m_cpbRemovalDelay   = 0;
98  m_lastBPSEI         = 0;
99#endif
100
101#if SVC_UPSAMPLING
102  m_pcPredSearch        = NULL;
103#endif
104  return;
105}
106
107TEncGOP::~TEncGOP()
108{
109}
110
111/** Create list to contain pointers to LCU start addresses of slice.
112 * \param iWidth, iHeight are picture width, height. iMaxCUWidth, iMaxCUHeight are LCU width, height.
113 */
114#if SVC_EXTENSION
115Void  TEncGOP::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UInt layerId )
116#else
117Void  TEncGOP::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight )
118#endif
119{
120  m_bLongtermTestPictureHasBeenCoded = 0;
121  m_bLongtermTestPictureHasBeenCoded2 = 0;
122
123#if SVC_EXTENSION
124  m_layerId = layerId;
125#endif
126}
127
128Void  TEncGOP::destroy()
129{
130}
131
132Void TEncGOP::init ( TEncTop* pcTEncTop )
133{
134  m_pcEncTop     = pcTEncTop;
135  m_pcCfg                = pcTEncTop;
136  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
137  m_pcListPic            = pcTEncTop->getListPic();
138
139#if SVC_EXTENSION
140  m_ppcTEncTop           = pcTEncTop->getLayerEnc();
141#endif
142 
143  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
144  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
145  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
146  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
147  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
148  m_pcBitCounter         = pcTEncTop->getBitCounter();
149 
150#if !REMOVE_ALF
151  // Adaptive Loop filter
152  m_pcAdaptiveLoopFilter = pcTEncTop->getAdaptiveLoopFilter();
153#endif
154  //--Adaptive Loop filter
155  m_pcSAO                = pcTEncTop->getSAO();
156  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
157#if BUFFERING_PERIOD_AND_TIMING_SEI
158  m_lastBPSEI          = 0;
159  m_totalCoded         = 0;
160#endif
161
162#if SVC_UPSAMPLING
163  m_pcPredSearch         = pcTEncTop->getPredSearch();                       ///< encoder search class
164#endif
165}
166
167// ====================================================================================================================
168// Public member functions
169// ====================================================================================================================
170#if SVC_EXTENSION
171Void TEncGOP::compressGOP( Int iPicIdInGOP, Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP)
172#else
173Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP)
174#endif
175{
176  TComPic*        pcPic;
177  TComPicYuv*     pcPicYuvRecOut;
178  TComSlice*      pcSlice;
179  TComOutputBitstream  *pcBitstreamRedirect;
180  pcBitstreamRedirect = new TComOutputBitstream;
181  AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
182  UInt                  uiOneBitstreamPerSliceLength = 0;
183  TEncSbac* pcSbacCoders = NULL;
184  TComOutputBitstream* pcSubstreamsOut = NULL;
185
186  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut );
187
188  m_iNumPicCoded = 0;
189#if BUFFERING_PERIOD_AND_TIMING_SEI
190  SEIPictureTiming pictureTimingSEI;
191  UInt *accumBitsDU = NULL;
192  UInt *accumNalsDU = NULL;
193#endif
194#if SVC_EXTENSION
195  for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
196#else
197  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
198#endif
199  {
200    UInt uiColDir = 1;
201    //-- For time output for each slice
202    long iBeforeTime = clock();
203
204    //select uiColDir
205    Int iCloseLeft=1, iCloseRight=-1;
206    for(Int i = 0; i<m_pcCfg->getGOPEntry(iGOPid).m_numRefPics; i++) 
207    {
208      Int iRef = m_pcCfg->getGOPEntry(iGOPid).m_referencePics[i];
209      if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
210      {
211        iCloseRight=iRef;
212      }
213      else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
214      {
215        iCloseLeft=iRef;
216      }
217    }
218    if(iCloseRight>-1)
219    {
220      iCloseRight=iCloseRight+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
221    }
222    if(iCloseLeft<1) 
223    {
224      iCloseLeft=iCloseLeft+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
225      while(iCloseLeft<0)
226      {
227        iCloseLeft+=m_iGopSize;
228      }
229    }
230    Int iLeftQP=0, iRightQP=0;
231    for(Int i=0; i<m_iGopSize; i++)
232    {
233      if(m_pcCfg->getGOPEntry(i).m_POC==(iCloseLeft%m_iGopSize)+1)
234      {
235        iLeftQP= m_pcCfg->getGOPEntry(i).m_QPOffset;
236      }
237      if (m_pcCfg->getGOPEntry(i).m_POC==(iCloseRight%m_iGopSize)+1)
238      {
239        iRightQP=m_pcCfg->getGOPEntry(i).m_QPOffset;
240      }
241    }
242    if(iCloseRight>-1&&iRightQP<iLeftQP)
243    {
244      uiColDir=0;
245    }
246
247    /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
248    UInt uiPOCCurr = iPOCLast -iNumPicRcvd+ m_pcCfg->getGOPEntry(iGOPid).m_POC;
249    Int iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
250    if(iPOCLast == 0)
251    {
252      uiPOCCurr=0;
253      iTimeOffset = 1;
254    }
255    if(uiPOCCurr>=m_pcCfg->getFrameToBeEncoded())
256    {
257      continue;
258    }
259
260#if SUPPORT_FOR_RAP_N_LP
261    if( getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR || getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
262#else
263    if(getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR)
264#endif
265    {
266      m_iLastIDR = uiPOCCurr;
267    }       
268    // start a new access unit: create an entry in the list of output access units
269    accessUnitsInGOP.push_back(AccessUnit());
270    AccessUnit& accessUnit = accessUnitsInGOP.back();
271    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, uiPOCCurr );
272
273    //  Slice data initialization
274    pcPic->clearSliceBuffer();
275    assert(pcPic->getNumAllocatedSlice() == 1);
276    m_pcSliceEncoder->setSliceIdx(0);
277    pcPic->setCurrSliceIdx(0);
278#if SVC_EXTENSION
279      pcPic->setLayerId( m_layerId );
280#endif
281
282#if !REMOVE_APS
283    std::vector<TComAPS>& vAPS = m_pcEncTop->getAPS();
284#endif
285    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, uiPOCCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS() );
286    pcSlice->setLastIDR(m_iLastIDR);
287    pcSlice->setSliceIdx(0);
288    //set default slice level flag to the same as SPS level flag
289#if MOVE_LOOP_FILTER_SLICES_FLAG
290    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
291#else
292    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getSPS()->getLFCrossSliceBoundaryFlag()  );
293#endif
294    pcSlice->setScalingList ( m_pcEncTop->getScalingList()  );
295#if TS_FLAT_QUANTIZATION_MATRIX
296    pcSlice->getScalingList()->setUseTransformSkip(m_pcEncTop->getPPS()->getUseTransformSkip());
297#endif
298    if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF)
299    {
300      m_pcEncTop->getTrQuant()->setFlatScalingList();
301      m_pcEncTop->getTrQuant()->setUseScalingList(false);
302      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
303      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
304    }
305    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT)
306    {
307      pcSlice->setDefaultScalingList ();
308      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
309      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
310      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
311      m_pcEncTop->getTrQuant()->setUseScalingList(true);
312    }
313    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ)
314    {
315      if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile()))
316      {
317        pcSlice->setDefaultScalingList ();
318      }
319      pcSlice->getScalingList()->checkDcOfMatrix();
320      m_pcEncTop->getSPS()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList());
321      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
322      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
323      m_pcEncTop->getTrQuant()->setUseScalingList(true);
324    }
325    else
326    {
327      printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId());
328      assert(0);
329    }
330
331    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
332    {
333      pcSlice->setSliceType(P_SLICE);
334    }
335
336    // Set the nal unit type
337    pcSlice->setNalUnitType(getNalUnitType(uiPOCCurr));
338#if REF_IDX_FRAMEWORK
339    if( m_layerId > 0 && (uiPOCCurr % m_pcCfg->getIntraPeriod() == 0) )
340    {
341      pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA);
342    }
343    if( m_layerId > 0 && !m_pcEncTop->getElRapSliceTypeB() )
344    {
345      if( (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA) &&
346          (pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA) &&
347           pcSlice->getSliceType() == B_SLICE )
348      {
349        pcSlice->setSliceType(P_SLICE);
350      }
351    }
352#endif
353#if TEMPORAL_LAYER_NON_REFERENCE
354    if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_TRAIL_R)
355    {
356      if(pcSlice->getTemporalLayerNonReferenceFlag())
357      {
358        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TRAIL_N);
359      }
360    }
361#endif
362
363    // Do decoding refresh marking if any
364    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
365    m_pcEncTop->selectReferencePictureSet(pcSlice, uiPOCCurr, iGOPid,rcListPic);
366    pcSlice->getRPS()->setNumberOfLongtermPictures(0);
367
368    if(pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0)
369    {
370      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS());
371    }
372    pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
373
374    if(pcSlice->getTLayer() > 0)
375    {
376      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic, pcSlice->getRPS()) || pcSlice->getSPS()->getTemporalIdNestingFlag())
377      {
378#if TEMPORAL_LAYER_NON_REFERENCE
379        if(pcSlice->getTemporalLayerNonReferenceFlag())
380        {
381          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
382        }
383        else
384        {
385          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TLA);
386        }
387#else
388        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TLA);
389#endif
390      }
391#if STSA
392      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic, pcSlice->getRPS()))
393      {
394          Bool isSTSA=true;
395          for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
396          {
397              Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
398              if(lTid==pcSlice->getTLayer()) 
399              {
400                  TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
401                  for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
402                  {
403                      if(nRPS->getUsed(jj)) {
404                          Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
405                          Int kk=0;
406                          for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
407                          {
408                              if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
409                                  break;
410                          }
411                          Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
412                          if(tTid >= pcSlice->getTLayer())
413                          {
414                              isSTSA=false;
415                              break;
416                          }
417                         
418                      }
419                  }
420              }
421          }
422          if(isSTSA==true)
423          {   
424#if TEMPORAL_LAYER_NON_REFERENCE
425            if(pcSlice->getTemporalLayerNonReferenceFlag())
426            {
427              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
428            }
429            else
430            {
431              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
432            }
433#else
434            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
435#endif
436          }
437      }
438#endif
439
440    }
441    arrangeLongtermPicturesInRPS(pcSlice, rcListPic);
442    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
443    refPicListModification->setRefPicListModificationFlagL0(0);
444    refPicListModification->setRefPicListModificationFlagL1(0);
445    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
446    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
447
448#if ADAPTIVE_QP_SELECTION
449    pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
450#endif     
451
452#if SVC_EXTENSION     
453      if(m_layerId > 0)
454      {
455        TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId-1]->getListPic();
456        pcSlice->setBaseColPic (*cListPic, m_layerId );
457#if SVC_UPSAMPLING
458        if ( pcPic->isSpatialEnhLayer())
459        {   
460          m_pcPredSearch->upsampleBasePic( pcPic->getFullPelBaseRec(), pcSlice->getBaseColPic()->getPicYuvRec(), pcPic->getPicYuvRec() );
461        }
462        else
463        {
464        pcPic->setFullPelBaseRec( pcSlice->getBaseColPic()->getPicYuvRec() );
465        }
466        pcSlice->setFullPelBaseRec ( pcPic->getFullPelBaseRec() );
467#endif
468      }
469#endif
470
471#if REF_IDX_FRAMEWORK
472    if( pcSlice->getSliceType() == B_SLICE )
473    {
474      pcSlice->setColFromL0Flag(1-uiColDir);
475    }
476#endif
477
478    //  Set reference list
479    pcSlice->setRefPicList ( rcListPic );
480#if REF_IDX_FRAMEWORK
481    if(m_layerId > 0)
482    {
483      m_pcEncTop->setILRPic(pcPic);
484
485#if REF_IDX_MFM
486      pcSlice->setRefPOCListILP(m_pcEncTop->getIlpList(), pcSlice->getBaseColPic());
487#endif
488      pcSlice->addRefPicList ( m_pcEncTop->getIlpList(), 1);
489
490#if REF_IDX_MFM
491      Bool found         = false;
492      UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
493      UInt ColRefIdx     = pcSlice->getColRefIdx();
494      for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
495      { 
496        if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->getIsILR() ) 
497        { 
498          ColRefIdx = colIdx; 
499          found = true;
500          break; 
501        }
502      }
503
504      if( found == false )
505      {
506        ColFromL0Flag = 1 - ColFromL0Flag;
507        for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
508        { 
509          if( pcSlice->getRefPic( RefPicList(1 - ColFromL0Flag), colIdx)->getIsILR() ) 
510          { 
511            ColRefIdx = colIdx; 
512            found = true; 
513            break; 
514          } 
515        }
516      }
517
518      if(found == true)
519      {
520        pcSlice->setColFromL0Flag(ColFromL0Flag);
521        pcSlice->setColRefIdx(ColRefIdx);
522      }
523#endif
524    }
525#endif
526
527    //  Slice info. refinement
528    if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
529    {
530      pcSlice->setSliceType ( P_SLICE );
531    }
532
533    if (pcSlice->getSliceType() != B_SLICE || !pcSlice->getSPS()->getUseLComb())
534    {
535      pcSlice->setNumRefIdx(REF_PIC_LIST_C, 0);
536      pcSlice->setRefPicListCombinationFlag(false);
537      pcSlice->setRefPicListModificationFlagLC(false);
538    }
539    else
540    {
541      pcSlice->setRefPicListCombinationFlag(pcSlice->getSPS()->getUseLComb());
542      pcSlice->setNumRefIdx(REF_PIC_LIST_C, pcSlice->getNumRefIdx(REF_PIC_LIST_0));
543    }
544
545    if (pcSlice->getSliceType() == B_SLICE)
546    {
547#if !REF_IDX_FRAMEWORK
548      pcSlice->setColFromL0Flag(1-uiColDir);
549#endif
550      Bool bLowDelay = true;
551      Int  iCurrPOC  = pcSlice->getPOC();
552      Int iRefIdx = 0;
553
554      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
555      {
556        if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
557        {
558          bLowDelay = false;
559        }
560      }
561      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
562      {
563        if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
564        {
565          bLowDelay = false;
566        }
567      }
568
569      pcSlice->setCheckLDC(bLowDelay); 
570    }
571
572    uiColDir = 1-uiColDir;
573
574    //-------------------------------------------------------------
575    pcSlice->setRefPOCList();
576
577    pcSlice->setNoBackPredFlag( false );
578    if ( pcSlice->getSliceType() == B_SLICE && !pcSlice->getRefPicListCombinationFlag())
579    {
580      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
581      {
582        pcSlice->setNoBackPredFlag( true );
583        int i;
584        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
585        {
586          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
587          {
588            pcSlice->setNoBackPredFlag( false );
589            break;
590          }
591        }
592      }
593    }
594
595    if(pcSlice->getNoBackPredFlag())
596    {
597      pcSlice->setNumRefIdx(REF_PIC_LIST_C, 0);
598    }
599    pcSlice->generateCombinedList();
600
601    if (m_pcEncTop->getTMVPModeId() == 2)
602    {
603      if (iGOPid == 0) // first picture in SOP (i.e. forward B)
604      {
605        pcSlice->setEnableTMVPFlag(0);
606      }
607      else
608      {
609        // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
610        pcSlice->setEnableTMVPFlag(1);
611      }
612      pcSlice->getSPS()->setTMVPFlagsPresent(1);
613    }
614    else if (m_pcEncTop->getTMVPModeId() == 1)
615    {
616      pcSlice->getSPS()->setTMVPFlagsPresent(1);
617      pcSlice->setEnableTMVPFlag(1);
618    }
619    else
620    {
621      pcSlice->getSPS()->setTMVPFlagsPresent(0);
622      pcSlice->setEnableTMVPFlag(0);
623    }
624    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
625    //  Slice compression
626    if (m_pcCfg->getUseASR())
627    {
628      m_pcSliceEncoder->setSearchRange(pcSlice);
629    }
630
631    Bool bGPBcheck=false;
632    if ( pcSlice->getSliceType() == B_SLICE)
633    {
634      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
635      {
636        bGPBcheck=true;
637        int i;
638        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
639        {
640          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
641          {
642            bGPBcheck=false;
643            break;
644          }
645        }
646      }
647    }
648    if(bGPBcheck)
649    {
650      pcSlice->setMvdL1ZeroFlag(true);
651    }
652    else
653    {
654      pcSlice->setMvdL1ZeroFlag(false);
655    }
656    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
657
658    UInt uiNumSlices = 1;
659
660    UInt uiInternalAddress = pcPic->getNumPartInCU()-4;
661    UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1;
662    UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
663    UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
664    UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
665    UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
666    while(uiPosX>=uiWidth||uiPosY>=uiHeight) 
667    {
668      uiInternalAddress--;
669      uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
670      uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
671    }
672    uiInternalAddress++;
673    if(uiInternalAddress==pcPic->getNumPartInCU()) 
674    {
675      uiInternalAddress = 0;
676      uiExternalAddress++;
677    }
678    UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress;
679
680    UInt uiCummulativeTileWidth;
681    UInt uiCummulativeTileHeight;
682    Int  p, j;
683    UInt uiEncCUAddr;
684
685    //set NumColumnsMinus1 and NumRowsMinus1
686    pcPic->getPicSym()->setNumColumnsMinus1( pcSlice->getPPS()->getNumColumnsMinus1() );
687    pcPic->getPicSym()->setNumRowsMinus1( pcSlice->getPPS()->getNumRowsMinus1() );
688
689    //create the TComTileArray
690    pcPic->getPicSym()->xCreateTComTileArray();
691
692    if( pcSlice->getPPS()->getUniformSpacingFlag() == 1 )
693    {
694      //set the width for each tile
695      for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
696      {
697        for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1()+1; p++)
698        {
699          pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->
700            setTileWidth( (p+1)*pcPic->getPicSym()->getFrameWidthInCU()/(pcPic->getPicSym()->getNumColumnsMinus1()+1) 
701            - (p*pcPic->getPicSym()->getFrameWidthInCU())/(pcPic->getPicSym()->getNumColumnsMinus1()+1) );
702        }
703      }
704
705      //set the height for each tile
706      for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
707      {
708        for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1()+1; p++)
709        {
710          pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->
711            setTileHeight( (p+1)*pcPic->getPicSym()->getFrameHeightInCU()/(pcPic->getPicSym()->getNumRowsMinus1()+1) 
712            - (p*pcPic->getPicSym()->getFrameHeightInCU())/(pcPic->getPicSym()->getNumRowsMinus1()+1) );   
713        }
714      }
715    }
716    else
717    {
718      //set the width for each tile
719      for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
720      {
721        uiCummulativeTileWidth = 0;
722        for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1(); p++)
723        {
724          pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->setTileWidth( pcSlice->getPPS()->getColumnWidth(p) );
725          uiCummulativeTileWidth += pcSlice->getPPS()->getColumnWidth(p);
726        }
727        pcPic->getPicSym()->getTComTile(j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p)->setTileWidth( pcPic->getPicSym()->getFrameWidthInCU()-uiCummulativeTileWidth );
728      }
729
730      //set the height for each tile
731      for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
732      {
733        uiCummulativeTileHeight = 0;
734        for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1(); p++)
735        {
736          pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->setTileHeight( pcSlice->getPPS()->getRowHeight(p) );
737          uiCummulativeTileHeight += pcSlice->getPPS()->getRowHeight(p);
738        }
739        pcPic->getPicSym()->getTComTile(p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j)->setTileHeight( pcPic->getPicSym()->getFrameHeightInCU()-uiCummulativeTileHeight );
740      }
741    }
742    //intialize each tile of the current picture
743    pcPic->getPicSym()->xInitTiles();
744
745    // Allocate some coders, now we know how many tiles there are.
746    Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
747
748    //generate the Coding Order Map and Inverse Coding Order Map
749    for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
750    {
751      pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr);
752      pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p);
753    }
754    pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());   
755    pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
756
757    // Allocate some coders, now we know how many tiles there are.
758    m_pcEncTop->createWPPCoders(iNumSubstreams);
759    pcSbacCoders = m_pcEncTop->getSbacCoders();
760    pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];
761
762    UInt uiStartCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
763    UInt uiStartCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
764    pcSlice->setSliceCurStartCUAddr( uiStartCUAddrSlice ); // Setting "start CU addr" for current slice
765    m_storedStartCUAddrForEncodingSlice.clear();
766
767    UInt uiStartCUAddrDependentSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
768    UInt uiStartCUAddrDependentSlice    = 0; // used to keep track of current Dependent slice's starting CU addr.
769    pcSlice->setDependentSliceCurStartCUAddr( uiStartCUAddrDependentSlice ); // Setting "start CU addr" for current Dependent slice
770
771    m_storedStartCUAddrForEncodingDependentSlice.clear();
772    UInt uiNextCUAddr = 0;
773    m_storedStartCUAddrForEncodingSlice.push_back (uiNextCUAddr);
774    uiStartCUAddrSliceIdx++;
775    m_storedStartCUAddrForEncodingDependentSlice.push_back(uiNextCUAddr);
776    uiStartCUAddrDependentSliceIdx++;
777
778#if AVC_BASE
779    if( m_layerId == 0 )
780    {
781      pcPic->getPicYuvOrg()->copyToPic( pcPic->getPicYuvRec() );
782#if AVC_SYNTAX
783      pcPic->readBLSyntax( m_ppcTEncTop[0]->getBLSyntaxFile(), SYNTAX_BYTES );
784#endif
785      return;
786    }
787#endif
788
789    while(uiNextCUAddr<uiRealEndAddress) // determine slice boundaries
790    {
791      pcSlice->setNextSlice       ( false );
792      pcSlice->setNextDependentSlice( false );
793      assert(pcPic->getNumAllocatedSlice() == uiStartCUAddrSliceIdx);
794      m_pcSliceEncoder->precompressSlice( pcPic );
795      m_pcSliceEncoder->compressSlice   ( pcPic );
796
797      Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextDependentSlice());
798      if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE))
799      {
800        uiStartCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
801        // Reconstruction slice
802        m_storedStartCUAddrForEncodingSlice.push_back(uiStartCUAddrSlice);
803        uiStartCUAddrSliceIdx++;
804        // Dependent slice
805        if (uiStartCUAddrDependentSliceIdx>0 && m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx-1] != uiStartCUAddrSlice)
806        {
807          m_storedStartCUAddrForEncodingDependentSlice.push_back(uiStartCUAddrSlice);
808          uiStartCUAddrDependentSliceIdx++;
809        }
810
811        if (uiStartCUAddrSlice < uiRealEndAddress)
812        {
813          pcPic->allocateNewSlice();         
814          pcPic->setCurrSliceIdx                  ( uiStartCUAddrSliceIdx-1 );
815          m_pcSliceEncoder->setSliceIdx           ( uiStartCUAddrSliceIdx-1 );
816          pcSlice = pcPic->getSlice               ( uiStartCUAddrSliceIdx-1 );
817          pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
818          pcSlice->setSliceIdx                    ( uiStartCUAddrSliceIdx-1 );
819          pcSlice->setSliceCurStartCUAddr         ( uiStartCUAddrSlice      );
820          pcSlice->setDependentSliceCurStartCUAddr  ( uiStartCUAddrSlice      );
821          pcSlice->setSliceBits(0);
822          uiNumSlices ++;
823        }
824      }
825      else if (pcSlice->isNextDependentSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE))
826      {
827        uiStartCUAddrDependentSlice                                                     = pcSlice->getDependentSliceCurEndCUAddr();
828        m_storedStartCUAddrForEncodingDependentSlice.push_back(uiStartCUAddrDependentSlice);
829        uiStartCUAddrDependentSliceIdx++;
830        pcSlice->setDependentSliceCurStartCUAddr( uiStartCUAddrDependentSlice );
831      }
832      else
833      {
834        uiStartCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
835        uiStartCUAddrDependentSlice                                                     = pcSlice->getDependentSliceCurEndCUAddr();
836      }       
837
838      uiNextCUAddr = (uiStartCUAddrSlice > uiStartCUAddrDependentSlice) ? uiStartCUAddrSlice : uiStartCUAddrDependentSlice;
839    }
840    m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
841    uiStartCUAddrSliceIdx++;
842    m_storedStartCUAddrForEncodingDependentSlice.push_back(pcSlice->getSliceCurEndCUAddr());
843    uiStartCUAddrDependentSliceIdx++;
844
845    pcSlice = pcPic->getSlice(0);
846
847#if SAO_LCU_BOUNDARY
848    // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
849    if( m_pcCfg->getSaoLcuBasedOptimization() && m_pcCfg->getSaoLcuBoundary() )
850    {
851      m_pcSAO->resetStats();
852      m_pcSAO->calcSaoStatsCu_BeforeDblk( pcPic );
853    }
854#endif
855
856    //-- Loop filter
857    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
858    m_pcLoopFilter->setCfg(pcSlice->getPPS()->getDeblockingFilterControlPresentFlag(), pcSlice->getDeblockingFilterDisable(), pcSlice->getDeblockingFilterBetaOffsetDiv2(), pcSlice->getDeblockingFilterTcOffsetDiv2(), bLFCrossTileBoundary);
859    m_pcLoopFilter->loopFilterPic( pcPic );
860
861    pcSlice = pcPic->getSlice(0);
862#if REMOVE_ALF
863    if(pcSlice->getSPS()->getUseSAO())
864#else
865    if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
866#endif
867    {
868#if !REMOVE_FGS
869      Int sliceGranularity = pcSlice->getPPS()->getSliceGranularity();
870#endif
871      std::vector<Bool> LFCrossSliceBoundaryFlag;
872      for(Int s=0; s< uiNumSlices; s++)
873      {
874        LFCrossSliceBoundaryFlag.push_back(  ((uiNumSlices==1)?true:pcPic->getSlice(s)->getLFCrossSliceBoundaryFlag()) );
875      }
876      m_storedStartCUAddrForEncodingSlice.resize(uiNumSlices+1);
877#if REMOVE_FGS
878      pcPic->createNonDBFilterInfo(m_storedStartCUAddrForEncodingSlice, 0, &LFCrossSliceBoundaryFlag ,pcPic->getPicSym()->getNumTiles() ,bLFCrossTileBoundary);
879#else
880      pcPic->createNonDBFilterInfo(m_storedStartCUAddrForEncodingSlice, sliceGranularity, &LFCrossSliceBoundaryFlag ,pcPic->getPicSym()->getNumTiles() ,bLFCrossTileBoundary);
881#endif
882    }
883
884
885    pcSlice = pcPic->getSlice(0);
886
887    if(pcSlice->getSPS()->getUseSAO())
888    {
889      m_pcSAO->createPicSaoInfo(pcPic, uiNumSlices);
890    }
891
892#if !REMOVE_ALF
893    pcSlice = pcPic->getSlice(0);
894
895    if(pcSlice->getSPS()->getUseALF())
896    {
897      m_pcAdaptiveLoopFilter->createPicAlfInfo(pcPic, uiNumSlices);
898    }
899#endif
900    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
901    // Set entropy coder
902    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
903
904    /* write various header sets. */
905    if ( m_bSeqFirst )
906    {
907#if SVC_EXTENSION
908#if REMOVE_NAL_REF_FLAG
909      OutputNALUnit nalu(NAL_UNIT_VPS, 0, m_layerId);
910#else
911      OutputNALUnit nalu(NAL_UNIT_VPS, true, 0, m_layerId);
912#endif
913#else
914#if REMOVE_NAL_REF_FLAG
915      OutputNALUnit nalu(NAL_UNIT_VPS);
916#else
917      OutputNALUnit nalu(NAL_UNIT_VPS, true);
918#endif
919#endif
920      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
921      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
922      writeRBSPTrailingBits(nalu.m_Bitstream);
923      accessUnit.push_back(new NALUnitEBSP(nalu));
924
925#if SVC_EXTENSION
926#if REMOVE_NAL_REF_FLAG
927      nalu = NALUnit(NAL_UNIT_SPS, 0, m_layerId);
928#else
929      nalu = NALUnit(NAL_UNIT_SPS, true, 0, m_layerId);
930#endif
931#else
932#if REMOVE_NAL_REF_FLAG
933      nalu = NALUnit(NAL_UNIT_SPS);
934#else
935      nalu = NALUnit(NAL_UNIT_SPS, true);
936#endif
937#endif
938      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
939#if LTRP_IN_SPS
940      if (m_bSeqFirst)
941      {
942        pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
943        for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
944        {
945          pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
946          pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
947        }
948      }
949#endif
950#if BUFFERING_PERIOD_AND_TIMING_SEI
951      if( m_pcCfg->getPictureTimingSEIEnabled() )
952      {
953        UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
954        UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 );
955        if( pcPic->getNumCUsInFrame() % maxCU != 0 )
956        {
957          numDU ++;
958        }
959        pcSlice->getSPS()->getVuiParameters()->setNumDU( numDU );
960        pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
961      }
962      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() )
963      {
964        pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
965      }
966#endif
967      m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
968      writeRBSPTrailingBits(nalu.m_Bitstream);
969      accessUnit.push_back(new NALUnitEBSP(nalu));
970
971#if SVC_EXTENSION
972#if REMOVE_NAL_REF_FLAG
973      nalu = NALUnit(NAL_UNIT_PPS, 0, m_layerId);
974#else
975      nalu = NALUnit(NAL_UNIT_PPS, true, 0, m_layerId);
976#endif
977#else
978#if REMOVE_NAL_REF_FLAG
979      nalu = NALUnit(NAL_UNIT_PPS);
980#else
981      nalu = NALUnit(NAL_UNIT_PPS, true);
982#endif
983#endif
984      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
985      m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
986      writeRBSPTrailingBits(nalu.m_Bitstream);
987      accessUnit.push_back(new NALUnitEBSP(nalu));
988
989#if ACTIVE_PARAMETER_SETS_SEI_MESSAGE 
990      if(m_pcCfg->getActiveParameterSetsSEIEnabled())
991      {
992        SEIActiveParameterSets sei_active_parameter_sets; 
993        sei_active_parameter_sets.activeVPSId = m_pcCfg->getVPS()->getVPSId(); 
994        sei_active_parameter_sets.activeSPSIdPresentFlag = m_pcCfg->getActiveParameterSetsSEIEnabled()==2 ? 1 : 0;
995        if(sei_active_parameter_sets.activeSPSIdPresentFlag) 
996        {
997          sei_active_parameter_sets.activeSeqParamSetId = pcSlice->getSPS()->getSPSId(); 
998        }
999        sei_active_parameter_sets.activeParamSetSEIExtensionFlag = 0;
1000
1001        nalu = NALUnit(NAL_UNIT_SEI); 
1002        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1003        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_active_parameter_sets); 
1004        writeRBSPTrailingBits(nalu.m_Bitstream);
1005        accessUnit.push_back(new NALUnitEBSP(nalu));
1006      }
1007#endif
1008
1009      m_bSeqFirst = false;
1010    }
1011
1012#if BUFFERING_PERIOD_AND_TIMING_SEI
1013    if( ( m_pcCfg->getPictureTimingSEIEnabled() ) &&
1014        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
1015        ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) )
1016    {
1017      if( pcSlice->getSPS()->getVuiParameters()->getSubPicCpbParamsPresentFlag() )
1018      {
1019        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getNumDU();
1020        pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
1021        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = 0;
1022
1023        if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
1024        {
1025          pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
1026        }
1027        if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
1028        {
1029          pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
1030        }
1031        if( accumBitsDU == NULL )
1032        {
1033          accumBitsDU                                  = new UInt[ numDU ];
1034        }
1035        if( accumNalsDU == NULL )
1036        {
1037          accumNalsDU                                  = new UInt[ numDU ];
1038        }
1039      }
1040      pictureTimingSEI.m_auCpbRemovalDelay = m_totalCoded - m_lastBPSEI;
1041      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(0) + pcSlice->getPOC() - m_totalCoded;
1042    }
1043    if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
1044        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
1045        ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) )
1046    {
1047      OutputNALUnit nalu(NAL_UNIT_SEI);
1048      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1049      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1050
1051      SEIBufferingPeriod sei_buffering_period;
1052     
1053      UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
1054      sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
1055      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
1056      sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
1057      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
1058
1059      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimeScale();
1060
1061      UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
1062      uiInitialCpbRemovalDelay -= uiTmp;
1063      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getTickDivisorMinus2() + 2 );
1064      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
1065      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
1066      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
1067      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
1068
1069      sei_buffering_period.m_altCpbParamsPresentFlag              = 0;
1070      sei_buffering_period.m_sps                                  = pcSlice->getSPS();
1071
1072      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period );
1073      writeRBSPTrailingBits(nalu.m_Bitstream);
1074      accessUnit.push_back(new NALUnitEBSP(nalu));
1075
1076      m_lastBPSEI = m_totalCoded;
1077      m_cpbRemovalDelay = 0;
1078    }
1079    m_cpbRemovalDelay ++;
1080#endif
1081#if RECOVERY_POINT_SEI
1082    if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
1083    {
1084      // Recovery point SEI
1085      OutputNALUnit nalu(NAL_UNIT_SEI);
1086      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1087      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1088
1089      SEIRecoveryPoint sei_recovery_point;
1090      sei_recovery_point.m_recoveryPocCnt    = 0;
1091      sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
1092      sei_recovery_point.m_brokenLinkFlag    = false;
1093
1094      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point );
1095      writeRBSPTrailingBits(nalu.m_Bitstream);
1096      accessUnit.push_back(new NALUnitEBSP(nalu));
1097    }
1098#endif
1099    /* use the main bitstream buffer for storing the marshalled picture */
1100    m_pcEntropyCoder->setBitstream(NULL);
1101
1102    uiStartCUAddrSliceIdx = 0;
1103    uiStartCUAddrSlice    = 0; 
1104
1105    uiStartCUAddrDependentSliceIdx = 0;
1106    uiStartCUAddrDependentSlice    = 0; 
1107    uiNextCUAddr                 = 0;
1108    pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
1109
1110#if REMOVE_ALF
1111    Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
1112#else
1113    Int processingState = (pcSlice->getSPS()->getUseALF() || pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
1114#endif
1115#if !REMOVE_APS
1116    static Int iCurrAPSIdx = 0;
1117    Int iCodedAPSIdx = 0;
1118    TComSlice* pcSliceForAPS = NULL;
1119#endif
1120    bool skippedSlice=false;
1121    while (uiNextCUAddr < uiRealEndAddress) // Iterate over all slices
1122    {
1123      switch(processingState)
1124      {
1125      case ENCODE_SLICE:
1126        {
1127          pcSlice->setNextSlice       ( false );
1128          pcSlice->setNextDependentSlice( false );
1129          if (uiNextCUAddr == m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx])
1130          {
1131            pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
1132            if(uiStartCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
1133            {
1134              pcSlice->checkColRefIdx(uiStartCUAddrSliceIdx, pcPic);
1135            }
1136            pcPic->setCurrSliceIdx(uiStartCUAddrSliceIdx);
1137            m_pcSliceEncoder->setSliceIdx(uiStartCUAddrSliceIdx);
1138            assert(uiStartCUAddrSliceIdx == pcSlice->getSliceIdx());
1139            // Reconstruction slice
1140            pcSlice->setSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
1141            pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx+1 ] );
1142            // Dependent slice
1143            pcSlice->setDependentSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
1144            pcSlice->setDependentSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx+1 ] );
1145
1146            pcSlice->setNextSlice       ( true );
1147
1148            uiStartCUAddrSliceIdx++;
1149            uiStartCUAddrDependentSliceIdx++;
1150          } 
1151          else if (uiNextCUAddr == m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx])
1152          {
1153            // Dependent slice
1154            pcSlice->setDependentSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
1155            pcSlice->setDependentSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx+1 ] );
1156
1157            pcSlice->setNextDependentSlice( true );
1158
1159            uiStartCUAddrDependentSliceIdx++;
1160          }
1161
1162          pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
1163          pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
1164          UInt uiDummyStartCUAddr;
1165          UInt uiDummyBoundingCUAddr;
1166          m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
1167
1168          uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurEndCUAddr()-1) % pcPic->getNumPartInCU();
1169          uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurEndCUAddr()-1) / pcPic->getNumPartInCU();
1170          uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1171          uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1172          uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1173          uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1174          while(uiPosX>=uiWidth||uiPosY>=uiHeight)
1175          {
1176            uiInternalAddress--;
1177            uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1178            uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1179          }
1180          uiInternalAddress++;
1181          if(uiInternalAddress==pcPic->getNumPartInCU())
1182          {
1183            uiInternalAddress = 0;
1184            uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1185          }
1186          UInt uiEndAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
1187          if(uiEndAddress<=pcSlice->getDependentSliceCurStartCUAddr()) {
1188            UInt uiBoundingAddrSlice, uiBoundingAddrDependentSlice;
1189            uiBoundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx];         
1190            uiBoundingAddrDependentSlice = m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx];         
1191            uiNextCUAddr               = min(uiBoundingAddrSlice, uiBoundingAddrDependentSlice);
1192            if(pcSlice->isNextSlice())
1193            {
1194              skippedSlice=true;
1195            }
1196            continue;
1197          }
1198          if(skippedSlice) 
1199          {
1200            pcSlice->setNextSlice       ( true );
1201            pcSlice->setNextDependentSlice( false );
1202          }
1203          skippedSlice=false;
1204          pcSlice->allocSubstreamSizes( iNumSubstreams );
1205          for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1206          {
1207            pcSubstreamsOut[ui].clear();
1208          }
1209
1210          m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1211          m_pcEntropyCoder->resetEntropy      ();
1212          /* start slice NALunit */
1213#if SVC_EXTENSION
1214#if REMOVE_NAL_REF_FLAG
1215          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId );
1216#else
1217          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->isReferenced(), pcSlice->getTLayer(), m_layerId );
1218#endif
1219#else
1220#if REMOVE_NAL_REF_FLAG
1221          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
1222#else
1223          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->isReferenced(), pcSlice->getTLayer() );
1224#endif
1225#endif
1226          Bool bDependentSlice = (!pcSlice->isNextSlice());
1227          if (!bDependentSlice)
1228          {
1229            uiOneBitstreamPerSliceLength = 0; // start of a new slice
1230          }
1231          m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1232          m_pcEntropyCoder->encodeSliceHeader(pcSlice);
1233
1234          // is it needed?
1235          {
1236            if (!bDependentSlice)
1237            {
1238              pcBitstreamRedirect->writeAlignOne();
1239            }
1240            else
1241            {
1242              // We've not completed our slice header info yet, do the alignment later.
1243            }
1244            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1245            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1246            m_pcEntropyCoder->resetEntropy    ();
1247            for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1248            {
1249              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1250              m_pcEntropyCoder->resetEntropy    ();
1251            }
1252          }
1253
1254          if(pcSlice->isNextSlice())
1255          {
1256            // set entropy coder for writing
1257            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1258            {
1259              for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1260              {
1261                m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1262                m_pcEntropyCoder->resetEntropy    ();
1263              }
1264              pcSbacCoders[0].load(m_pcSbacCoder);
1265              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice );  //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below)
1266            }
1267            m_pcEntropyCoder->resetEntropy    ();
1268            // File writing
1269            if (!bDependentSlice)
1270            {
1271              m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
1272            }
1273            else
1274            {
1275              m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1276            }
1277            // for now, override the TILES_DECODER setting in order to write substreams.
1278            m_pcEntropyCoder->setBitstream    ( &pcSubstreamsOut[0] );
1279
1280          }
1281          pcSlice->setFinalized(true);
1282
1283          m_pcSbacCoder->load( &pcSbacCoders[0] );
1284
1285          pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
1286          if (!bDependentSlice)
1287          {
1288            pcSlice->setTileLocationCount ( 0 );
1289            m_pcSliceEncoder->encodeSlice(pcPic, pcBitstreamRedirect, pcSubstreamsOut); // redirect is only used for CAVLC tile position info.
1290          }
1291          else
1292          {
1293            m_pcSliceEncoder->encodeSlice(pcPic, &nalu.m_Bitstream, pcSubstreamsOut); // nalu.m_Bitstream is only used for CAVLC tile position info.
1294          }
1295
1296          {
1297            // Construct the final bitstream by flushing and concatenating substreams.
1298            // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
1299            UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes();
1300            UInt uiTotalCodedSize = 0; // for padding calcs.
1301            UInt uiNumSubstreamsPerTile = iNumSubstreams;
1302            if (iNumSubstreams > 1)
1303            {
1304              uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
1305            }
1306            for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1307            {
1308              // Flush all substreams -- this includes empty ones.
1309              // Terminating bit and flush.
1310              m_pcEntropyCoder->setEntropyCoder   ( &pcSbacCoders[ui], pcSlice );
1311              m_pcEntropyCoder->setBitstream      (  &pcSubstreamsOut[ui] );
1312              m_pcEntropyCoder->encodeTerminatingBit( 1 );
1313              m_pcEntropyCoder->encodeSliceFinish();
1314
1315#if BYTE_ALIGNMENT 
1316              pcSubstreamsOut[ui].writeByteAlignment();   // Byte-alignment in slice_data() at end of sub-stream
1317#else
1318              //!KS: The following writes trailing_bits. Should use proper function call to writeRBSPTrailingBits()
1319              pcSubstreamsOut[ui].write( 1, 1 ); // stop bit.
1320              pcSubstreamsOut[ui].writeAlignZero();
1321#endif
1322              // Byte alignment is necessary between tiles when tiles are independent.
1323              uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
1324
1325              {
1326                Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)
1327                  && ((ui+1)%uiNumSubstreamsPerTile == 0);
1328                if (bNextSubstreamInNewTile)
1329                {
1330                  // byte align.
1331                  while (uiTotalCodedSize&0x7)
1332                  {
1333                    pcSubstreamsOut[ui].write(0, 1);
1334                    uiTotalCodedSize++;
1335                  }
1336                }
1337                Bool bRecordOffsetNext = bNextSubstreamInNewTile;
1338                if (bRecordOffsetNext)
1339                  pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
1340              }
1341              if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
1342                puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits();
1343            }
1344
1345            // Complete the slice header info.
1346            m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1347            m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1348            m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
1349
1350            // Substreams...
1351            TComOutputBitstream *pcOut = pcBitstreamRedirect;
1352#if !BYTE_ALIGNMENT
1353            // xWriteTileLocation will perform byte-alignment...
1354            {
1355              if (bDependentSlice)
1356              {
1357                // In these cases, padding is necessary here.
1358                pcOut = &nalu.m_Bitstream;
1359                pcOut->writeAlignOne();
1360              }
1361            }
1362#endif
1363          Int offs = 0;
1364          Int nss = pcSlice->getPPS()->getNumSubstreams();
1365#if TILES_WPP_ENTROPYSLICES_FLAGS
1366          if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
1367#else
1368          if (pcSlice->getPPS()->getTilesOrEntropyCodingSyncIdc() == 2)
1369#endif
1370          {
1371            // 1st line present for WPP.
1372#if DEPENDENT_SLICES
1373            offs = pcSlice->getDependentSliceCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
1374#else
1375            offs = pcSlice->getSliceCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
1376#endif
1377            nss  = pcSlice->getNumEntryPointOffsets()+1;
1378          }
1379          for ( UInt ui = 0 ; ui < nss; ui++ )
1380          {
1381            pcOut->addSubstream(&pcSubstreamsOut[ui+offs]);
1382            }
1383          }
1384
1385          UInt uiBoundingAddrSlice, uiBoundingAddrDependentSlice;
1386          uiBoundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx];         
1387          uiBoundingAddrDependentSlice = m_storedStartCUAddrForEncodingDependentSlice[uiStartCUAddrDependentSliceIdx];         
1388          uiNextCUAddr               = min(uiBoundingAddrSlice, uiBoundingAddrDependentSlice);
1389          // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
1390          // If current NALU is the last NALU of slice and a NALU was buffered, then (a) Write current NALU (b) Update an write buffered NALU at approproate location in NALU list.
1391          Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
1392          xWriteTileLocationToSliceHeader(nalu, pcBitstreamRedirect, pcSlice);
1393          accessUnit.push_back(new NALUnitEBSP(nalu));
1394          bNALUAlignedWrittenToList = true; 
1395          uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
1396
1397          if (!bNALUAlignedWrittenToList)
1398          {
1399            {
1400              nalu.m_Bitstream.writeAlignZero();
1401            }
1402            accessUnit.push_back(new NALUnitEBSP(nalu));
1403            uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001
1404          }
1405
1406#if BUFFERING_PERIOD_AND_TIMING_SEI
1407          if( ( m_pcCfg->getPictureTimingSEIEnabled() ) &&
1408              ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
1409              ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) &&
1410              ( pcSlice->getSPS()->getVuiParameters()->getSubPicCpbParamsPresentFlag() ) )
1411          {
1412            UInt numRBSPBytes = 0;
1413            for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
1414            {
1415              UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
1416              if ((*it)->m_nalUnitType != NAL_UNIT_SEI)
1417              {
1418                numRBSPBytes += numRBSPBytes_nal;
1419              }
1420            }
1421            accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
1422            accumNalsDU[ pcSlice->getSliceIdx() ] = (UInt)accessUnit.size();
1423          }
1424#endif
1425          processingState = ENCODE_SLICE;
1426          }
1427          break;
1428        case EXECUTE_INLOOPFILTER:
1429          {
1430#if !REMOVE_APS
1431            TComAPS cAPS;
1432            allocAPS(&cAPS, pcSlice->getSPS());
1433#endif
1434            // set entropy coder for RD
1435            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1436            if ( pcSlice->getSPS()->getUseSAO() )
1437            {
1438              m_pcEntropyCoder->resetEntropy();
1439              m_pcEntropyCoder->setBitstream( m_pcBitCounter );
1440              m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcEncTop->getRDGoOnSbacCoder());
1441#if REMOVE_APS
1442              SAOParam& cSaoParam = *pcSlice->getPic()->getPicSym()->getSaoParam();
1443#else
1444              SAOParam& cSaoParam = *(cAPS.getSaoParam());
1445#endif
1446
1447#if SAO_CHROMA_LAMBDA
1448#if SAO_ENCODING_CHOICE
1449              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), pcPic->getSlice(0)->getDepth());
1450#else
1451              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma());
1452#endif
1453#else
1454#if ALF_CHROMA_LAMBDA
1455              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma());
1456#else
1457              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambda());
1458#endif
1459#endif
1460              m_pcSAO->endSaoEnc();
1461#if !REMOVE_ALF
1462              m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
1463#else
1464              m_pcSAO->PCMLFDisableProcess(pcPic);
1465#endif
1466            }
1467#if SAO_RDO
1468            m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
1469#endif
1470            // adaptive loop filter
1471#if !REMOVE_ALF
1472            if ( pcSlice->getSPS()->getUseALF())
1473            {
1474#if ALF_CHROMA_LAMBDA
1475              m_pcAdaptiveLoopFilter->ALFProcess(cAPS.getAlfParam(), pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma() );
1476#else
1477#if SAO_CHROMA_LAMBDA
1478              m_pcAdaptiveLoopFilter->ALFProcess(cAPS.getAlfParam(), pcPic->getSlice(0)->getLambdaLuma());
1479#else
1480              m_pcAdaptiveLoopFilter->ALFProcess(cAPS.getAlfParam(), pcPic->getSlice(0)->getLambda());
1481#endif
1482#endif
1483              m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
1484            }
1485#endif
1486#if !REMOVE_APS
1487            iCodedAPSIdx = iCurrAPSIdx;
1488            pcSliceForAPS = pcSlice;
1489
1490            assignNewAPS(cAPS, iCodedAPSIdx, vAPS, pcSliceForAPS);
1491            iCurrAPSIdx = (iCurrAPSIdx +1)%MAX_NUM_SUPPORTED_APS;
1492#endif
1493            processingState = ENCODE_APS;
1494
1495            //set APS link to the slices
1496            for(Int s=0; s< uiNumSlices; s++)
1497            {
1498#if !REMOVE_ALF
1499              if (pcSlice->getSPS()->getUseALF())
1500              {
1501                for(Int compIdx =0; compIdx< 3; compIdx++)
1502                {
1503                  pcPic->getSlice(s)->setAlfEnabledFlag( cAPS.getAlfEnabled(compIdx), compIdx);
1504                }
1505              }
1506#endif
1507              if (pcSlice->getSPS()->getUseSAO())
1508              {
1509#if REMOVE_APS
1510                pcPic->getSlice(s)->setSaoEnabledFlag((pcSlice->getPic()->getPicSym()->getSaoParam()->bSaoFlag[0]==1)?true:false);
1511#else
1512                pcPic->getSlice(s)->setSaoEnabledFlag((cAPS.getSaoParam()->bSaoFlag[0]==1)?true:false);
1513#endif
1514              }
1515#if !REMOVE_APS
1516              pcPic->getSlice(s)->setAPS(&(vAPS[iCodedAPSIdx]));
1517              pcPic->getSlice(s)->setAPSId(iCodedAPSIdx);
1518#endif
1519            }
1520
1521            /* The destructor of cAPS that is about to be called will free
1522             * the resource held by cAPS, which will cause problems since it
1523             * has been aliased elsewhere.
1524             *   Hint: never ever write an assignment operator that copies
1525             *         pointers without the use of smart pointers.
1526             * The following will clear the saved state before the destructor.
1527             */
1528#if !REMOVE_APS
1529            cAPS = TComAPS();
1530#endif
1531          }
1532          break;
1533        case ENCODE_APS:
1534          {
1535#if !REMOVE_APS
1536            OutputNALUnit nalu(NAL_UNIT_APS, true);
1537            encodeAPS(&(vAPS[iCodedAPSIdx]), nalu.m_Bitstream, pcSliceForAPS);
1538            accessUnit.push_back(new NALUnitEBSP(nalu));
1539#endif
1540            processingState = ENCODE_SLICE;
1541          }
1542          break;
1543        default:
1544          {
1545            printf("Not a supported encoding state\n");
1546            assert(0);
1547            exit(-1);
1548          }
1549        }
1550      } // end iteration over slices
1551
1552#if REMOVE_ALF
1553      if(pcSlice->getSPS()->getUseSAO())
1554#else
1555      if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
1556#endif
1557      {
1558        if(pcSlice->getSPS()->getUseSAO())
1559        {
1560          m_pcSAO->destroyPicSaoInfo();
1561        }
1562#if !REMOVE_ALF
1563        if(pcSlice->getSPS()->getUseALF())
1564        {
1565          m_pcAdaptiveLoopFilter->destroyPicAlfInfo();
1566        }
1567#endif
1568        pcPic->destroyNonDBFilterInfo();
1569      }
1570
1571      pcPic->compressMotion(); 
1572     
1573      //-- For time output for each slice
1574      Double dEncTime = (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
1575
1576      const char* digestStr = NULL;
1577      if (m_pcCfg->getDecodedPictureHashSEIEnabled())
1578      {
1579        /* calculate MD5sum for entire reconstructed picture */
1580        SEIDecodedPictureHash sei_recon_picture_digest;
1581        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
1582        {
1583          sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
1584          calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
1585          digestStr = digestToString(sei_recon_picture_digest.digest, 16);
1586        }
1587        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
1588        {
1589          sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
1590          calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
1591          digestStr = digestToString(sei_recon_picture_digest.digest, 2);
1592        }
1593        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
1594        {
1595          sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
1596          calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
1597          digestStr = digestToString(sei_recon_picture_digest.digest, 4);
1598        }
1599#if SVC_EXTENSION
1600#if REMOVE_NAL_REF_FLAG
1601        OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer(), m_layerId);
1602#else
1603        OutputNALUnit nalu(NAL_UNIT_SEI, false, pcSlice->getTLayer(), m_layerId);
1604#endif
1605#else
1606#if REMOVE_NAL_REF_FLAG
1607        OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer());
1608#else
1609        OutputNALUnit nalu(NAL_UNIT_SEI, false, pcSlice->getTLayer());
1610#endif
1611#endif
1612
1613        /* write the SEI messages */
1614        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1615        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest);
1616        writeRBSPTrailingBits(nalu.m_Bitstream);
1617
1618        /* insert the SEI message NALUnit before any Slice NALUnits */
1619        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
1620        accessUnit.insert(it, new NALUnitEBSP(nalu));
1621      }
1622
1623      xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime );
1624
1625      if (digestStr)
1626      {
1627        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
1628        {
1629          printf(" [MD5:%s]", digestStr);
1630        }
1631        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
1632        {
1633          printf(" [CRC:%s]", digestStr);
1634        }
1635        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
1636        {
1637          printf(" [Checksum:%s]", digestStr);
1638        }
1639      }
1640      if(m_pcCfg->getUseRateCtrl())
1641      {
1642        unsigned  frameBits = m_vRVM_RP[m_vRVM_RP.size()-1];
1643        m_pcRateCtrl->updataRCFrameStatus((Int)frameBits, pcSlice->getSliceType());
1644      }
1645#if BUFFERING_PERIOD_AND_TIMING_SEI
1646      if( ( m_pcCfg->getPictureTimingSEIEnabled() ) &&
1647          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
1648          ( ( pcSlice->getSPS()->getVuiParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getVuiParameters()->getVclHrdParametersPresentFlag() ) ) )
1649      {
1650        OutputNALUnit nalu(NAL_UNIT_SEI, pcSlice->getTLayer());
1651        TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
1652
1653        if( vui->getSubPicCpbParamsPresentFlag() )
1654        {
1655          Int i;
1656          UInt64 ui64Tmp;
1657          UInt uiTmp, uiPrev, uiCurr;
1658
1659          uiPrev = 0;
1660          for( i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
1661          {
1662            pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
1663            ui64Tmp = ( ( ( accumBitsDU[ pictureTimingSEI.m_numDecodingUnitsMinus1 ] - accumBitsDU[ i ] ) * ( vui->getTimeScale() / vui->getNumUnitsInTick() ) * ( vui->getTickDivisorMinus2() + 2 ) ) 
1664                        / ( m_pcCfg->getTargetBitrate() << 10 ) );
1665
1666            uiTmp = (UInt)ui64Tmp;
1667            if( uiTmp >= ( vui->getTickDivisorMinus2() + 2 ) )      uiCurr = 0;
1668            else                                                     uiCurr = ( vui->getTickDivisorMinus2() + 2 ) - uiTmp;
1669
1670            if( i == pictureTimingSEI.m_numDecodingUnitsMinus1 ) uiCurr = vui->getTickDivisorMinus2() + 2;
1671            if( uiCurr <= uiPrev )                                   uiCurr = uiPrev + 1;
1672
1673            pictureTimingSEI.m_duCpbRemovalDelayMinus1[ i ]              = (uiCurr - uiPrev) - 1;
1674            uiPrev = uiCurr;
1675          }
1676        }
1677        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1678        pictureTimingSEI.m_sps = pcSlice->getSPS();
1679        m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI);
1680        writeRBSPTrailingBits(nalu.m_Bitstream);
1681
1682        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
1683        accessUnit.insert(it, new NALUnitEBSP(nalu));
1684      }
1685#endif
1686#if FIXED_ROUNDING_FRAME_MEMORY
1687      /* TODO: this should happen after copyToPic(pcPicYuvRecOut) */
1688      pcPic->getPicYuvRec()->xFixedRoundingPic();
1689#endif
1690      pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
1691
1692      pcPic->setReconMark   ( true );
1693      m_bFirst = false;
1694      m_iNumPicCoded++;
1695#if BUFFERING_PERIOD_AND_TIMING_SEI
1696      m_totalCoded ++;
1697#endif
1698      /* logging: insert a newline at end of picture period */
1699      printf("\n");
1700      fflush(stdout);
1701
1702      delete[] pcSubstreamsOut;
1703  }
1704  if(m_pcCfg->getUseRateCtrl())
1705  {
1706    m_pcRateCtrl->updateRCGOPStatus();
1707  }
1708  delete pcBitstreamRedirect;
1709
1710#if BUFFERING_PERIOD_AND_TIMING_SEI
1711  if( accumBitsDU != NULL) delete accumBitsDU;
1712  if( accumNalsDU != NULL) delete accumNalsDU;
1713#endif
1714
1715#if SVC_EXTENSION
1716  assert ( m_iNumPicCoded <= 1 );
1717#else
1718  assert ( m_iNumPicCoded == iNumPicRcvd );
1719#endif
1720}
1721
1722#if !REMOVE_APS
1723/** Memory allocation for APS
1724  * \param [out] pAPS APS pointer
1725  * \param [in] pSPS SPS pointer
1726  */
1727Void TEncGOP::allocAPS (TComAPS* pAPS, TComSPS* pSPS)
1728{
1729  if(pSPS->getUseSAO())
1730  {
1731    pAPS->createSaoParam();
1732    m_pcSAO->allocSaoParam(pAPS->getSaoParam());
1733  }
1734#if !REMOVE_ALF
1735  pAPS->createAlfParam();
1736#endif
1737}
1738
1739/** Memory deallocation for APS
1740  * \param [out] pAPS APS pointer
1741  * \param [in] pSPS SPS pointer
1742  */
1743Void TEncGOP::freeAPS (TComAPS* pAPS, TComSPS* pSPS)
1744{
1745  if(pSPS->getUseSAO())
1746  {
1747    if(pAPS->getSaoParam() != NULL)
1748    {
1749      m_pcSAO->freeSaoParam(pAPS->getSaoParam());
1750      pAPS->destroySaoParam();
1751
1752    }
1753  }
1754#if !REMOVE_ALF
1755  pAPS->destroyAlfParam();
1756#endif
1757}
1758
1759/** Assign APS object into APS container according to APS ID
1760  * \param [in] cAPS APS object
1761  * \param [in] apsID APS ID
1762  * \param [in,out] vAPS APS container
1763  * \param [in] pcSlice pointer to slice
1764  */
1765Void TEncGOP::assignNewAPS(TComAPS& cAPS, Int apsID, std::vector<TComAPS>& vAPS, TComSlice* pcSlice)
1766{
1767
1768  cAPS.setAPSID(apsID);
1769
1770  //assign new APS into APS container
1771  Int apsBufSize= (Int)vAPS.size();
1772
1773  if(apsID >= apsBufSize)
1774  {
1775    vAPS.resize(apsID +1);
1776  }
1777
1778  freeAPS(&(vAPS[apsID]), pcSlice->getSPS());
1779  vAPS[apsID] = cAPS;
1780}
1781
1782/** encode APS syntax elements
1783  * \param [in] pcAPS APS pointer
1784  * \param [in, out] APSbs bitstream
1785  * \param [in] pointer to slice (just used for entropy coder initialization)
1786  */
1787Void TEncGOP::encodeAPS(TComAPS* pcAPS, TComOutputBitstream& APSbs, TComSlice* pcSlice)
1788{
1789  m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice);
1790  m_pcEntropyCoder->resetEntropy      ();
1791  m_pcEntropyCoder->setBitstream(&APSbs);
1792
1793  m_pcEntropyCoder->encodeAPSInitInfo(pcAPS);
1794#if !REMOVE_ALF
1795  for(Int compIdx=0; compIdx < 3; compIdx++)
1796  {
1797    m_pcEntropyCoder->encodeAlfParam( (pcAPS->getAlfParam())[compIdx]);
1798  }
1799#endif
1800  m_pcEntropyCoder->encodeApsExtensionFlag();
1801  //neither SAO and ALF is enabled
1802  writeRBSPTrailingBits(APSbs);
1803}
1804#endif
1805
1806#if !SVC_EXTENSION
1807Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded)
1808{
1809  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
1810 
1811   
1812  //--CFG_KDY
1813  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
1814  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
1815  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
1816  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
1817 
1818  //-- all
1819  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
1820  m_gcAnalyzeAll.printOut('a');
1821 
1822  printf( "\n\nI Slices--------------------------------------------------------\n" );
1823  m_gcAnalyzeI.printOut('i');
1824 
1825  printf( "\n\nP Slices--------------------------------------------------------\n" );
1826  m_gcAnalyzeP.printOut('p');
1827 
1828  printf( "\n\nB Slices--------------------------------------------------------\n" );
1829  m_gcAnalyzeB.printOut('b');
1830 
1831#if _SUMMARY_OUT_
1832  m_gcAnalyzeAll.printSummaryOut();
1833#endif
1834#if _SUMMARY_PIC_
1835  m_gcAnalyzeI.printSummary('I');
1836  m_gcAnalyzeP.printSummary('P');
1837  m_gcAnalyzeB.printSummary('B');
1838#endif
1839
1840  printf("\nRVM: %.3lf\n" , xCalculateRVM());
1841}
1842#endif
1843
1844Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
1845{
1846  TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
1847  Bool bCalcDist = false;
1848  m_pcLoopFilter->setCfg(pcSlice->getPPS()->getDeblockingFilterControlPresentFlag(), pcSlice->getDeblockingFilterDisable(), m_pcCfg->getLoopFilterBetaOffset(), m_pcCfg->getLoopFilterTcOffset(), m_pcCfg->getLFCrossTileBoundaryFlag());
1849  m_pcLoopFilter->loopFilterPic( pcPic );
1850 
1851  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
1852  m_pcEntropyCoder->resetEntropy    ();
1853  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
1854  pcSlice = pcPic->getSlice(0);
1855#if REMOVE_ALF
1856  if(pcSlice->getSPS()->getUseSAO())
1857#else
1858  if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
1859#endif
1860  {
1861    std::vector<Bool> LFCrossSliceBoundaryFlag(1, true);
1862    std::vector<Int>  sliceStartAddress;
1863    sliceStartAddress.push_back(0);
1864    sliceStartAddress.push_back(pcPic->getNumCUsInFrame()* pcPic->getNumPartInCU());
1865    pcPic->createNonDBFilterInfo(sliceStartAddress, 0, &LFCrossSliceBoundaryFlag);
1866  }
1867 
1868#if !REMOVE_ALF
1869  // Adaptive Loop filter
1870  if( pcSlice->getSPS()->getUseALF() )
1871  {
1872    m_pcAdaptiveLoopFilter->createPicAlfInfo(pcPic);
1873
1874    ALFParam* alfPicParam[3];
1875    for(Int compIdx=0; compIdx < 3; compIdx++)
1876    {
1877      alfPicParam[compIdx] = new ALFParam(compIdx);
1878    }
1879
1880#if ALF_CHROMA_LAMBDA
1881    m_pcAdaptiveLoopFilter->ALFProcess(alfPicParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma() );
1882#else
1883#if SAO_CHROMA_LAMBDA
1884    m_pcAdaptiveLoopFilter->ALFProcess(alfPicParam, pcPic->getSlice(0)->getLambdaLuma());
1885#else
1886    m_pcAdaptiveLoopFilter->ALFProcess(alfPicParam, pcPic->getSlice(0)->getLambda());
1887#endif
1888#endif
1889    for(Int compIdx=0; compIdx < 3; compIdx++)
1890    {
1891      delete alfPicParam[compIdx]; alfPicParam[compIdx] = NULL;
1892    }
1893    m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
1894    m_pcAdaptiveLoopFilter->destroyPicAlfInfo();
1895  }
1896#endif
1897#if REMOVE_ALF
1898  if( pcSlice->getSPS()->getUseSAO())
1899#else
1900  if( pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
1901#endif
1902  {
1903    pcPic->destroyNonDBFilterInfo();
1904  }
1905 
1906  m_pcEntropyCoder->resetEntropy    ();
1907  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
1908 
1909  if (!bCalcDist)
1910    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
1911}
1912
1913// ====================================================================================================================
1914// Protected member functions
1915// ====================================================================================================================
1916
1917Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut )
1918{
1919  assert( iNumPicRcvd > 0 );
1920  //  Exception for the first frame
1921  if ( iPOCLast == 0 )
1922  {
1923    m_iGopSize    = 1;
1924  }
1925  else
1926    m_iGopSize    = m_pcCfg->getGOPSize();
1927 
1928  assert (m_iGopSize > 0); 
1929
1930  return;
1931}
1932
1933Void TEncGOP::xGetBuffer( TComList<TComPic*>&       rcListPic,
1934                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
1935                         Int                       iNumPicRcvd,
1936                         Int                       iTimeOffset,
1937                         TComPic*&                 rpcPic,
1938                         TComPicYuv*&              rpcPicYuvRecOut,
1939                         UInt                      uiPOCCurr )
1940{
1941  Int i;
1942  //  Rec. output
1943  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
1944  for ( i = 0; i < iNumPicRcvd - iTimeOffset + 1; i++ )
1945  {
1946    iterPicYuvRec--;
1947  }
1948 
1949  rpcPicYuvRecOut = *(iterPicYuvRec);
1950 
1951  //  Current pic.
1952  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
1953  while (iterPic != rcListPic.end())
1954  {
1955    rpcPic = *(iterPic);
1956    rpcPic->setCurrSliceIdx(0);
1957    if (rpcPic->getPOC() == (Int)uiPOCCurr)
1958    {
1959      break;
1960    }
1961    iterPic++;
1962  }
1963 
1964  assert (rpcPic->getPOC() == (Int)uiPOCCurr);
1965 
1966  return;
1967}
1968
1969UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
1970{
1971  Int     x, y;
1972  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
1973  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
1974#if IBDI_DISTORTION
1975  Int  iShift = g_uiBitIncrement;
1976  Int  iOffset = 1<<(g_uiBitIncrement-1);
1977#else
1978  UInt  uiShift = g_uiBitIncrement<<1;
1979#endif
1980  Int   iTemp;
1981 
1982  Int   iStride = pcPic0->getStride();
1983  Int   iWidth  = pcPic0->getWidth();
1984  Int   iHeight = pcPic0->getHeight();
1985 
1986  UInt64  uiTotalDiff = 0;
1987 
1988  for( y = 0; y < iHeight; y++ )
1989  {
1990    for( x = 0; x < iWidth; x++ )
1991    {
1992#if IBDI_DISTORTION
1993      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
1994#else
1995      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
1996#endif
1997    }
1998    pSrc0 += iStride;
1999    pSrc1 += iStride;
2000  }
2001 
2002  iHeight >>= 1;
2003  iWidth  >>= 1;
2004  iStride >>= 1;
2005 
2006  pSrc0  = pcPic0->getCbAddr();
2007  pSrc1  = pcPic1->getCbAddr();
2008 
2009  for( y = 0; y < iHeight; y++ )
2010  {
2011    for( x = 0; x < iWidth; x++ )
2012    {
2013#if IBDI_DISTORTION
2014      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
2015#else
2016      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2017#endif
2018    }
2019    pSrc0 += iStride;
2020    pSrc1 += iStride;
2021  }
2022 
2023  pSrc0  = pcPic0->getCrAddr();
2024  pSrc1  = pcPic1->getCrAddr();
2025 
2026  for( y = 0; y < iHeight; y++ )
2027  {
2028    for( x = 0; x < iWidth; x++ )
2029    {
2030#if IBDI_DISTORTION
2031      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
2032#else
2033      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2034#endif
2035    }
2036    pSrc0 += iStride;
2037    pSrc1 += iStride;
2038  }
2039 
2040  return uiTotalDiff;
2041}
2042
2043#if VERBOSE_RATE
2044static const char* nalUnitTypeToString(NalUnitType type)
2045{
2046  switch (type)
2047  {
2048#if NAL_UNIT_TYPES_J1003_D7
2049    case NAL_UNIT_CODED_SLICE_TRAIL_R: return "TRAIL_R";
2050    case NAL_UNIT_CODED_SLICE_TRAIL_N: return "TRAIL_N";
2051    case NAL_UNIT_CODED_SLICE_TLA: return "TLA";
2052    case NAL_UNIT_CODED_SLICE_TSA_N: return "TSA_N";
2053    case NAL_UNIT_CODED_SLICE_STSA_R: return "STSA_R";
2054    case NAL_UNIT_CODED_SLICE_STSA_N: return "STSA_N";
2055    case NAL_UNIT_CODED_SLICE_BLA: return "BLA";
2056    case NAL_UNIT_CODED_SLICE_BLANT: return "BLANT";
2057    case NAL_UNIT_CODED_SLICE_BLA_N_LP: return "BLA_N_LP";
2058    case NAL_UNIT_CODED_SLICE_IDR: return "IDR";
2059    case NAL_UNIT_CODED_SLICE_IDR_N_LP: return "IDR_N_LP";
2060    case NAL_UNIT_CODED_SLICE_CRA: return "CRA";
2061    case NAL_UNIT_CODED_SLICE_DLP: return "DLP";
2062    case NAL_UNIT_CODED_SLICE_TFD: return "TFD";
2063#else
2064    case NAL_UNIT_CODED_SLICE: return "SLICE";
2065    case NAL_UNIT_CODED_SLICE_TFD: return "TFD";
2066    case NAL_UNIT_CODED_SLICE_TLA: return "TLA";
2067    case NAL_UNIT_CODED_SLICE_CRA: return "CRA";
2068    case NAL_UNIT_CODED_SLICE_CRANT: return "CRANT";
2069    case NAL_UNIT_CODED_SLICE_BLA: return "BLA";
2070    case NAL_UNIT_CODED_SLICE_BLANT: return "BLANT";
2071    case NAL_UNIT_CODED_SLICE_IDR: return "IDR";
2072#endif
2073    case NAL_UNIT_VPS: return "VPS";
2074    case NAL_UNIT_SPS: return "SPS";
2075    case NAL_UNIT_PPS: return "PPS";
2076#if NAL_UNIT_TYPES_J1003_D7
2077    case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
2078    case NAL_UNIT_EOS: return "EOS";
2079    case NAL_UNIT_EOB: return "EOB";
2080    case NAL_UNIT_FILLER_DATA: return "FILLER";
2081    case NAL_UNIT_SEI: return "SEI";
2082#else
2083    case NAL_UNIT_APS: return "APS";
2084    case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
2085    case NAL_UNIT_FILLER_DATA: return "FILLER";
2086    case NAL_UNIT_SEI: return "SEI";
2087#endif
2088    default: return "UNK";
2089  }
2090}
2091#endif
2092
2093Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime )
2094{
2095  Int     x, y;
2096  UInt64 uiSSDY  = 0;
2097  UInt64 uiSSDU  = 0;
2098  UInt64 uiSSDV  = 0;
2099 
2100  Double  dYPSNR  = 0.0;
2101  Double  dUPSNR  = 0.0;
2102  Double  dVPSNR  = 0.0;
2103 
2104  //===== calculate PSNR =====
2105  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
2106  Pel*  pRec    = pcPicD->getLumaAddr();
2107  Int   iStride = pcPicD->getStride();
2108 
2109  Int   iWidth;
2110  Int   iHeight;
2111 
2112  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
2113  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
2114 
2115  Int   iSize   = iWidth*iHeight;
2116 
2117  for( y = 0; y < iHeight; y++ )
2118  {
2119    for( x = 0; x < iWidth; x++ )
2120    {
2121      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2122      uiSSDY   += iDiff * iDiff;
2123    }
2124    pOrg += iStride;
2125    pRec += iStride;
2126  }
2127 
2128  iHeight >>= 1;
2129  iWidth  >>= 1;
2130  iStride >>= 1;
2131  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
2132  pRec  = pcPicD->getCbAddr();
2133 
2134  for( y = 0; y < iHeight; y++ )
2135  {
2136    for( x = 0; x < iWidth; x++ )
2137    {
2138      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2139      uiSSDU   += iDiff * iDiff;
2140    }
2141    pOrg += iStride;
2142    pRec += iStride;
2143  }
2144 
2145  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
2146  pRec  = pcPicD->getCrAddr();
2147 
2148  for( y = 0; y < iHeight; y++ )
2149  {
2150    for( x = 0; x < iWidth; x++ )
2151    {
2152      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2153      uiSSDV   += iDiff * iDiff;
2154    }
2155    pOrg += iStride;
2156    pRec += iStride;
2157  }
2158 
2159  unsigned int maxval = 255 * (1<<(g_uiBitDepth + g_uiBitIncrement -8));
2160  Double fRefValueY = (double) maxval * maxval * iSize;
2161  Double fRefValueC = fRefValueY / 4.0;
2162  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
2163  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
2164  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
2165
2166  /* calculate the size of the access unit, excluding:
2167   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
2168   *  - SEI NAL units
2169   */
2170  unsigned numRBSPBytes = 0;
2171  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2172  {
2173    unsigned numRBSPBytes_nal = unsigned((*it)->m_nalUnitData.str().size());
2174#if VERBOSE_RATE
2175    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
2176#endif
2177    if ((*it)->m_nalUnitType != NAL_UNIT_SEI)
2178      numRBSPBytes += numRBSPBytes_nal;
2179  }
2180
2181  unsigned uibits = numRBSPBytes * 8;
2182  m_vRVM_RP.push_back( uibits );
2183
2184  //===== add PSNR =====
2185#if SVC_EXTENSION
2186  m_gcAnalyzeAll[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2187  TComSlice*  pcSlice = pcPic->getSlice(0);
2188  if (pcSlice->isIntra())
2189  {
2190    m_gcAnalyzeI[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2191  }
2192  if (pcSlice->isInterP())
2193  {
2194    m_gcAnalyzeP[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2195  }
2196  if (pcSlice->isInterB())
2197  {
2198    m_gcAnalyzeB[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2199  }
2200#else
2201  m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2202  TComSlice*  pcSlice = pcPic->getSlice(0);
2203  if (pcSlice->isIntra())
2204  {
2205    m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2206  }
2207  if (pcSlice->isInterP())
2208  {
2209    m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2210  }
2211  if (pcSlice->isInterB())
2212  {
2213    m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2214  }
2215#endif
2216
2217  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
2218  if (!pcSlice->isReferenced()) c += 32;
2219
2220#if SVC_EXTENSION
2221#if ADAPTIVE_QP_SELECTION
2222  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
2223         pcSlice->getPOC(),
2224         pcSlice->getLayerId(),
2225         pcSlice->getTLayer(),
2226         c,
2227         pcSlice->getSliceQpBase(),
2228         pcSlice->getSliceQp(),
2229         uibits );
2230#else
2231  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
2232         pcSlice->getPOC()-pcSlice->getLastIDR(),
2233         pcSlice->getLayerId(),
2234         pcSlice->getTLayer(),
2235         c,
2236         pcSlice->getSliceQp(),
2237         uibits );
2238#endif
2239#else
2240#if ADAPTIVE_QP_SELECTION
2241  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
2242         pcSlice->getPOC(),
2243         pcSlice->getTLayer(),
2244         c,
2245         pcSlice->getSliceQpBase(),
2246         pcSlice->getSliceQp(),
2247         uibits );
2248#else
2249  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
2250         pcSlice->getPOC()-pcSlice->getLastIDR(),
2251         pcSlice->getTLayer(),
2252         c,
2253         pcSlice->getSliceQp(),
2254         uibits );
2255#endif
2256#endif
2257
2258  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR );
2259  printf(" [ET %5.0f ]", dEncTime );
2260 
2261  for (Int iRefList = 0; iRefList < 2; iRefList++)
2262  {
2263    printf(" [L%d ", iRefList);
2264    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
2265    {
2266      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
2267    }
2268    printf("]");
2269  }
2270}
2271
2272/** Function for deciding the nal_unit_type.
2273 * \param uiPOCCurr POC of the current picture
2274 * \returns the nal_unit type of the picture
2275 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
2276 */
2277NalUnitType TEncGOP::getNalUnitType(UInt uiPOCCurr)
2278{
2279  if (uiPOCCurr == 0)
2280  {
2281    return NAL_UNIT_CODED_SLICE_IDR;
2282  }
2283  if (uiPOCCurr % m_pcCfg->getIntraPeriod() == 0)
2284  {
2285    if (m_pcCfg->getDecodingRefreshType() == 1)
2286    {
2287      return NAL_UNIT_CODED_SLICE_CRA;
2288    }
2289    else if (m_pcCfg->getDecodingRefreshType() == 2)
2290    {
2291      return NAL_UNIT_CODED_SLICE_IDR;
2292    }
2293  }
2294  if(m_pocCRA>0)
2295  {
2296    if(uiPOCCurr<m_pocCRA)
2297    {
2298      // All leading pictures are being marked as TFD pictures here since current encoder uses all
2299      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
2300      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
2301      // controlling the reference pictures used for encoding that leading picture. Such a leading
2302      // picture need not be marked as a TFD picture.
2303      return NAL_UNIT_CODED_SLICE_TFD;
2304    }
2305  }
2306#if NAL_UNIT_TYPES_J1003_D7
2307  return NAL_UNIT_CODED_SLICE_TRAIL_R;
2308#else
2309  return NAL_UNIT_CODED_SLICE;
2310#endif
2311}
2312
2313Double TEncGOP::xCalculateRVM()
2314{
2315  Double dRVM = 0;
2316 
2317  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFrameToBeEncoded() > RVM_VCEGAM10_M * 2 )
2318  {
2319    // calculate RVM only for lowdelay configurations
2320    std::vector<Double> vRL , vB;
2321    size_t N = m_vRVM_RP.size();
2322    vRL.resize( N );
2323    vB.resize( N );
2324   
2325    Int i;
2326    Double dRavg = 0 , dBavg = 0;
2327    vB[RVM_VCEGAM10_M] = 0;
2328    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
2329    {
2330      vRL[i] = 0;
2331      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
2332        vRL[i] += m_vRVM_RP[j];
2333      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
2334      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
2335      dRavg += m_vRVM_RP[i];
2336      dBavg += vB[i];
2337    }
2338   
2339    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
2340    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
2341   
2342    double dSigamB = 0;
2343    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
2344    {
2345      Double tmp = vB[i] - dBavg;
2346      dSigamB += tmp * tmp;
2347    }
2348    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
2349   
2350    double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
2351   
2352    dRVM = dSigamB / dRavg * f;
2353  }
2354 
2355  return( dRVM );
2356}
2357
2358/** Determine the difference between consecutive tile sizes (in bytes) and writes it to  bistream rNalu [slice header]
2359 * \param rpcBitstreamRedirect contains the bitstream to be concatenated to rNalu. rpcBitstreamRedirect contains slice payload. rpcSlice contains tile location information.
2360 * \returns Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
2361 */
2362Void TEncGOP::xWriteTileLocationToSliceHeader (OutputNALUnit& rNalu, TComOutputBitstream*& rpcBitstreamRedirect, TComSlice*& rpcSlice)
2363{
2364  // Byte-align
2365#if BYTE_ALIGNMENT
2366  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
2367#else
2368  rNalu.m_Bitstream.writeAlignOne();
2369#endif
2370
2371  // Perform bitstream concatenation
2372  if (rpcBitstreamRedirect->getNumberOfWrittenBits() > 0)
2373  {
2374    UInt uiBitCount  = rpcBitstreamRedirect->getNumberOfWrittenBits();
2375    if (rpcBitstreamRedirect->getByteStreamLength()>0)
2376    {
2377      UChar *pucStart  =  reinterpret_cast<UChar*>(rpcBitstreamRedirect->getByteStream());
2378      UInt uiWriteByteCount = 0;
2379      while (uiWriteByteCount < (uiBitCount >> 3) )
2380      {
2381        UInt uiBits = (*pucStart);
2382        rNalu.m_Bitstream.write(uiBits, 8);
2383        pucStart++;
2384        uiWriteByteCount++;
2385      }
2386    }
2387    UInt uiBitsHeld = (uiBitCount & 0x07);
2388    for (UInt uiIdx=0; uiIdx < uiBitsHeld; uiIdx++)
2389    {
2390      rNalu.m_Bitstream.write((rpcBitstreamRedirect->getHeldBits() & (1 << (7-uiIdx))) >> (7-uiIdx), 1);
2391    }         
2392  }
2393
2394  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
2395
2396  delete rpcBitstreamRedirect;
2397  rpcBitstreamRedirect = new TComOutputBitstream;
2398}
2399
2400// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
2401// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
2402Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
2403{
2404  TComReferencePictureSet *rps = pcSlice->getRPS();
2405  if(!rps->getNumberOfLongtermPictures())
2406  {
2407    return;
2408  }
2409
2410  // Arrange long-term reference pictures in the correct order of LSB and MSB,
2411  // and assign values for pocLSBLT and MSB present flag
2412  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
2413  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
2414  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
2415  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
2416  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
2417  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
2418
2419  // Get the long-term reference pictures
2420  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
2421  Int i, ctr = 0;
2422  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
2423  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
2424  {
2425    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
2426    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
2427    indices[ctr]      = i; 
2428  }
2429  Int numLongPics = rps->getNumberOfLongtermPictures();
2430  assert(ctr == numLongPics);
2431
2432  // Arrange LTR pictures in decreasing order of LSB
2433  for(i = 0; i < numLongPics; i++)
2434  {
2435    for(Int j = 0; j < numLongPics - 1; j++)
2436    {
2437      if(longtermPicsLSB[j] < longtermPicsLSB[j+1])
2438      {
2439        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
2440        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
2441        std::swap(indices[j]        , indices[j+1]        );
2442      }
2443    }
2444  }
2445  // Now for those pictures that have the same LSB, arrange them
2446  // in increasing MSB cycle, or equivalently decreasing MSB
2447  for(i = 0; i < numLongPics;)    // i incremented using j
2448  {
2449    Int j = i + 1;
2450    Int pocLSB = longtermPicsLSB[i];
2451    for(; j < numLongPics; j++)
2452    {
2453      if(pocLSB != longtermPicsLSB[j])
2454      {
2455        break;
2456      }
2457    }
2458    // Last index upto which lsb equals pocLSB is j - 1
2459    // Now sort based on the MSB values
2460    Int sta, end;
2461    for(sta = i; sta < j; sta++)
2462    {
2463      for(end = i; end < j - 1; end++)
2464      {
2465      // longtermPicsMSB = longtermPicsPoc - longtermPicsLSB
2466        if(longtermPicsPoc[end] - longtermPicsLSB[end] < longtermPicsPoc[end+1] - longtermPicsLSB[end+1])
2467        {
2468          std::swap(longtermPicsPoc[end], longtermPicsPoc[end+1]);
2469          std::swap(longtermPicsLSB[end], longtermPicsLSB[end+1]);
2470          std::swap(indices[end]        , indices[end+1]        );
2471        }
2472      }
2473    }
2474    i = j;
2475  }
2476  for(i = 0; i < numLongPics; i++)
2477  {
2478    // Check if MSB present flag should be enabled.
2479    // Check if the buffer contains any pictures that have the same LSB.
2480    TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
2481    TComPic*                      pcPic;
2482    while ( iterPic != rcListPic.end() )
2483    {
2484      pcPic = *iterPic;
2485      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
2486#if REFERENCE_PICTURE_DEFN
2487                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
2488#else
2489                                      (pcPic->getSlice(0)->getNalRefFlag())     &&    // Reference picture
2490#endif
2491                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
2492      {
2493        mSBPresentFlag[i] = true;
2494        break;
2495      }
2496      iterPic++;     
2497    }
2498  }
2499
2500  // tempArray for usedByCurr flag
2501  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
2502  for(i = 0; i < numLongPics; i++)
2503  {
2504    tempArray[i] = rps->getUsed(indices[i]);
2505  }
2506  // Now write the final values;
2507  ctr = 0;
2508  Int currMSB = 0, currLSB = 0;
2509  // currPicPoc = currMSB + currLSB
2510  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 
2511  currMSB = pcSlice->getPOC() - currLSB;
2512
2513  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
2514  {
2515    rps->setPOC                   (i, longtermPicsPoc[ctr]);
2516    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
2517    rps->setUsed                  (i, tempArray[ctr]);
2518    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
2519    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
2520    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);     
2521
2522    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
2523  }
2524}
2525//! \}
Note: See TracBrowser for help on using the repository browser.