source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncGOP.cpp @ 186

Last change on this file since 186 was 125, checked in by seregin, 12 years ago

copy from HM-10.0-dev-SHM

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.