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

Last change on this file since 58 was 57, checked in by seregin, 12 years ago

RefIdx porting

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