source: SHVCSoftware/branches/SHM-1.0-dev/source/Lib/TLibEncoder/TEncGOP.cpp @ 1108

Last change on this file since 1108 was 27, checked in by qualcomm, 12 years ago

Clean up for L0366 from Qualcomm, liweig@…

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