source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibEncoder/TEncGOP.cpp @ 1263

Last change on this file since 1263 was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

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