source: SHVCSoftware/branches/HM-10.0-dev-SHM/source/Lib/TLibEncoder/TEncGOP.cpp @ 582

Last change on this file since 582 was 107, checked in by interdigital, 12 years ago

reference picture list construction bug fix for adding ILR picture to match SHM test model text.

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