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

Last change on this file since 1502 was 1502, checked in by seregin, 8 years ago

infer parameters in SPS after activation, fixing chroma scaling for non 4:2:0

  • Property svn:eol-style set to native
File size: 157.5 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-2015, 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
52#include <deque>
53using namespace std;
54
55#if SVC_EXTENSION
56#include <limits.h>
57Bool TEncGOP::m_signalledVPS = false;
58#endif
59
60
61//! \ingroup TLibEncoder
62//! \{
63
64// ====================================================================================================================
65// Constructor / destructor / initialization / destroy
66// ====================================================================================================================
67Int getLSB(Int poc, Int maxLSB)
68{
69  if (poc >= 0)
70  {
71    return poc % maxLSB;
72  }
73  else
74  {
75    return (maxLSB - ((-poc) % maxLSB)) % maxLSB;
76  }
77}
78
79TEncGOP::TEncGOP()
80{
81  m_iLastIDR            = 0;
82  m_iGopSize            = 0;
83  m_iNumPicCoded        = 0; //Niko
84  m_bFirst              = true;
85  m_iLastRecoveryPicPOC = 0;
86
87  m_pcCfg               = NULL;
88  m_pcSliceEncoder      = NULL;
89  m_pcListPic           = NULL;
90
91  m_pcEntropyCoder      = NULL;
92  m_pcCavlcCoder        = NULL;
93  m_pcSbacCoder         = NULL;
94  m_pcBinCABAC          = NULL;
95
96  m_bSeqFirst           = true;
97
98  m_bRefreshPending     = 0;
99  m_pocCRA            = 0;
100  m_numLongTermRefPicSPS = 0;
101  ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
102  ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
103  m_lastBPSEI         = 0;
104  m_bufferingPeriodSEIPresentInAU = false;
105  m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP;
106  m_associatedIRAPPOC  = 0;
107#if SVC_EXTENSION
108  m_pocCraWithoutReset = 0;
109  m_associatedIrapPocBeforeReset = 0;
110  m_pcPredSearch        = NULL;
111#if CGS_3D_ASYMLUT
112  m_temp = NULL;
113  m_pColorMappedPic = NULL;
114#endif
115  m_lastPocPeriodId = -1;
116  m_noRaslOutputFlag = false;
117  m_prevPicHasEos    = false;
118#endif //SVC_EXTENSION
119  return;
120}
121
122TEncGOP::~TEncGOP()
123{
124#if CGS_3D_ASYMLUT
125  if(m_pColorMappedPic)
126  {
127    m_pColorMappedPic->destroy();
128    delete m_pColorMappedPic;
129    m_pColorMappedPic = NULL;               
130  }
131  if(m_temp)
132  {
133    xDestroy2DArray(m_temp, m_cgsFilterLength>>1, 0);
134    m_temp = NULL;
135  }
136#endif
137}
138
139/** Create list to contain pointers to CTU start addresses of slice.
140 */
141#if SVC_EXTENSION
142Void  TEncGOP::create( UInt layerId )
143{
144  m_bLongtermTestPictureHasBeenCoded = 0;
145  m_bLongtermTestPictureHasBeenCoded2 = 0;
146  m_layerId = layerId;
147}
148#else
149Void  TEncGOP::create()
150{
151  m_bLongtermTestPictureHasBeenCoded = 0;
152  m_bLongtermTestPictureHasBeenCoded2 = 0;
153}
154#endif
155
156Void  TEncGOP::destroy()
157{
158}
159
160Void TEncGOP::init ( TEncTop* pcTEncTop )
161{
162  m_pcEncTop     = pcTEncTop;
163  m_pcCfg                = pcTEncTop;
164  m_seiEncoder.init(m_pcCfg, pcTEncTop, this);
165  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
166  m_pcListPic            = pcTEncTop->getListPic();
167
168  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
169  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
170  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
171  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
172  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
173
174  m_pcSAO                = pcTEncTop->getSAO();
175  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
176  m_lastBPSEI          = 0;
177  m_totalCoded         = 0;
178
179#if SVC_EXTENSION
180  m_ppcTEncTop           = pcTEncTop->getLayerEnc();
181  m_pcPredSearch         = pcTEncTop->getPredSearch();                       ///< encoder search class
182#if CGS_3D_ASYMLUT
183  if( pcTEncTop->getLayerId() )
184  {
185    UInt prevLayerIdx = 0;
186
187    if( pcTEncTop->getNumActiveRefLayers() > 0 )
188    {
189      prevLayerIdx = pcTEncTop->getPredLayerIdx( pcTEncTop->getNumActiveRefLayers() - 1);
190    }
191
192    const TComSPS *sps = pcTEncTop->getSPS();
193
194    const Int bitDepthLuma = sps->getBitDepth(CHANNEL_TYPE_LUMA);
195    const Int bitDepthChroma = sps->getBitDepth(CHANNEL_TYPE_CHROMA);
196    const Int prevBitDepthLuma = m_ppcTEncTop[prevLayerIdx]->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
197    const Int prevBitDepthChroma = m_ppcTEncTop[prevLayerIdx]->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA);
198
199    m_Enc3DAsymLUTPicUpdate.create( m_pcCfg->getCGSMaxOctantDepth() , prevBitDepthLuma, prevBitDepthChroma, bitDepthLuma, bitDepthChroma , m_pcCfg->getCGSMaxYPartNumLog2() );
200    m_Enc3DAsymLUTPPS.create( m_pcCfg->getCGSMaxOctantDepth(), prevBitDepthLuma, prevBitDepthChroma, bitDepthLuma, bitDepthChroma, m_pcCfg->getCGSMaxYPartNumLog2() );
201
202    if(!m_pColorMappedPic)
203    {
204      m_pColorMappedPic = new TComPicYuv;
205      m_pColorMappedPic->create( m_ppcTEncTop[0]->getSourceWidth(), m_ppcTEncTop[0]->getSourceHeight(), m_ppcTEncTop[0]->getChromaFormatIDC(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getMaxTotalCUDepth(), true, NULL );
206    }
207  }
208#endif
209#endif //SVC_EXTENSION
210}
211
212Int TEncGOP::xWriteVPS (AccessUnit &accessUnit, const TComVPS *vps)
213{
214#if SVC_EXTENSION
215  if( m_signalledVPS )
216  {
217    return 0;
218  }
219  m_signalledVPS = true;
220#endif
221  OutputNALUnit nalu(NAL_UNIT_VPS);
222  m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
223  m_pcEntropyCoder->encodeVPS(vps);
224  accessUnit.push_back(new NALUnitEBSP(nalu));
225  return (Int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
226}
227
228Int TEncGOP::xWriteSPS (AccessUnit &accessUnit, const TComSPS *sps)
229{
230#if SVC_EXTENSION
231  OutputNALUnit nalu(NAL_UNIT_SPS, 0, m_layerId);
232
233  if (m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0)
234  {
235    nalu.m_nuhLayerId = 0; // For independent base layer rewriting
236  }
237
238  // dependency constraint
239  assert( sps->getLayerId() == 0 || sps->getLayerId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, sps->getLayerId()) );
240#else
241  OutputNALUnit nalu(NAL_UNIT_SPS);
242#endif
243  m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
244  m_pcEntropyCoder->encodeSPS(sps);
245  accessUnit.push_back(new NALUnitEBSP(nalu));
246  return (Int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
247
248}
249
250Int TEncGOP::xWritePPS (AccessUnit &accessUnit, const TComPPS *pps)
251{
252#if SVC_EXTENSION
253  OutputNALUnit nalu(NAL_UNIT_PPS, 0, m_layerId);
254
255  if( m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0 )
256  {
257    // For independent base layer rewriting
258    nalu.m_nuhLayerId = 0;
259  }
260
261  // dependency constraint
262  assert( pps->getLayerId() == 0 || pps->getLayerId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pps->getLayerId()) );
263#else
264  OutputNALUnit nalu(NAL_UNIT_PPS);
265#endif
266  m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
267#if SVC_EXTENSION && CGS_3D_ASYMLUT
268  m_pcEntropyCoder->encodePPS(pps, &m_Enc3DAsymLUTPPS);
269#else
270  m_pcEntropyCoder->encodePPS(pps);
271#endif 
272  accessUnit.push_back(new NALUnitEBSP(nalu));
273  return (Int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
274}
275
276
277Int TEncGOP::xWriteParameterSets (AccessUnit &accessUnit, TComSlice *slice)
278{
279  Int actualTotalBits = 0;
280
281  actualTotalBits += xWriteVPS(accessUnit, m_pcEncTop->getVPS());
282  actualTotalBits += xWriteSPS(accessUnit, slice->getSPS());
283  actualTotalBits += xWritePPS(accessUnit, slice->getPPS());
284
285  return actualTotalBits;
286}
287
288Void TEncGOP::xWriteAccessUnitDelimiter (AccessUnit &accessUnit, TComSlice *slice)
289{
290  AUDWriter audWriter;
291  OutputNALUnit nalu(NAL_UNIT_ACCESS_UNIT_DELIMITER);
292
293  Int picType = slice->isIntra() ? 0 : (slice->isInterP() ? 1 : 2);
294
295  audWriter.codeAUD(nalu.m_Bitstream, picType);
296  accessUnit.push_front(new NALUnitEBSP(nalu));
297}
298
299// write SEI list into one NAL unit and add it to the Access unit at auPos
300#if O0164_MULTI_LAYER_HRD
301Void TEncGOP::xWriteSEI (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, Int temporalId, const TComVPS *vps, const TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei)
302#else
303Void TEncGOP::xWriteSEI (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, Int temporalId, const TComSPS *sps)
304#endif
305{
306  // don't do anything, if we get an empty list
307  if (seiMessages.empty())
308  {
309    return;
310  }
311#if O0164_MULTI_LAYER_HRD
312  OutputNALUnit nalu(naluType, temporalId, sps->getLayerId());
313  m_seiWriter.writeSEImessages(nalu.m_Bitstream, seiMessages, vps, sps, false, nestingSei, bspNestingSei);
314#else
315  OutputNALUnit nalu(naluType, temporalId);
316  m_seiWriter.writeSEImessages(nalu.m_Bitstream, seiMessages, sps, false);
317#endif 
318  auPos = accessUnit.insert(auPos, new NALUnitEBSP(nalu));
319  auPos++;
320}
321
322#if O0164_MULTI_LAYER_HRD
323Void TEncGOP::xWriteSEISeparately (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, Int temporalId, const TComVPS *vps, const TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei)
324#else
325Void TEncGOP::xWriteSEISeparately (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, Int temporalId, const TComSPS *sps)
326#endif
327{
328  // don't do anything, if we get an empty list
329  if (seiMessages.empty())
330  {
331    return;
332  }
333  for (SEIMessages::const_iterator sei = seiMessages.begin(); sei!=seiMessages.end(); sei++ )
334  {
335    SEIMessages tmpMessages;
336    tmpMessages.push_back(*sei);
337#if O0164_MULTI_LAYER_HRD
338    OutputNALUnit nalu(naluType, temporalId, sps->getLayerId());
339    m_seiWriter.writeSEImessages(nalu.m_Bitstream, tmpMessages, vps, sps, false, nestingSei, bspNestingSei);
340#else
341    OutputNALUnit nalu(naluType, temporalId);
342    m_seiWriter.writeSEImessages(nalu.m_Bitstream, tmpMessages, sps, false);
343#endif
344    auPos = accessUnit.insert(auPos, new NALUnitEBSP(nalu));
345    auPos++;
346  }
347}
348
349Void TEncGOP::xClearSEIs(SEIMessages& seiMessages, Bool deleteMessages)
350{
351  if (deleteMessages)
352  {
353    deleteSEIs(seiMessages);
354  }
355  else
356  {
357    seiMessages.clear();
358  }
359}
360
361// write SEI messages as separate NAL units ordered
362#if O0164_MULTI_LAYER_HRD
363Void TEncGOP::xWriteLeadingSEIOrdered (SEIMessages& seiMessages, SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId,const TComVPS *vps, const TComSPS *sps, Bool testWrite, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei)
364#else
365Void TEncGOP::xWriteLeadingSEIOrdered (SEIMessages& seiMessages, SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps, Bool testWrite)
366#endif
367{
368  AccessUnit::iterator itNalu = accessUnit.begin();
369
370  while ( (itNalu!=accessUnit.end())&&
371    ( (*itNalu)->m_nalUnitType==NAL_UNIT_ACCESS_UNIT_DELIMITER
372    || (*itNalu)->m_nalUnitType==NAL_UNIT_VPS
373    || (*itNalu)->m_nalUnitType==NAL_UNIT_SPS
374    || (*itNalu)->m_nalUnitType==NAL_UNIT_PPS
375    ))
376  {
377    itNalu++;
378  }
379
380  SEIMessages localMessages = seiMessages;
381  SEIMessages currentMessages;
382 
383#if ENC_DEC_TRACE
384  g_HLSTraceEnable = !testWrite;
385#endif
386  // The case that a specific SEI is not present is handled in xWriteSEI (empty list)
387
388  // Active parameter sets SEI must always be the first SEI
389  currentMessages = extractSeisByType(localMessages, SEI::ACTIVE_PARAMETER_SETS);
390  assert (currentMessages.size() <= 1);
391#if O0164_MULTI_LAYER_HRD
392  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, vps, sps, nestingSei, bspNestingSei);
393#else
394  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
395#endif
396  xClearSEIs(currentMessages, !testWrite);
397 
398  // Buffering period SEI must always be following active parameter sets
399  currentMessages = extractSeisByType(localMessages, SEI::BUFFERING_PERIOD);
400  assert (currentMessages.size() <= 1);
401#if O0164_MULTI_LAYER_HRD
402  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, vps, sps, nestingSei, bspNestingSei);
403#else
404  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
405#endif
406  xClearSEIs(currentMessages, !testWrite);
407
408  // Picture timing SEI must always be following buffering period
409  currentMessages = extractSeisByType(localMessages, SEI::PICTURE_TIMING);
410  assert (currentMessages.size() <= 1);
411#if O0164_MULTI_LAYER_HRD
412  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, vps, sps, nestingSei, bspNestingSei);
413#else
414  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
415#endif
416  xClearSEIs(currentMessages, !testWrite);
417
418  // Decoding unit info SEI must always be following picture timing
419  if (!duInfoSeiMessages.empty())
420  {
421    currentMessages.push_back(duInfoSeiMessages.front());
422    if (!testWrite)
423    {
424      duInfoSeiMessages.pop_front();
425    }
426#if O0164_MULTI_LAYER_HRD
427    xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, vps, sps, nestingSei, bspNestingSei);
428#else
429    xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
430#endif
431    xClearSEIs(currentMessages, !testWrite);
432  }
433
434  // Scalable nesting SEI must always be the following DU info
435  currentMessages = extractSeisByType(localMessages, SEI::SCALABLE_NESTING);
436#if O0164_MULTI_LAYER_HRD
437  xWriteSEISeparately(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, vps, sps, nestingSei, bspNestingSei);
438#else
439  xWriteSEISeparately(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
440#endif
441  xClearSEIs(currentMessages, !testWrite);
442
443  // And finally everything else one by one
444#if O0164_MULTI_LAYER_HRD
445  xWriteSEISeparately(NAL_UNIT_PREFIX_SEI, localMessages, accessUnit, itNalu, temporalId, vps, sps, nestingSei, bspNestingSei);
446#else
447  xWriteSEISeparately(NAL_UNIT_PREFIX_SEI, localMessages, accessUnit, itNalu, temporalId, sps);
448#endif
449  xClearSEIs(localMessages, !testWrite);
450
451  if (!testWrite)
452  {
453    seiMessages.clear();
454  }
455}
456
457#if O0164_MULTI_LAYER_HRD
458Void TEncGOP::xWriteLeadingSEIMessages (SEIMessages& seiMessages, SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId,const TComVPS *vps, const TComSPS *sps, std::deque<DUData> &duData, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei)
459#else
460Void TEncGOP::xWriteLeadingSEIMessages (SEIMessages& seiMessages, SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps, std::deque<DUData> &duData)
461#endif
462{
463  AccessUnit testAU;
464  SEIMessages picTimingSEIs = getSeisByType(seiMessages, SEI::PICTURE_TIMING);
465  assert (picTimingSEIs.size() < 2);
466  SEIPictureTiming * picTiming = picTimingSEIs.empty() ? NULL : (SEIPictureTiming*) picTimingSEIs.front();
467
468  // test writing
469#if O0164_MULTI_LAYER_HRD
470  xWriteLeadingSEIOrdered(seiMessages, duInfoSeiMessages, testAU, temporalId, vps, sps, true, nestingSei, bspNestingSei);
471#else
472  xWriteLeadingSEIOrdered(seiMessages, duInfoSeiMessages, testAU, temporalId, sps, true);
473#endif
474  // update Timing and DU info SEI
475  xUpdateDuData(testAU, duData);
476  xUpdateTimingSEI(picTiming, duData, sps);
477  xUpdateDuInfoSEI(duInfoSeiMessages, picTiming);
478  // actual writing
479#if O0164_MULTI_LAYER_HRD
480  xWriteLeadingSEIOrdered(seiMessages, duInfoSeiMessages, accessUnit, temporalId, vps, sps, false, nestingSei, bspNestingSei);
481#else
482  xWriteLeadingSEIOrdered(seiMessages, duInfoSeiMessages, accessUnit, temporalId, sps, false);
483#endif
484
485  // testAU will automatically be cleaned up when losing scope
486}
487
488#if O0164_MULTI_LAYER_HRD
489Void TEncGOP::xWriteTrailingSEIMessages (SEIMessages& seiMessages, AccessUnit &accessUnit, Int temporalId, const TComVPS *vps, const TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei)
490#else
491Void TEncGOP::xWriteTrailingSEIMessages (SEIMessages& seiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps)
492#endif
493{
494  // Note: using accessUnit.end() works only as long as this function is called after slice coding and before EOS/EOB NAL units
495  AccessUnit::iterator pos = accessUnit.end();
496#if O0164_MULTI_LAYER_HRD
497  xWriteSEISeparately(NAL_UNIT_SUFFIX_SEI, seiMessages, accessUnit, pos, temporalId, vps, sps, nestingSei, bspNestingSei);
498#else
499  xWriteSEISeparately(NAL_UNIT_SUFFIX_SEI, seiMessages, accessUnit, pos, temporalId, sps);
500#endif
501  deleteSEIs(seiMessages);
502}
503
504#if O0164_MULTI_LAYER_HRD
505Void TEncGOP::xWriteDuSEIMessages (SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId, const TComVPS *vps, const TComSPS *sps, std::deque<DUData> &duData, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei)
506#else
507Void TEncGOP::xWriteDuSEIMessages (SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps, std::deque<DUData> &duData)
508#endif
509{
510  const TComHRD *hrd = sps->getVuiParameters()->getHrdParameters();
511
512  if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
513  {
514    Int naluIdx = 0;
515    AccessUnit::iterator nalu = accessUnit.begin();
516
517    // skip over first DU, we have a DU info SEI there already
518    while (naluIdx < duData[0].accumNalsDU && nalu!=accessUnit.end())
519    {
520      naluIdx++;
521      nalu++;
522    }
523
524    SEIMessages::iterator duSEI = duInfoSeiMessages.begin();
525    // loop over remaining DUs
526    for (Int duIdx = 1; duIdx < duData.size(); duIdx++)
527    {
528      if (duSEI == duInfoSeiMessages.end())
529      {
530        // if the number of generated SEIs matches the number of DUs, this should not happen
531        assert (false);
532        return;
533      }
534      // write the next SEI
535      SEIMessages tmpSEI;
536      tmpSEI.push_back(*duSEI);
537#if O0164_MULTI_LAYER_HRD
538      xWriteSEI(NAL_UNIT_PREFIX_SEI, tmpSEI, accessUnit, nalu, temporalId, vps, sps, nestingSei, bspNestingSei);
539#else
540      xWriteSEI(NAL_UNIT_PREFIX_SEI, tmpSEI, accessUnit, nalu, temporalId, sps);
541#endif
542      // nalu points to the position after the SEI, so we have to increase the index as well
543      naluIdx++;
544      while ((naluIdx < duData[duIdx].accumNalsDU) && nalu!=accessUnit.end())
545      {
546        naluIdx++;
547        nalu++;
548      }
549      duSEI++;
550    }
551  }
552  deleteSEIs(duInfoSeiMessages);
553}
554
555
556Void TEncGOP::xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const TComSPS *sps, const TComPPS *pps)
557{
558  OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
559
560#if R0247_SEI_ACTIVE
561  if(m_pcCfg->getActiveParameterSetsSEIEnabled() && m_layerId == 0 )
562#else
563  if(m_pcCfg->getActiveParameterSetsSEIEnabled())
564#endif
565  {
566    SEIActiveParameterSets *sei = new SEIActiveParameterSets;
567    m_seiEncoder.initSEIActiveParameterSets (sei, m_pcCfg->getVPS(), sps);
568    seiMessages.push_back(sei);
569  }
570
571  if(m_pcCfg->getFramePackingArrangementSEIEnabled())
572  {
573    SEIFramePacking *sei = new SEIFramePacking;
574    m_seiEncoder.initSEIFramePacking (sei, m_iNumPicCoded);
575    seiMessages.push_back(sei);
576  }
577
578  if(m_pcCfg->getSegmentedRectFramePackingArrangementSEIEnabled())
579  {
580    SEISegmentedRectFramePacking *sei = new SEISegmentedRectFramePacking;
581    m_seiEncoder.initSEISegmentedRectFramePacking(sei);
582    seiMessages.push_back(sei);
583  }
584
585  if (m_pcCfg->getDisplayOrientationSEIAngle())
586  {
587    SEIDisplayOrientation *sei = new SEIDisplayOrientation;
588    m_seiEncoder.initSEIDisplayOrientation(sei);
589    seiMessages.push_back(sei);
590  }
591
592  if(m_pcCfg->getToneMappingInfoSEIEnabled())
593  {
594    SEIToneMappingInfo *sei = new SEIToneMappingInfo;
595    m_seiEncoder.initSEIToneMappingInfo (sei);
596    seiMessages.push_back(sei);
597  }
598
599  if(m_pcCfg->getTMCTSSEIEnabled())
600  {
601    SEITempMotionConstrainedTileSets *sei = new SEITempMotionConstrainedTileSets;
602    m_seiEncoder.initSEITempMotionConstrainedTileSets(sei, pps);
603    seiMessages.push_back(sei);
604  }
605
606  if(m_pcCfg->getTimeCodeSEIEnabled())
607  {
608    SEITimeCode *seiTimeCode = new SEITimeCode;
609    m_seiEncoder.initSEITimeCode(seiTimeCode);
610    seiMessages.push_back(seiTimeCode);
611  }
612
613  if(m_pcCfg->getKneeSEIEnabled())
614  {
615    SEIKneeFunctionInfo *sei = new SEIKneeFunctionInfo;
616    m_seiEncoder.initSEIKneeFunctionInfo(sei);
617    seiMessages.push_back(sei);
618  }
619   
620  if(m_pcCfg->getMasteringDisplaySEI().colourVolumeSEIEnabled)
621  {
622    const TComSEIMasteringDisplay &seiCfg=m_pcCfg->getMasteringDisplaySEI();
623    SEIMasteringDisplayColourVolume *sei = new SEIMasteringDisplayColourVolume;
624    sei->values = seiCfg;
625    seiMessages.push_back(sei);
626  }
627  if(m_pcCfg->getChromaResamplingFilterHintEnabled())
628  {
629    SEIChromaResamplingFilterHint *seiChromaResamplingFilterHint = new SEIChromaResamplingFilterHint;
630    m_seiEncoder.initSEIChromaResamplingFilterHint(seiChromaResamplingFilterHint, m_pcCfg->getChromaResamplingHorFilterIdc(), m_pcCfg->getChromaResamplingVerFilterIdc());
631    seiMessages.push_back(seiChromaResamplingFilterHint);
632  }
633
634#if SVC_EXTENSION
635#if LAYERS_NOT_PRESENT_SEI
636  if(m_pcCfg->getLayersNotPresentSEIEnabled())
637  {
638    SEILayersNotPresent *sei = new SEILayersNotPresent;
639    m_seiEncoder.initSEILayersNotPresent(sei);
640    seiMessages.push_back(sei);
641  }
642#endif
643
644#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
645  if(m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled())
646  {
647    SEIInterLayerConstrainedTileSets *sei = new SEIInterLayerConstrainedTileSets;
648    m_seiEncoder.initSEIInterLayerConstrainedTileSets(sei);
649
650    // nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, m_pcCfg->getNumLayer()-1); // For highest layer //ToDo(VS)
651    seiMessages.push_back(sei);
652  }
653#endif
654
655#if P0123_ALPHA_CHANNEL_SEI
656  if( m_pcCfg->getAlphaSEIEnabled() && m_pcEncTop->getVPS()->getScalabilityId(m_layerId, AUX_ID) && m_pcEncTop->getVPS()->getDimensionId(m_pcEncTop->getVPS()->getLayerIdxInVps(m_layerId), m_pcEncTop->getVPS()->getNumScalabilityTypes() - 1) == AUX_ALPHA )
657  {
658    SEIAlphaChannelInfo *sei = new SEIAlphaChannelInfo;
659    m_seiEncoder.initSEIAlphaChannelInfo(sei);
660    seiMessages.push_back(sei);
661  }
662#endif
663
664#if Q0096_OVERLAY_SEI
665  if(m_pcCfg->getOverlaySEIEnabled())
666  {
667    SEIOverlayInfo *sei = new SEIOverlayInfo;
668    m_seiEncoder.initSEIOverlayInfo(sei);
669    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
670    seiMessages.push_back(sei);
671  }
672#endif
673#if O0164_MULTI_LAYER_HRD
674  if( m_layerId == 0 && m_pcEncTop->getVPS()->getVpsVuiBspHrdPresentFlag() )
675  {
676    TComVPS *vps = m_pcEncTop->getVPS();
677    for(Int i = 0; i < vps->getNumOutputLayerSets(); i++)
678    {
679      for(Int k = 0; k < vps->getNumSignalledPartitioningSchemes(i); k++)
680      {
681        for(Int l = 0; l < vps->getNumPartitionsInSchemeMinus1(i, k)+1; l++)
682        {
683          SEIScalableNesting *scalableBspNestingSei = new SEIScalableNesting;
684          m_seiEncoder.initBspNestingSEI(scalableBspNestingSei, vps, sps, i, k, l);
685          seiMessages.push_back(scalableBspNestingSei);
686        }
687      }
688    }
689  }
690#endif
691#endif //SVC_EXTENSION
692}
693
694Void TEncGOP::xCreatePerPictureSEIMessages (Int picInGOP, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, TComSlice *slice)
695{
696  if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( slice->getSliceType() == I_SLICE ) &&
697    ( slice->getSPS()->getVuiParametersPresentFlag() ) &&
698    ( ( slice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
699    || ( slice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
700  {
701    SEIBufferingPeriod *bufferingPeriodSEI = new SEIBufferingPeriod();
702    m_seiEncoder.initSEIBufferingPeriod(bufferingPeriodSEI, slice);
703    seiMessages.push_back(bufferingPeriodSEI);
704    m_bufferingPeriodSEIPresentInAU = true;
705
706    if (m_pcCfg->getScalableNestingSEIEnabled())
707    {
708      SEIBufferingPeriod *bufferingPeriodSEIcopy = new SEIBufferingPeriod();
709      bufferingPeriodSEI->copyTo(*bufferingPeriodSEIcopy);
710      nestedSeiMessages.push_back(bufferingPeriodSEIcopy);
711    }
712  }
713
714  if (picInGOP ==0 && m_pcCfg->getSOPDescriptionSEIEnabled() ) // write SOP description SEI (if enabled) at the beginning of GOP
715  {
716    SEISOPDescription* sopDescriptionSEI = new SEISOPDescription();
717    m_seiEncoder.initSEISOPDescription(sopDescriptionSEI, slice, picInGOP, m_iLastIDR, m_iGopSize);
718    seiMessages.push_back(sopDescriptionSEI);
719  }
720
721  if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( slice->getSliceType() == I_SLICE ) )
722  {
723    if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !slice->getRapPicFlag() )
724    {
725      // Gradual decoding refresh SEI
726      SEIGradualDecodingRefreshInfo *gradualDecodingRefreshInfoSEI = new SEIGradualDecodingRefreshInfo();
727      gradualDecodingRefreshInfoSEI->m_gdrForegroundFlag = true; // Indicating all "foreground"
728      seiMessages.push_back(gradualDecodingRefreshInfoSEI);
729    }
730    // Recovery point SEI
731    SEIRecoveryPoint *recoveryPointSEI = new SEIRecoveryPoint();
732    m_seiEncoder.initSEIRecoveryPoint(recoveryPointSEI, slice);
733    seiMessages.push_back(recoveryPointSEI);
734  }
735  if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
736  {
737    SEITemporalLevel0Index *temporalLevel0IndexSEI = new SEITemporalLevel0Index();
738    m_seiEncoder.initTemporalLevel0IndexSEI(temporalLevel0IndexSEI, slice);
739    seiMessages.push_back(temporalLevel0IndexSEI);
740  }
741
742  if( m_pcEncTop->getNoDisplaySEITLayer() && ( slice->getTLayer() >= m_pcEncTop->getNoDisplaySEITLayer() ) )
743  {
744    SEINoDisplay *seiNoDisplay = new SEINoDisplay;
745    seiNoDisplay->m_noDisplay = true;
746    seiMessages.push_back(seiNoDisplay);
747  }
748
749  // insert one Colour Remapping Info SEI for the picture (if the file exists)
750  if (!m_pcCfg->getColourRemapInfoSEIFileRoot().empty())
751  {
752    SEIColourRemappingInfo *seiColourRemappingInfo = new SEIColourRemappingInfo();
753    const Bool success = m_seiEncoder.initSEIColourRemappingInfo(seiColourRemappingInfo, slice->getPOC() );
754
755    if(success)
756    {
757      seiMessages.push_back(seiColourRemappingInfo);
758    }
759    else
760    {
761      delete seiColourRemappingInfo;
762    }
763  }
764
765#if Q0189_TMVP_CONSTRAINTS
766  if( m_pcEncTop->getTMVPConstraintsSEIEnabled() == 1 && (m_pcEncTop->getTMVPModeId() == 1 || m_pcEncTop->getTMVPModeId() == 2) &&
767    slice->getLayerId() > 0 && (slice->getNalUnitType() ==  NAL_UNIT_CODED_SLICE_IDR_W_RADL || slice->getNalUnitType() ==  NAL_UNIT_CODED_SLICE_IDR_N_LP))
768  {
769    SEITMVPConstrains *seiTMVPConstrains = new SEITMVPConstrains;
770    seiTMVPConstrains->no_intra_layer_col_pic_flag = 1;
771    seiTMVPConstrains->prev_pics_not_used_flag = 1;
772    seiMessages.push_back(seiTMVPConstrains);
773  }
774#endif
775#if Q0247_FRAME_FIELD_INFO
776  if( slice->getLayerId()> 0 && ( (m_pcCfg->getProgressiveSourceFlag() && m_pcCfg->getInterlacedSourceFlag()) || m_pcCfg->getFrameFieldInfoPresentFlag()))
777  {
778    Bool isField = slice->getPic()->isField();
779    SEIFrameFieldInfo *seiFFInfo = new SEIFrameFieldInfo;
780    seiFFInfo->m_ffinfo_picStruct = (isField && slice->getPic()->isTopField())? 1 : isField? 2 : 0;
781    seiMessages.push_back(seiFFInfo);
782  }
783#endif
784}
785
786Void TEncGOP::xCreateScalableNestingSEI (SEIMessages& seiMessages, SEIMessages& nestedSeiMessages)
787{
788  SEIMessages tmpMessages;
789  while (!nestedSeiMessages.empty())
790  {
791    SEI* sei=nestedSeiMessages.front();
792    nestedSeiMessages.pop_front();
793    tmpMessages.push_back(sei);
794    SEIScalableNesting *nestingSEI = new SEIScalableNesting();
795    m_seiEncoder.initSEIScalableNesting(nestingSEI, tmpMessages);
796    seiMessages.push_back(nestingSEI);
797    tmpMessages.clear();
798  }
799}
800
801Void TEncGOP::xCreatePictureTimingSEI  (Int IRAPGOPid, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, SEIMessages& duInfoSeiMessages, TComSlice *slice, Bool isField, std::deque<DUData> &duData)
802{
803  const TComVUI *vui = slice->getSPS()->getVuiParameters();
804  const TComHRD *hrd = vui->getHrdParameters();
805
806  // update decoding unit parameters
807  if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
808    ( slice->getSPS()->getVuiParametersPresentFlag() ) &&
809    (  hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() ) )
810  {
811    Int picSptDpbOutputDuDelay = 0;
812    SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming();
813
814    // DU parameters
815    if( hrd->getSubPicCpbParamsPresentFlag() )
816    {
817      UInt numDU = (UInt) duData.size();
818      pictureTimingSEI->m_numDecodingUnitsMinus1     = ( numDU - 1 );
819      pictureTimingSEI->m_duCommonCpbRemovalDelayFlag = false;
820      pictureTimingSEI->m_numNalusInDuMinus1.resize( numDU );
821      pictureTimingSEI->m_duCpbRemovalDelayMinus1.resize( numDU );
822    }
823    pictureTimingSEI->m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<Double>(hrd->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
824    pictureTimingSEI->m_picDpbOutputDelay = slice->getSPS()->getNumReorderPics(slice->getSPS()->getMaxTLayers()-1) + slice->getPOC() - m_totalCoded;
825    if(m_pcCfg->getEfficientFieldIRAPEnabled() && IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
826    {
827      // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
828      pictureTimingSEI->m_picDpbOutputDelay ++;
829    }
830    Int factor = hrd->getTickDivisorMinus2() + 2;
831    pictureTimingSEI->m_picDpbOutputDuDelay = factor * pictureTimingSEI->m_picDpbOutputDelay;
832    if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
833    {
834      picSptDpbOutputDuDelay = factor * pictureTimingSEI->m_picDpbOutputDelay;
835    }
836    if (m_bufferingPeriodSEIPresentInAU)
837    {
838      m_lastBPSEI = m_totalCoded;
839    }
840
841    if( hrd->getSubPicCpbParamsPresentFlag() )
842    {
843      Int i;
844      UInt64 ui64Tmp;
845      UInt uiPrev = 0;
846      UInt numDU = ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 );
847      std::vector<UInt> &rDuCpbRemovalDelayMinus1 = pictureTimingSEI->m_duCpbRemovalDelayMinus1;
848      UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
849
850      for( i = 0; i < numDU; i ++ )
851      {
852        pictureTimingSEI->m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( duData[i].accumNalsDU - 1 ) : ( duData[i].accumNalsDU- duData[i-1].accumNalsDU - 1 );
853      }
854
855      if( numDU == 1 )
856      {
857        rDuCpbRemovalDelayMinus1[ 0 ] = 0; /* don't care */
858      }
859      else
860      {
861        rDuCpbRemovalDelayMinus1[ numDU - 1 ] = 0;/* by definition */
862        UInt tmp = 0;
863        UInt accum = 0;
864
865        for( i = ( numDU - 2 ); i >= 0; i -- )
866        {
867          ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
868          if( (UInt)ui64Tmp > maxDiff )
869          {
870            tmp ++;
871          }
872        }
873        uiPrev = 0;
874
875        UInt flag = 0;
876        for( i = ( numDU - 2 ); i >= 0; i -- )
877        {
878          flag = 0;
879          ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
880
881          if( (UInt)ui64Tmp > maxDiff )
882          {
883            if(uiPrev >= maxDiff - tmp)
884            {
885              ui64Tmp = uiPrev + 1;
886              flag = 1;
887            }
888            else                            ui64Tmp = maxDiff - tmp + 1;
889          }
890          rDuCpbRemovalDelayMinus1[ i ] = (UInt)ui64Tmp - uiPrev - 1;
891          if( (Int)rDuCpbRemovalDelayMinus1[ i ] < 0 )
892          {
893            rDuCpbRemovalDelayMinus1[ i ] = 0;
894          }
895          else if (tmp > 0 && flag == 1)
896          {
897            tmp --;
898          }
899          accum += rDuCpbRemovalDelayMinus1[ i ] + 1;
900          uiPrev = accum;
901        }
902      }
903    }
904   
905    if( m_pcCfg->getPictureTimingSEIEnabled() )
906    {
907      pictureTimingSEI->m_picStruct = (isField && slice->getPic()->isTopField())? 1 : isField? 2 : 0;
908      seiMessages.push_back(pictureTimingSEI);
909
910      if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
911      {
912        SEIPictureTiming *pictureTimingSEIcopy = new SEIPictureTiming();
913        pictureTimingSEI->copyTo(*pictureTimingSEIcopy);
914        nestedSeiMessages.push_back(pictureTimingSEIcopy);
915      }
916    }
917
918    if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
919    {
920      for( Int i = 0; i < ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 ); i ++ )
921      {
922        SEIDecodingUnitInfo *duInfoSEI = new SEIDecodingUnitInfo();
923        duInfoSEI->m_decodingUnitIdx = i;
924        duInfoSEI->m_duSptCpbRemovalDelay = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i] + 1;
925        duInfoSEI->m_dpbOutputDuDelayPresentFlag = false;
926        duInfoSEI->m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
927
928        duInfoSeiMessages.push_back(duInfoSEI);
929      }
930    }
931
932    if( !m_pcCfg->getPictureTimingSEIEnabled() && pictureTimingSEI )
933    {
934      delete pictureTimingSEI;
935    }
936  }
937}
938
939Void TEncGOP::xUpdateDuData(AccessUnit &testAU, std::deque<DUData> &duData)
940{
941  if (duData.empty())
942  {
943    return;
944  }
945  // fix first
946  UInt numNalUnits = (UInt)testAU.size();
947  UInt numRBSPBytes = 0;
948  for (AccessUnit::const_iterator it = testAU.begin(); it != testAU.end(); it++)
949  {
950    numRBSPBytes += UInt((*it)->m_nalUnitData.str().size());
951  }
952  duData[0].accumBitsDU += ( numRBSPBytes << 3 );
953  duData[0].accumNalsDU += numNalUnits;
954
955  // adapt cumulative sums for all following DUs
956  // and add one DU info SEI, if enabled
957  for (Int i=1; i<duData.size(); i++)
958  {
959    if (m_pcCfg->getDecodingUnitInfoSEIEnabled())
960    {
961      numNalUnits  += 1;
962      numRBSPBytes += ( 5 << 3 );
963    }
964    duData[i].accumBitsDU += numRBSPBytes; // probably around 5 bytes
965    duData[i].accumNalsDU += numNalUnits;
966  }
967
968  // The last DU may have a trailing SEI
969  if (m_pcCfg->getDecodedPictureHashSEIType()!=HASHTYPE_NONE)
970  {
971    duData.back().accumBitsDU += ( 20 << 3 ); // probably around 20 bytes - should be further adjusted, e.g. by type
972    duData.back().accumNalsDU += 1;
973  }
974
975}
976Void TEncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUData> &duData, const TComSPS *sps)
977{
978  if (!pictureTimingSEI)
979  {
980    return;
981  }
982  const TComVUI *vui = sps->getVuiParameters();
983  const TComHRD *hrd = vui->getHrdParameters();
984  if( hrd->getSubPicCpbParamsPresentFlag() )
985  {
986    Int i;
987    UInt64 ui64Tmp;
988    UInt uiPrev = 0;
989    UInt numDU = ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 );
990    std::vector<UInt> &rDuCpbRemovalDelayMinus1 = pictureTimingSEI->m_duCpbRemovalDelayMinus1;
991    UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
992
993    for( i = 0; i < numDU; i ++ )
994    {
995      pictureTimingSEI->m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( duData[i].accumNalsDU - 1 ) : ( duData[i].accumNalsDU- duData[i-1].accumNalsDU - 1 );
996    }
997
998    if( numDU == 1 )
999    {
1000      rDuCpbRemovalDelayMinus1[ 0 ] = 0; /* don't care */
1001    }
1002    else
1003    {
1004      rDuCpbRemovalDelayMinus1[ numDU - 1 ] = 0;/* by definition */
1005      UInt tmp = 0;
1006      UInt accum = 0;
1007
1008      for( i = ( numDU - 2 ); i >= 0; i -- )
1009      {
1010        ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
1011        if( (UInt)ui64Tmp > maxDiff )
1012        {
1013          tmp ++;
1014        }
1015      }
1016      uiPrev = 0;
1017
1018      UInt flag = 0;
1019      for( i = ( numDU - 2 ); i >= 0; i -- )
1020      {
1021        flag = 0;
1022        ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
1023
1024        if( (UInt)ui64Tmp > maxDiff )
1025        {
1026          if(uiPrev >= maxDiff - tmp)
1027          {
1028            ui64Tmp = uiPrev + 1;
1029            flag = 1;
1030          }
1031          else                            ui64Tmp = maxDiff - tmp + 1;
1032        }
1033        rDuCpbRemovalDelayMinus1[ i ] = (UInt)ui64Tmp - uiPrev - 1;
1034        if( (Int)rDuCpbRemovalDelayMinus1[ i ] < 0 )
1035        {
1036          rDuCpbRemovalDelayMinus1[ i ] = 0;
1037        }
1038        else if (tmp > 0 && flag == 1)
1039        {
1040          tmp --;
1041        }
1042        accum += rDuCpbRemovalDelayMinus1[ i ] + 1;
1043        uiPrev = accum;
1044      }
1045    }
1046  }
1047}
1048Void TEncGOP::xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI)
1049{
1050  if (duInfoSeiMessages.empty() || (pictureTimingSEI == NULL))
1051  {
1052    return;
1053  }
1054
1055  Int i=0;
1056
1057  for (SEIMessages::iterator du = duInfoSeiMessages.begin(); du!= duInfoSeiMessages.end(); du++)
1058  {
1059    SEIDecodingUnitInfo *duInfoSEI = (SEIDecodingUnitInfo*) (*du);
1060    duInfoSEI->m_decodingUnitIdx = i;
1061    duInfoSEI->m_duSptCpbRemovalDelay = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i] + 1;
1062    duInfoSEI->m_dpbOutputDuDelayPresentFlag = false;
1063    i++;
1064  }
1065}
1066
1067static Void
1068cabac_zero_word_padding(TComSlice *const pcSlice, TComPic *const pcPic, const std::size_t binCountsInNalUnits, const std::size_t numBytesInVclNalUnits, std::ostringstream &nalUnitData, const Bool cabacZeroWordPaddingEnabled)
1069{
1070  const TComSPS &sps=*(pcSlice->getSPS());
1071  const Int log2subWidthCxsubHeightC = (pcPic->getComponentScaleX(COMPONENT_Cb)+pcPic->getComponentScaleY(COMPONENT_Cb));
1072  const Int minCuWidth  = pcPic->getMinCUWidth();
1073  const Int minCuHeight = pcPic->getMinCUHeight();
1074  const Int paddedWidth = ((sps.getPicWidthInLumaSamples()  + minCuWidth  - 1) / minCuWidth) * minCuWidth;
1075  const Int paddedHeight= ((sps.getPicHeightInLumaSamples() + minCuHeight - 1) / minCuHeight) * minCuHeight;
1076  const Int rawBits = paddedWidth * paddedHeight *
1077                         (sps.getBitDepth(CHANNEL_TYPE_LUMA) + 2*(sps.getBitDepth(CHANNEL_TYPE_CHROMA)>>log2subWidthCxsubHeightC));
1078  const std::size_t threshold = (32/3)*numBytesInVclNalUnits + (rawBits/32);
1079  if (binCountsInNalUnits >= threshold)
1080  {
1081    // need to add additional cabac zero words (each one accounts for 3 bytes (=00 00 03)) to increase numBytesInVclNalUnits
1082    const std::size_t targetNumBytesInVclNalUnits = ((binCountsInNalUnits - (rawBits/32))*3+31)/32;
1083
1084    if (targetNumBytesInVclNalUnits>numBytesInVclNalUnits) // It should be!
1085    {
1086      const std::size_t numberOfAdditionalBytesNeeded=targetNumBytesInVclNalUnits - numBytesInVclNalUnits;
1087      const std::size_t numberOfAdditionalCabacZeroWords=(numberOfAdditionalBytesNeeded+2)/3;
1088      const std::size_t numberOfAdditionalCabacZeroBytes=numberOfAdditionalCabacZeroWords*3;
1089      if (cabacZeroWordPaddingEnabled)
1090      {
1091        std::vector<UChar> zeroBytesPadding(numberOfAdditionalCabacZeroBytes, UChar(0));
1092        for(std::size_t i=0; i<numberOfAdditionalCabacZeroWords; i++)
1093        {
1094          zeroBytesPadding[i*3+2]=3;  // 00 00 03
1095        }
1096        nalUnitData.write(reinterpret_cast<const TChar*>(&(zeroBytesPadding[0])), numberOfAdditionalCabacZeroBytes);
1097        printf("Adding %d bytes of padding\n", UInt(numberOfAdditionalCabacZeroWords*3));
1098      }
1099      else
1100      {
1101        printf("Standard would normally require adding %d bytes of padding\n", UInt(numberOfAdditionalCabacZeroWords*3));
1102      }
1103    }
1104  }
1105}
1106
1107class EfficientFieldIRAPMapping
1108{
1109  private:
1110    Int  IRAPGOPid;
1111    Bool IRAPtoReorder;
1112    Bool swapIRAPForward;
1113
1114  public:
1115    EfficientFieldIRAPMapping() :
1116      IRAPGOPid(-1),
1117      IRAPtoReorder(false),
1118      swapIRAPForward(false)
1119    { }
1120
1121#if SVC_EXTENSION
1122    Void initialize(const Bool isField, const Int picIdInGOP, const Int gopSize, const Int POCLast, const Int numPicRcvd, const Int lastIDR, TEncGOP *pEncGop, TEncCfg *pCfg);
1123#else
1124    Void initialize(const Bool isField, const Int gopSize, const Int POCLast, const Int numPicRcvd, const Int lastIDR, TEncGOP *pEncGop, TEncCfg *pCfg);
1125#endif
1126
1127    Int adjustGOPid(const Int gopID);
1128    Int restoreGOPid(const Int gopID);
1129    Int GetIRAPGOPid() const { return IRAPGOPid; }
1130};
1131
1132#if SVC_EXTENSION
1133Void EfficientFieldIRAPMapping::initialize(const Bool isField, const Int picIdInGOP, const Int gopSize, const Int POCLast, const Int numPicRcvd, const Int lastIDR, TEncGOP *pEncGop, TEncCfg *pCfg )
1134#else
1135Void EfficientFieldIRAPMapping::initialize(const Bool isField, const Int gopSize, const Int POCLast, const Int numPicRcvd, const Int lastIDR, TEncGOP *pEncGop, TEncCfg *pCfg )
1136#endif
1137{
1138  if(isField)
1139  {
1140    Int pocCurr;
1141#if SVC_EXTENSION
1142    for ( Int iGOPid=picIdInGOP; iGOPid < picIdInGOP+1; iGOPid++ )
1143#else
1144    for ( Int iGOPid=0; iGOPid < gopSize; iGOPid++ )
1145#endif   
1146    {
1147      // determine actual POC
1148      if(POCLast == 0) //case first frame or first top field
1149      {
1150        pocCurr=0;
1151      }
1152      else if(POCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
1153      {
1154        pocCurr = 1;
1155      }
1156      else
1157      {
1158        pocCurr = POCLast - numPicRcvd + pCfg->getGOPEntry(iGOPid).m_POC - isField;
1159      }
1160
1161      // check if POC corresponds to IRAP
1162      NalUnitType tmpUnitType = pEncGop->getNalUnitType(pocCurr, lastIDR, isField);
1163      if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP
1164      {
1165        if(pocCurr%2 == 0 && iGOPid < gopSize-1 && pCfg->getGOPEntry(iGOPid).m_POC == pCfg->getGOPEntry(iGOPid+1).m_POC-1)
1166        { // if top field and following picture in enc order is associated bottom field
1167          IRAPGOPid = iGOPid;
1168          IRAPtoReorder = true;
1169          swapIRAPForward = true; 
1170          break;
1171        }
1172        if(pocCurr%2 != 0 && iGOPid > 0 && pCfg->getGOPEntry(iGOPid).m_POC == pCfg->getGOPEntry(iGOPid-1).m_POC+1)
1173        {
1174          // if picture is an IRAP remember to process it first
1175          IRAPGOPid = iGOPid;
1176          IRAPtoReorder = true;
1177          swapIRAPForward = false; 
1178          break;
1179        }
1180      }
1181    }
1182  }
1183}
1184
1185Int EfficientFieldIRAPMapping::adjustGOPid(const Int GOPid)
1186{
1187  if(IRAPtoReorder)
1188  {
1189    if(swapIRAPForward)
1190    {
1191      if(GOPid == IRAPGOPid)
1192      {
1193        return IRAPGOPid +1;
1194      }
1195      else if(GOPid == IRAPGOPid +1)
1196      {
1197        return IRAPGOPid;
1198      }
1199    }
1200    else
1201    {
1202      if(GOPid == IRAPGOPid -1)
1203      {
1204        return IRAPGOPid;
1205      }
1206      else if(GOPid == IRAPGOPid)
1207      {
1208        return IRAPGOPid -1;
1209      }
1210    }
1211  }
1212  return GOPid;
1213}
1214
1215Int EfficientFieldIRAPMapping::restoreGOPid(const Int GOPid)
1216{
1217  if(IRAPtoReorder)
1218  {
1219    if(swapIRAPForward)
1220    {
1221      if(GOPid == IRAPGOPid)
1222      {
1223        IRAPtoReorder = false;
1224        return IRAPGOPid +1;
1225      }
1226      else if(GOPid == IRAPGOPid +1)
1227      {
1228        return GOPid -1;
1229      }
1230    }
1231    else
1232    {
1233      if(GOPid == IRAPGOPid)
1234      {
1235        return IRAPGOPid -1;
1236      }
1237      else if(GOPid == IRAPGOPid -1)
1238      {
1239        IRAPtoReorder = false;
1240        return IRAPGOPid;
1241      }
1242    }
1243  }
1244  return GOPid;
1245}
1246
1247
1248static UInt calculateCollocatedFromL1Flag(TEncCfg *pCfg, const Int GOPid, const Int gopSize)
1249{
1250  Int iCloseLeft=1, iCloseRight=-1;
1251  for(Int i = 0; i<pCfg->getGOPEntry(GOPid).m_numRefPics; i++)
1252  {
1253    Int iRef = pCfg->getGOPEntry(GOPid).m_referencePics[i];
1254    if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
1255    {
1256      iCloseRight=iRef;
1257    }
1258    else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
1259    {
1260      iCloseLeft=iRef;
1261    }
1262  }
1263  if(iCloseRight>-1)
1264  {
1265    iCloseRight=iCloseRight+pCfg->getGOPEntry(GOPid).m_POC-1;
1266  }
1267  if(iCloseLeft<1)
1268  {
1269    iCloseLeft=iCloseLeft+pCfg->getGOPEntry(GOPid).m_POC-1;
1270    while(iCloseLeft<0)
1271    {
1272      iCloseLeft+=gopSize;
1273    }
1274  }
1275  Int iLeftQP=0, iRightQP=0;
1276  for(Int i=0; i<gopSize; i++)
1277  {
1278    if(pCfg->getGOPEntry(i).m_POC==(iCloseLeft%gopSize)+1)
1279    {
1280      iLeftQP= pCfg->getGOPEntry(i).m_QPOffset;
1281    }
1282    if (pCfg->getGOPEntry(i).m_POC==(iCloseRight%gopSize)+1)
1283    {
1284      iRightQP=pCfg->getGOPEntry(i).m_QPOffset;
1285    }
1286  }
1287  if(iCloseRight>-1&&iRightQP<iLeftQP)
1288  {
1289    return 0;
1290  }
1291  else
1292  {
1293    return 1;
1294  }
1295}
1296
1297
1298static Void
1299printHash(const HashType hashType, const std::string &digestStr)
1300{
1301  const TChar *decodedPictureHashModeName;
1302  switch (hashType)
1303  {
1304    case HASHTYPE_MD5:
1305      decodedPictureHashModeName = "MD5";
1306      break;
1307    case HASHTYPE_CRC:
1308      decodedPictureHashModeName = "CRC";
1309      break;
1310    case HASHTYPE_CHECKSUM:
1311      decodedPictureHashModeName = "Checksum";
1312      break;
1313    default:
1314      decodedPictureHashModeName = NULL;
1315      break;
1316  }
1317  if (decodedPictureHashModeName != NULL)
1318  {
1319    if (digestStr.empty())
1320    {
1321      printf(" [%s:%s]", decodedPictureHashModeName, "?");
1322    }
1323    else
1324    {
1325      printf(" [%s:%s]", decodedPictureHashModeName, digestStr.c_str());
1326    }
1327  }
1328}
1329
1330// ====================================================================================================================
1331// Public member functions
1332// ====================================================================================================================
1333#if SVC_EXTENSION
1334Void TEncGOP::compressGOP( Int iPicIdInGOP, Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,
1335#else
1336Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,
1337#endif
1338                           TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP,
1339                           Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
1340
1341{
1342  // TODO: Split this function up.
1343
1344  TComPic*        pcPic = NULL;
1345  TComPicYuv*     pcPicYuvRecOut;
1346  TComSlice*      pcSlice;
1347  TComOutputBitstream  *pcBitstreamRedirect;
1348  pcBitstreamRedirect = new TComOutputBitstream;
1349  AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
1350
1351  xInitGOP( iPOCLast, iNumPicRcvd, isField );
1352
1353  m_iNumPicCoded = 0;
1354  SEIMessages leadingSeiMessages;
1355  SEIMessages nestedSeiMessages;
1356  SEIMessages duInfoSeiMessages;
1357  SEIMessages trailingSeiMessages;
1358  std::deque<DUData> duData;
1359  SEIDecodingUnitInfo decodingUnitInfoSEI;
1360
1361  EfficientFieldIRAPMapping effFieldIRAPMap;
1362  if (m_pcCfg->getEfficientFieldIRAPEnabled())
1363  {
1364#if SVC_EXTENSION
1365    effFieldIRAPMap.initialize(isField, iPicIdInGOP, m_iGopSize, iPOCLast, iNumPicRcvd, m_iLastIDR, this, m_pcCfg);
1366#else
1367    effFieldIRAPMap.initialize(isField, m_iGopSize, iPOCLast, iNumPicRcvd, m_iLastIDR, this, m_pcCfg);
1368#endif
1369  }
1370
1371  // reset flag indicating whether pictures have been encoded
1372  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
1373  {
1374    m_pcCfg->setEncodedFlag(iGOPid, false);
1375  }
1376#if SVC_EXTENSION
1377  for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
1378#else
1379  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
1380#endif
1381  {
1382    if (m_pcCfg->getEfficientFieldIRAPEnabled())
1383    {
1384      iGOPid=effFieldIRAPMap.adjustGOPid(iGOPid);
1385    }
1386
1387    //-- For time output for each slice
1388    clock_t iBeforeTime = clock();
1389
1390    UInt uiColDir = calculateCollocatedFromL1Flag(m_pcCfg, iGOPid, m_iGopSize);
1391
1392    /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
1393    Int iTimeOffset;
1394    Int pocCurr;
1395
1396    if(iPOCLast == 0) //case first frame or first top field
1397    {
1398      pocCurr=0;
1399      iTimeOffset = 1;
1400    }
1401    else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
1402    {
1403      pocCurr = 1;
1404      iTimeOffset = 1;
1405    }
1406    else
1407    {
1408      pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - ((isField && m_iGopSize>1) ? 1:0);
1409      iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
1410    }
1411
1412    if(pocCurr>=m_pcCfg->getFramesToBeEncoded())
1413    {
1414      if (m_pcCfg->getEfficientFieldIRAPEnabled())
1415      {
1416        iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
1417      }
1418      continue;
1419    }
1420
1421#if SVC_EXTENSION
1422    if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && ((m_layerId > 0 && pocCurr < m_pcEncTop->getAdaptiveResolutionChange()) ||
1423                                                          (m_layerId == 0 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange())) )
1424    {
1425      continue;
1426    }
1427
1428    if (pocCurr > m_pcEncTop->getLayerSwitchOffBegin() && pocCurr < m_pcEncTop->getLayerSwitchOffEnd())
1429    {
1430      continue;
1431    }
1432#endif
1433
1434    if( getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
1435    {
1436      m_iLastIDR = pocCurr;
1437    }
1438    // start a new access unit: create an entry in the list of output access units
1439    accessUnitsInGOP.push_back(AccessUnit());
1440    AccessUnit& accessUnit = accessUnitsInGOP.back();
1441    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField );
1442
1443    //  Slice data initialization
1444    pcPic->clearSliceBuffer();
1445    pcPic->allocateNewSlice();
1446    m_pcSliceEncoder->setSliceIdx(0);
1447    pcPic->setCurrSliceIdx(0);
1448
1449#if SVC_EXTENSION
1450    pcPic->setLayerId( m_layerId );
1451#endif
1452
1453    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField );
1454
1455    //Set Frame/Field coding
1456    pcSlice->getPic()->setField(isField);
1457
1458#if SVC_EXTENSION
1459#if SVC_POC
1460    pcSlice->setPocValueBeforeReset( pocCurr );
1461    // Check if the current picture is to be assigned as a reset picture
1462    determinePocResetIdc(pocCurr, pcSlice);
1463
1464    Bool pocResettingFlag = false;
1465
1466    if( pcSlice->getPocResetIdc() != 0 )
1467    {
1468      if( pcSlice->getVPS()->getVpsPocLsbAlignedFlag() )
1469      {
1470        pocResettingFlag = true;
1471      }
1472      else if( m_pcEncTop->getPocDecrementedInDPBFlag() )
1473      {
1474        pocResettingFlag = false;
1475      }
1476      else
1477      {
1478        pocResettingFlag = true;
1479      }
1480    }
1481
1482    // If reset, do the following steps:
1483    if( pocResettingFlag )
1484    {
1485      updatePocValuesOfPics(pocCurr, pcSlice);
1486    }
1487    else
1488    {
1489      // Check the base layer picture is IDR. If so, just set current POC equal to 0 (alignment of POC)
1490      if( ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2) && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 ) )       
1491      {
1492        m_pcEncTop->setPocAdjustmentValue( pocCurr );
1493      }
1494
1495      // Just subtract POC by the current cumulative POC delta
1496      pcSlice->setPOC( pocCurr - m_pcEncTop->getPocAdjustmentValue() );
1497
1498      Int maxPocLsb = 1 << pcSlice->getSPS()->getBitsForPOC();
1499      pcSlice->setPocMsbVal( pcSlice->getPOC() - ( pcSlice->getPOC() & (maxPocLsb-1) ) );
1500    }
1501    // Update the POC of current picture, pictures in the DPB, including references inside the reference pictures
1502#endif
1503
1504    if( m_layerId == 0 && (getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP) )
1505    {
1506      pcSlice->setCrossLayerBLAFlag(m_pcEncTop->getCrossLayerBLAFlag());
1507    }
1508    else
1509    {
1510      pcSlice->setCrossLayerBLAFlag(false);
1511    }
1512
1513    // Set the nal unit type
1514    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
1515
1516#if NO_CLRAS_OUTPUT_FLAG
1517    if (m_layerId == 0 &&
1518        (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1519      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1520      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1521      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1522      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1523      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA))
1524    {
1525      if (m_bFirst)
1526      {
1527        m_pcEncTop->setNoClrasOutputFlag(true);
1528      }
1529      else if (m_prevPicHasEos)
1530      {
1531        m_pcEncTop->setNoClrasOutputFlag(true);
1532      }
1533      else if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1534            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1535            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP)
1536      {
1537        m_pcEncTop->setNoClrasOutputFlag(true);
1538      }
1539      else if( pcSlice->getCrossLayerBLAFlag() && ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP ) )
1540      {
1541        m_pcEncTop->setNoClrasOutputFlag(true);
1542      }
1543      else
1544      {
1545        m_pcEncTop->setNoClrasOutputFlag(false);
1546      }
1547
1548      if( m_pcEncTop->getNoClrasOutputFlag() )
1549      {
1550        for (UInt i = 0; i < m_pcCfg->getNumLayer(); i++)
1551        {
1552          m_ppcTEncTop[i]->setLayerInitializedFlag(false);
1553          m_ppcTEncTop[i]->setFirstPicInLayerDecodedFlag(false);
1554        }
1555      }
1556    }
1557#endif
1558    xCheckLayerReset(pcSlice);
1559    xSetNoRaslOutputFlag(pcSlice);
1560    xSetLayerInitializedFlag(pcSlice);
1561
1562    if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && m_layerId > 0 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange())
1563    {
1564      pcSlice->setActiveNumILRRefIdx(0);
1565      pcSlice->setInterLayerPredEnabledFlag(false);
1566      pcSlice->setMFMEnabledFlag(false);
1567    }
1568#endif //SVC_EXTENSION
1569
1570    pcSlice->setLastIDR(m_iLastIDR);
1571    pcSlice->setSliceIdx(0);
1572    //set default slice level flag to the same as SPS level flag
1573    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
1574
1575    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
1576    {
1577      pcSlice->setSliceType(P_SLICE);
1578    }
1579    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I')
1580    {
1581      pcSlice->setSliceType(I_SLICE);
1582    }
1583   
1584#if SVC_EXTENSION
1585    if (m_layerId > 0)
1586    {
1587      if( pcSlice->getSliceIdx() == 0 )
1588      {
1589        // create buffers for scaling factors
1590        if( pcSlice->getNumILRRefIdx() )
1591        {
1592          pcSlice->getPic()->createMvScalingFactor(pcSlice->getNumILRRefIdx());
1593          pcSlice->getPic()->createPosScalingFactor(pcSlice->getNumILRRefIdx());
1594        }
1595      }
1596
1597      Int interLayerPredLayerIdcTmp[MAX_VPS_LAYER_IDX_PLUS1];
1598      Int activeNumILRRefIdxTmp = 0;
1599
1600      for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
1601      {
1602        UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
1603        UInt refLayerId = pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc);
1604        TComList<TComPic*> *cListPic = m_ppcTEncTop[pcSlice->getVPS()->getLayerIdxInVps(m_layerId)]->getRefLayerEnc(refLayerIdc)->getListPic();
1605
1606        pcSlice->setBaseColPic( *cListPic, refLayerIdc );
1607
1608        // Apply temporal layer restriction to inter-layer prediction
1609        Int maxTidIlRefPicsPlus1 = m_pcEncTop->getVPS()->getMaxTidIlRefPicsPlus1(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getLayerIdx(), pcSlice->getLayerIdx());
1610        if( ((Int)(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getTLayer())<=maxTidIlRefPicsPlus1-1) || (maxTidIlRefPicsPlus1==0 && pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getRapPicFlag()) )
1611        {
1612          interLayerPredLayerIdcTmp[activeNumILRRefIdxTmp++] = refLayerIdc; // add picture to the list of valid inter-layer pictures
1613        }
1614        else
1615        {
1616          continue; // ILP is not valid due to temporal layer restriction
1617        }
1618
1619        const Window &scalEL = m_pcEncTop->getScaledRefLayerWindowForLayer(refLayerId);
1620        const Window &windowRL = m_pcEncTop->getRefLayerWindowForLayer(pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc));
1621        Int widthBL   = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getWidth(COMPONENT_Y) - windowRL.getWindowLeftOffset() - windowRL.getWindowRightOffset();
1622        Int heightBL  = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getHeight(COMPONENT_Y) - windowRL.getWindowTopOffset() - windowRL.getWindowBottomOffset();
1623        Int widthEL   = pcPic->getPicYuvRec()->getWidth(COMPONENT_Y)  - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset();
1624        Int heightEL  = pcPic->getPicYuvRec()->getHeight(COMPONENT_Y) - scalEL.getWindowTopOffset()  - scalEL.getWindowBottomOffset();
1625
1626        // conformance check: the values of RefLayerRegionWidthInSamplesY, RefLayerRegionHeightInSamplesY, ScaledRefRegionWidthInSamplesY and ScaledRefRegionHeightInSamplesY shall be greater than 0
1627        assert(widthEL > 0 && heightEL > 0 && widthBL > 0 && widthEL > 0);
1628
1629        // conformance check: ScaledRefRegionWidthInSamplesY shall be greater or equal to RefLayerRegionWidthInSamplesY and ScaledRefRegionHeightInSamplesY shall be greater or equal to RefLayerRegionHeightInSamplesY
1630        assert(widthEL >= widthBL && heightEL >= heightBL);
1631
1632        // conformance check: when ScaledRefRegionWidthInSamplesY is equal to RefLayerRegionWidthInSamplesY, PhaseHorY shall be equal to 0, when ScaledRefRegionWidthInSamplesC is equal to RefLayerRegionWidthInSamplesC, PhaseHorC shall be equal to 0, when ScaledRefRegionHeightInSamplesY is equal to RefLayerRegionHeightInSamplesY, PhaseVerY shall be equal to 0, and when ScaledRefRegionHeightInSamplesC is equal to RefLayerRegionHeightInSamplesC, PhaseVerC shall be equal to 0.
1633        const ResamplingPhase &resamplingPhase = pcSlice->getPPS()->getResamplingPhase( refLayerId );
1634
1635        assert( ( (widthEL  != widthBL)  || (resamplingPhase.phaseHorLuma == 0 && resamplingPhase.phaseHorChroma == 0) )
1636             && ( (heightEL != heightBL) || (resamplingPhase.phaseVerLuma == 0 && resamplingPhase.phaseVerChroma == 0) ) );
1637
1638        pcSlice->getPic()->setMvScalingFactor( refLayerIdc,
1639                                               widthEL  == widthBL  ? MV_SCALING_FACTOR_1X : Clip3(-4096, 4095, ((widthEL  << 8) + (widthBL  >> 1)) / widthBL),
1640                                               heightEL == heightBL ? MV_SCALING_FACTOR_1X : Clip3(-4096, 4095, ((heightEL << 8) + (heightBL >> 1)) / heightBL) );
1641
1642        pcSlice->getPic()->setPosScalingFactor( refLayerIdc, 
1643                                                ((widthBL  << 16) + (widthEL  >> 1)) / widthEL,
1644                                                ((heightBL << 16) + (heightEL >> 1)) / heightEL );
1645
1646#if CGS_3D_ASYMLUT
1647        TComPicYuv* pBaseColRec = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
1648        if( pcSlice->getPPS()->getCGSFlag() )
1649        {
1650          // all reference layers are currently taken as CGS reference layers
1651          m_Enc3DAsymLUTPPS.addRefLayerId( pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc) );
1652          m_Enc3DAsymLUTPicUpdate.addRefLayerId( pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc) );
1653
1654          if( pcSlice->getPic()->getPosScalingFactor(refLayerIdc, 0) < POS_SCALING_FACTOR_1X || pcSlice->getPic()->getPosScalingFactor(refLayerIdc, 1) < POS_SCALING_FACTOR_1X ) //if(pcPic->isSpatialEnhLayer(refLayerIdc))
1655          {
1656            //downsampling
1657            xDownScalePic(pcPic->getPicYuvOrg(), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg(), pcSlice->getSPS()->getBitDepths(), pcPic->getPosScalingFactor(refLayerIdc, 0));
1658           
1659            m_Enc3DAsymLUTPPS.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1660            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1661          }
1662          else
1663          {
1664            m_Enc3DAsymLUTPPS.setDsOrigPic(pcPic->getPicYuvOrg());
1665            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcPic->getPicYuvOrg());
1666          }
1667
1668          Bool bSignalPPS = m_bSeqFirst;
1669          bSignalPPS |= m_pcCfg->getGOPSize() > 1 ? pocCurr % m_pcCfg->getIntraPeriod() == 0 : pocCurr % m_pcCfg->getFrameRate() == 0;
1670          xDetermine3DAsymLUT( pcSlice, pcPic, refLayerIdc, m_pcCfg, bSignalPPS );
1671
1672          // update PPS in TEncTop and TComPicSym classes
1673          m_pcEncTop->getPPS()->setCGSOutputBitDepthY( m_Enc3DAsymLUTPPS.getOutputBitDepthY() );
1674          m_pcEncTop->getPPS()->setCGSOutputBitDepthC( m_Enc3DAsymLUTPPS.getOutputBitDepthC() );
1675          pcPic->getPicSym()->getPPSToUpdate()->setCGSOutputBitDepthY( m_Enc3DAsymLUTPPS.getOutputBitDepthY() );
1676          pcPic->getPicSym()->getPPSToUpdate()->setCGSOutputBitDepthC( m_Enc3DAsymLUTPPS.getOutputBitDepthC() );
1677
1678          m_Enc3DAsymLUTPPS.colorMapping( pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(),  m_pColorMappedPic );
1679          pBaseColRec = m_pColorMappedPic;
1680        }
1681#endif
1682
1683        if( pcPic->isSpatialEnhLayer(refLayerIdc) )
1684        {
1685          // check for the sample prediction picture type
1686          if( pcSlice->getVPS()->isSamplePredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), pcSlice->getVPS()->getLayerIdxInVps(refLayerId) ) )
1687          {
1688            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA), pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) );
1689          }
1690        }
1691        else
1692        {
1693#if CGS_3D_ASYMLUT
1694          pcPic->setFullPelBaseRec( refLayerIdc, pBaseColRec );
1695#else
1696          pcPic->setFullPelBaseRec( refLayerIdc, pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec() );
1697#endif
1698        }
1699        pcSlice->setFullPelBaseRec ( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc) );
1700      }
1701
1702      // Update the list of active inter-layer pictures
1703      for ( Int i = 0; i < activeNumILRRefIdxTmp; i++)
1704      {
1705        pcSlice->setInterLayerPredLayerIdc( interLayerPredLayerIdcTmp[i], i );
1706      }
1707
1708      pcSlice->setActiveNumILRRefIdx( activeNumILRRefIdxTmp );
1709
1710      if ( pcSlice->getActiveNumILRRefIdx() == 0 )
1711      {
1712        // No valid inter-layer pictures -> disable inter-layer prediction
1713        pcSlice->setInterLayerPredEnabledFlag(false);
1714      }
1715
1716      if( pocCurr % m_pcCfg->getIntraPeriod() == 0 )
1717      {
1718        if(pcSlice->getVPS()->getCrossLayerIrapAlignFlag())
1719        {
1720          TComList<TComPic*> *cListPic = m_ppcTEncTop[pcSlice->getVPS()->getLayerIdxInVps(m_layerId)]->getRefLayerEnc(0)->getListPic();
1721          TComPic* picLayer0 = pcSlice->getRefPic(*cListPic, pcSlice->getPOC() );
1722          if(picLayer0)
1723          {
1724            pcSlice->setNalUnitType(picLayer0->getSlice(0)->getNalUnitType());
1725          }
1726          else
1727          {
1728            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA);
1729          }
1730        }       
1731      }
1732
1733      if( pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
1734      {
1735        if( pcSlice->getActiveNumILRRefIdx() == 0 && m_pcEncTop->getNumDirectRefLayers() == 0 )
1736        {
1737          pcSlice->setSliceType(I_SLICE);
1738        }
1739        else if( !m_pcEncTop->getElRapSliceTypeB() && pcSlice->getSliceType() == B_SLICE )
1740        {
1741          pcSlice->setSliceType(P_SLICE);
1742        }
1743      }
1744    }
1745#else
1746    // Set the nal unit type
1747    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
1748#endif //#if SVC_EXTENSION
1749
1750    if(pcSlice->getTemporalLayerNonReferenceFlag())
1751    {
1752      if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_TRAIL_R &&
1753#if SVC_EXTENSION
1754        ( m_iGopSize != 1 || m_ppcTEncTop[pcSlice->getVPS()->getLayerIdxInVps(m_layerId)]->getIntraPeriod() > 1 ) )
1755#else
1756          !(m_iGopSize == 1 && pcSlice->getSliceType() == I_SLICE))
1757#endif
1758        // Add this condition to avoid POC issues with encoder_intra_main.cfg configuration (see #1127 in bug tracker)
1759      {
1760        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TRAIL_N);
1761      }
1762      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RADL_R)
1763      {
1764        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RADL_N);
1765      }
1766      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RASL_R)
1767      {
1768        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RASL_N);
1769      }
1770    }
1771
1772    if (m_pcCfg->getEfficientFieldIRAPEnabled())
1773    {
1774      if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1775        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1776        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1777        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1778        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1779        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
1780      {
1781        m_associatedIRAPType = pcSlice->getNalUnitType();
1782#if SVC_POC
1783        m_associatedIRAPPOC = pcSlice->getPOC();
1784        m_associatedIrapPocBeforeReset = pocCurr;
1785#else
1786        m_associatedIRAPPOC = pocCurr;
1787#endif
1788      }
1789      pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
1790      pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
1791#if SVC_POC
1792      pcSlice->setAssociatedIrapPocBeforeReset(m_associatedIrapPocBeforeReset);
1793#endif
1794    }
1795    // Do decoding refresh marking if any
1796#if NO_CLRAS_OUTPUT_FLAG
1797    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcCfg->getEfficientFieldIRAPEnabled(), m_pcEncTop->getNoClrasOutputFlag());
1798#else
1799    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcCfg->getEfficientFieldIRAPEnabled());
1800#endif
1801#if SVC_POC
1802    // m_pocCRA may have been update here; update m_pocCraWithoutReset
1803    m_pocCraWithoutReset = m_pocCRA + m_pcEncTop->getPocAdjustmentValue();
1804#endif
1805    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
1806    if (!m_pcCfg->getEfficientFieldIRAPEnabled())
1807    {
1808      if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1809        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1810        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1811        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1812        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1813        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
1814      {
1815        m_associatedIRAPType = pcSlice->getNalUnitType();
1816        m_associatedIRAPPOC = pocCurr;
1817      }
1818      pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
1819      pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
1820    }
1821
1822    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) 
1823      || (m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)
1824      )
1825    {
1826      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3, m_pcCfg->getEfficientFieldIRAPEnabled());
1827    }
1828
1829#if ALIGNED_BUMPING
1830    pcSlice->checkLeadingPictureRestrictions(rcListPic, true);
1831#endif
1832    pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
1833
1834    if(pcSlice->getTLayer() > 0 
1835      &&  !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     // Check if not a leading picture
1836          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
1837          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
1838          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R )
1839        )
1840    {
1841      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag())
1842      {
1843        if(pcSlice->getTemporalLayerNonReferenceFlag())
1844        {
1845          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1846        }
1847        else
1848        {
1849          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R);
1850        }
1851      }
1852      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
1853      {
1854        Bool isSTSA=true;
1855        for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
1856        {
1857          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
1858          if(lTid==pcSlice->getTLayer())
1859          {
1860            const TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
1861            for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
1862            {
1863              if(nRPS->getUsed(jj))
1864              {
1865                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
1866                Int kk=0;
1867                for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
1868                {
1869                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
1870                  {
1871                    break;
1872                  }
1873                }
1874                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
1875                if(tTid >= pcSlice->getTLayer())
1876                {
1877                  isSTSA=false;
1878                  break;
1879                }
1880              }
1881            }
1882          }
1883        }
1884        if(isSTSA==true)
1885        {
1886          if(pcSlice->getTemporalLayerNonReferenceFlag())
1887          {
1888            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1889          }
1890          else
1891          {
1892            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
1893          }
1894        }
1895      }
1896    }
1897    arrangeLongtermPicturesInRPS(pcSlice, rcListPic);
1898    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
1899    refPicListModification->setRefPicListModificationFlagL0(0);
1900    refPicListModification->setRefPicListModificationFlagL1(0);
1901    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
1902    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
1903
1904#if SVC_EXTENSION
1905    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
1906    {
1907      if( pocCurr > 0 && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL() )
1908      {
1909        pcSlice->setActiveNumILRRefIdx(0);
1910        pcSlice->setInterLayerPredEnabledFlag(0);
1911      }
1912
1913      if( pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
1914      {
1915        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getActiveNumILRRefIdx());
1916        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getActiveNumILRRefIdx());
1917      }
1918      else
1919      {
1920        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getNumRefIdx(REF_PIC_LIST_0)+pcSlice->getActiveNumILRRefIdx());
1921        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getNumRefIdx(REF_PIC_LIST_1)+pcSlice->getActiveNumILRRefIdx());
1922      }
1923
1924      // check for the reference pictures whether there is at least one either temporal picture or ILRP with sample prediction type
1925      if( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) - pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) - pcSlice->getActiveNumILRRefIdx() == 0 )
1926      {
1927        Bool foundSamplePredPicture = false;               
1928
1929        for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
1930        {
1931          if( pcSlice->getVPS()->isSamplePredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), pcSlice->getInterLayerPredLayerIdc(i) ) )
1932          {
1933            foundSamplePredPicture = true;
1934            break;
1935          }
1936        }
1937
1938        if( !foundSamplePredPicture )
1939        {
1940          pcSlice->setSliceType(I_SLICE);
1941          pcSlice->setInterLayerPredEnabledFlag(0);
1942          pcSlice->setActiveNumILRRefIdx(0);
1943        }
1944      }
1945    }
1946
1947   if( ( pcSlice->getTLayer() == 0 && pcSlice->getLayerId() > 0  )    // only for enhancement layer and with temporal layer 0
1948     && !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     
1949          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
1950          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
1951          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R
1952          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1953          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1954          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA
1955          )
1956        )
1957    {
1958        Bool isSTSA=true;
1959        Bool isIntra=false;
1960
1961        for( Int i = 0; i < pcSlice->getLayerId(); i++)
1962        {
1963          TComList<TComPic *> *cListPic = m_ppcTEncTop[pcSlice->getVPS()->getLayerIdxInVps(i)]->getListPic();
1964          TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC());
1965          if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerIdx(), i) )
1966          {
1967            if( lowerLayerPic->getSlice(0)->getSliceType() == I_SLICE)
1968            { 
1969              isIntra = true;
1970            }
1971          }
1972        }
1973
1974        for(Int ii=iGOPid+1; ii < m_pcCfg->getGOPSize() && isSTSA; ii++)
1975        {
1976          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
1977          if(lTid==pcSlice->getTLayer()) 
1978          {
1979            const TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
1980            for(Int jj=0; jj<nRPS->getNumberOfPictures(); jj++)
1981            {
1982              if(nRPS->getUsed(jj)) 
1983              {
1984                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
1985                Int kk=0;
1986                for(kk=0; kk<m_pcCfg->getGOPSize(); kk++)
1987                {
1988                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
1989                  {
1990                    break;
1991                  }
1992                }
1993                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
1994                if(tTid >= pcSlice->getTLayer())
1995                {
1996                  isSTSA = false;
1997                  break;
1998                }
1999              }
2000            }
2001          }
2002        }
2003        if(isSTSA==true && isIntra == false)
2004        {   
2005          if(pcSlice->getTemporalLayerNonReferenceFlag())
2006          {
2007            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
2008          }
2009          else
2010          {
2011            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
2012          }
2013        }
2014    }
2015
2016    if( pcSlice->getSliceType() == B_SLICE )
2017    {
2018      pcSlice->setColFromL0Flag(1-uiColDir);
2019    }
2020
2021    //  Set reference list
2022    if(m_layerId ==  0 || ( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() == 0 ) )
2023    {
2024      pcSlice->setRefPicList( rcListPic );
2025    }
2026
2027    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
2028    {
2029      pcSlice->setILRPic( m_pcEncTop->getIlpList() );
2030      pcSlice->setRefPicListModificationSvc();
2031      pcSlice->setRefPicList( rcListPic, false, m_pcEncTop->getIlpList());
2032
2033      if( pcSlice->getMFMEnabledFlag() )
2034      {
2035        Bool found         = false;
2036        UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
2037        UInt ColRefIdx     = pcSlice->getColRefIdx();
2038
2039        for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
2040        {
2041          RefPicList refList = RefPicList(1 - ColFromL0Flag);
2042          TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
2043
2044          // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
2045          // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
2046          if( refPic->isILR(m_layerId) && pcSlice->getVPS()->isMotionPredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() )           
2047            && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerIdx()]->getListPic() )->checkSameRefInfo() == true ) 
2048          { 
2049            ColRefIdx = colIdx; 
2050            found = true;
2051            break; 
2052          }
2053        }
2054
2055        if( found == false )
2056        {
2057          ColFromL0Flag = 1 - ColFromL0Flag;
2058          for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
2059          {
2060            RefPicList refList = RefPicList(1 - ColFromL0Flag);
2061            TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
2062
2063            // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
2064            // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
2065            if( refPic->isILR(m_layerId) && pcSlice->getVPS()->isMotionPredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() )
2066              && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerIdx()]->getListPic() )->checkSameRefInfo() == true ) 
2067            { 
2068              ColRefIdx = colIdx; 
2069              found = true; 
2070              break; 
2071            } 
2072          }
2073        }
2074
2075        if(found == true)
2076        {
2077          pcSlice->setColFromL0Flag(ColFromL0Flag);
2078          pcSlice->setColRefIdx(ColRefIdx);
2079        }
2080      }
2081    }
2082#else //SVC_EXTENSION
2083    //  Set reference list
2084    pcSlice->setRefPicList ( rcListPic );
2085#endif //#if SVC_EXTENSION
2086
2087    //  Slice info. refinement
2088    if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
2089    {
2090      pcSlice->setSliceType ( P_SLICE );
2091    }
2092    pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
2093
2094    if (pcSlice->getSliceType() == B_SLICE)
2095    {
2096#if !SVC_EXTENSION
2097      pcSlice->setColFromL0Flag(1-uiColDir);
2098#endif
2099      Bool bLowDelay = true;
2100      Int  iCurrPOC  = pcSlice->getPOC();
2101      Int iRefIdx = 0;
2102
2103      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
2104      {
2105        if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
2106        {
2107          bLowDelay = false;
2108        }
2109      }
2110      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
2111      {
2112        if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
2113        {
2114          bLowDelay = false;
2115        }
2116      }
2117
2118      pcSlice->setCheckLDC(bLowDelay);
2119    }
2120    else
2121    {
2122      pcSlice->setCheckLDC(true);
2123    }
2124
2125    uiColDir = 1-uiColDir;
2126
2127    //-------------------------------------------------------------
2128    pcSlice->setRefPOCList();
2129
2130    pcSlice->setList1IdxToList0Idx();
2131
2132    if (m_pcEncTop->getTMVPModeId() == 2)
2133    {
2134      if (iGOPid == 0) // first picture in SOP (i.e. forward B)
2135      {
2136        pcSlice->setEnableTMVPFlag(0);
2137      }
2138      else
2139      {
2140        // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
2141        pcSlice->setEnableTMVPFlag(1);
2142      }
2143    }
2144    else if (m_pcEncTop->getTMVPModeId() == 1)
2145    {
2146#if SVC_EXTENSION
2147      if( pcSlice->getIdrPicFlag() )
2148      {
2149        pcSlice->setEnableTMVPFlag(0);
2150      }
2151      else
2152#endif
2153      pcSlice->setEnableTMVPFlag(1);
2154    }
2155    else
2156    {
2157      pcSlice->setEnableTMVPFlag(0);
2158    }
2159
2160#if SVC_EXTENSION
2161    if( m_layerId > 0 && !pcSlice->isIntra() )
2162    {
2163      Int colFromL0Flag = 1;
2164      Int colRefIdx = 0;
2165
2166      // check whether collocated picture is valid
2167      if( pcSlice->getEnableTMVPFlag() )
2168      {
2169        colFromL0Flag = pcSlice->getColFromL0Flag();
2170        colRefIdx = pcSlice->getColRefIdx();
2171
2172        TComPic* refPic = pcSlice->getRefPic(RefPicList(1-colFromL0Flag), colRefIdx);
2173
2174        assert( refPic );
2175
2176        // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
2177        // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
2178        if( refPic->isILR(m_layerId) && !pcSlice->getVPS()->isMotionPredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() ) )
2179        {
2180          pcSlice->setEnableTMVPFlag(false);
2181          pcSlice->setMFMEnabledFlag(false);
2182          colRefIdx = 0;
2183        }
2184      }
2185
2186      // remove motion only ILRP from the end of the colFromL0Flag reference picture list
2187      RefPicList refList = RefPicList(colFromL0Flag);
2188      Int numRefIdx = pcSlice->getNumRefIdx(refList);
2189
2190      if( numRefIdx > 0 )
2191      {
2192        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > 0; refIdx-- )
2193        {
2194          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
2195
2196          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && pcSlice->getVPS()->isSamplePredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() ) ) )
2197          {
2198            break;
2199          }
2200          else
2201          {
2202            assert( numRefIdx > 1 );
2203            numRefIdx--;             
2204          }
2205        }
2206
2207        pcSlice->setNumRefIdx( refList, numRefIdx );
2208      }
2209
2210      // remove motion only ILRP from the end of the (1-colFromL0Flag) reference picture list up to colRefIdx
2211      refList = RefPicList(1 - colFromL0Flag);
2212      numRefIdx = pcSlice->getNumRefIdx(refList);
2213
2214      if( numRefIdx > 0 )
2215      {
2216        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > colRefIdx; refIdx-- )
2217        {
2218          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
2219
2220          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && pcSlice->getVPS()->isSamplePredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() ) ) )
2221          {
2222            break;
2223          }
2224          else
2225          {
2226            assert( numRefIdx > 1 );
2227            numRefIdx--;             
2228          }
2229        }
2230
2231        pcSlice->setNumRefIdx( refList, numRefIdx );
2232      }
2233
2234      assert( pcSlice->getNumRefIdx(REF_PIC_LIST_0) > 0 && ( pcSlice->isInterP() || (pcSlice->isInterB() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) > 0) ) );
2235    }
2236#endif
2237
2238    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
2239    // set adaptive search range for non-intra-slices
2240    if (m_pcCfg->getUseASR() && pcSlice->getSliceType()!=I_SLICE)
2241    {
2242      m_pcSliceEncoder->setSearchRange(pcSlice);
2243    }
2244
2245    Bool bGPBcheck=false;
2246    if ( pcSlice->getSliceType() == B_SLICE)
2247    {
2248      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
2249      {
2250        bGPBcheck=true;
2251        Int i;
2252        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
2253        {
2254          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
2255          {
2256            bGPBcheck=false;
2257            break;
2258          }
2259        }
2260      }
2261    }
2262    if(bGPBcheck)
2263    {
2264      pcSlice->setMvdL1ZeroFlag(true);
2265    }
2266    else
2267    {
2268      pcSlice->setMvdL1ZeroFlag(false);
2269    }
2270    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
2271
2272
2273    Double lambda            = 0.0;
2274    Int actualHeadBits       = 0;
2275    Int actualTotalBits      = 0;
2276    Int estimatedBits        = 0;
2277    Int tmpBitsBeforeWriting = 0;
2278    if ( m_pcCfg->getUseRateCtrl() ) // TODO: does this work with multiple slices and slice-segments?
2279    {
2280      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
2281      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
2282      {
2283        frameLevel = 0;
2284      }
2285      m_pcRateCtrl->initRCPic( frameLevel );
2286      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
2287
2288#if U0132_TARGET_BITS_SATURATION
2289      if (m_pcRateCtrl->getCpbSaturationEnabled() && frameLevel != 0)
2290      {
2291        Int estimatedCpbFullness = m_pcRateCtrl->getCpbState() + m_pcRateCtrl->getBufferingRate();
2292
2293        // prevent overflow
2294        if (estimatedCpbFullness - estimatedBits > (Int)(m_pcRateCtrl->getCpbSize()*0.9f))
2295        {
2296          estimatedBits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.9f);
2297        }
2298
2299        estimatedCpbFullness -= m_pcRateCtrl->getBufferingRate();
2300        // prevent underflow
2301        if (estimatedCpbFullness - estimatedBits < (Int)(m_pcRateCtrl->getCpbSize()*0.1f))
2302        {
2303          estimatedBits = max(200, estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.1f));
2304        }
2305
2306        m_pcRateCtrl->getRCPic()->setTargetBits(estimatedBits);
2307      }
2308#endif
2309
2310      Int sliceQP = m_pcCfg->getInitialQP();
2311#if SVC_EXTENSION
2312      if ( ( pocCurr == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
2313#else
2314      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
2315#endif
2316      {
2317        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
2318        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
2319        Double dQPFactor     = 0.57*dLambda_scale;
2320        Int    SHIFT_QP      = 12;
2321        Int    bitdepth_luma_qp_scale = 0;
2322        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
2323        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
2324      }
2325      else if ( frameLevel == 0 )   // intra case, but use the model
2326      {
2327        m_pcSliceEncoder->calCostSliceI(pcPic); // TODO: This only analyses the first slice segment - what about the others?
2328
2329        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
2330        {
2331          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
2332          bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
2333
2334#if U0132_TARGET_BITS_SATURATION
2335          if (m_pcRateCtrl->getCpbSaturationEnabled() )
2336          {
2337            Int estimatedCpbFullness = m_pcRateCtrl->getCpbState() + m_pcRateCtrl->getBufferingRate();
2338
2339            // prevent overflow
2340            if (estimatedCpbFullness - bits > (Int)(m_pcRateCtrl->getCpbSize()*0.9f))
2341            {
2342              bits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.9f);
2343            }
2344
2345            estimatedCpbFullness -= m_pcRateCtrl->getBufferingRate();
2346            // prevent underflow
2347            if (estimatedCpbFullness - bits < (Int)(m_pcRateCtrl->getCpbSize()*0.1f))
2348            {
2349              bits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.1f);
2350            }
2351          }
2352#endif
2353
2354          if ( bits < 200 )
2355          {
2356            bits = 200;
2357          }
2358          m_pcRateCtrl->getRCPic()->setTargetBits( bits );
2359        }
2360
2361        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
2362        m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();
2363        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
2364        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
2365      }
2366      else    // normal case
2367      {
2368        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
2369        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
2370        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
2371      }
2372
2373      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, sliceQP );
2374      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
2375
2376      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
2377    }
2378
2379    UInt uiNumSliceSegments = 1;
2380
2381#if AVC_BASE
2382    if( m_layerId == 0 && m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() )
2383    {
2384      pcPic->getPicYuvOrg()->copyToPic( pcPic->getPicYuvRec() );
2385
2386      // Calculate for the base layer to be used in EL as Inter layer reference
2387      if( m_pcEncTop->getInterLayerWeightedPredFlag() )
2388      {
2389        m_pcSliceEncoder->estimateILWpParam( pcSlice );
2390      }
2391
2392      return;
2393    }
2394#endif
2395
2396    // Allocate some coders, now the number of tiles are known.
2397    const Int numSubstreamsColumns = (pcSlice->getPPS()->getNumTileColumnsMinus1() + 1);
2398    const Int numSubstreamRows     = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->getFrameHeightInCtus() : (pcSlice->getPPS()->getNumTileRowsMinus1() + 1);
2399    const Int numSubstreams        = numSubstreamRows * numSubstreamsColumns;
2400    std::vector<TComOutputBitstream> substreamsOut(numSubstreams);
2401
2402    // now compress (trial encode) the various slice segments (slices, and dependent slices)
2403    {
2404      const UInt numberOfCtusInFrame=pcPic->getPicSym()->getNumberOfCtusInFrame();
2405      pcSlice->setSliceCurStartCtuTsAddr( 0 );
2406      pcSlice->setSliceSegmentCurStartCtuTsAddr( 0 );
2407
2408      for(UInt nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; )
2409      {
2410        m_pcSliceEncoder->precompressSlice( pcPic );
2411        m_pcSliceEncoder->compressSlice   ( pcPic, false, false );
2412
2413        const UInt curSliceSegmentEnd = pcSlice->getSliceSegmentCurEndCtuTsAddr();
2414        if (curSliceSegmentEnd < numberOfCtusInFrame)
2415        {
2416          const Bool bNextSegmentIsDependentSlice=curSliceSegmentEnd<pcSlice->getSliceCurEndCtuTsAddr();
2417          const UInt sliceBits=pcSlice->getSliceBits();
2418          pcPic->allocateNewSlice();
2419          // prepare for next slice
2420          pcPic->setCurrSliceIdx                    ( uiNumSliceSegments );
2421          m_pcSliceEncoder->setSliceIdx             ( uiNumSliceSegments   );
2422          pcSlice = pcPic->getSlice                 ( uiNumSliceSegments   );
2423          assert(pcSlice->getPPS()!=0);
2424          pcSlice->copySliceInfo                    ( pcPic->getSlice(uiNumSliceSegments-1)  );
2425          pcSlice->setSliceIdx                      ( uiNumSliceSegments   );
2426          if (bNextSegmentIsDependentSlice)
2427          {
2428            pcSlice->setSliceBits(sliceBits);
2429          }
2430          else
2431          {
2432            pcSlice->setSliceCurStartCtuTsAddr      ( curSliceSegmentEnd );
2433            pcSlice->setSliceBits(0);
2434          }
2435          pcSlice->setDependentSliceSegmentFlag(bNextSegmentIsDependentSlice);
2436          pcSlice->setSliceSegmentCurStartCtuTsAddr ( curSliceSegmentEnd );
2437          // TODO: optimise cabac_init during compress slice to improve multi-slice operation
2438          // pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
2439          uiNumSliceSegments ++;
2440        }
2441        nextCtuTsAddr = curSliceSegmentEnd;
2442      }
2443    }
2444
2445#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
2446    if (m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled())
2447    {
2448      xBuildTileSetsMap(pcPic->getPicSym());
2449    }
2450#endif
2451
2452    duData.clear();
2453    pcSlice = pcPic->getSlice(0);
2454
2455    // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
2456    if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoCtuBoundary() )
2457    {
2458      m_pcSAO->getPreDBFStatistics(pcPic);
2459    }
2460
2461    //-- Loop filter
2462    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
2463    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
2464    if ( m_pcCfg->getDeblockingFilterMetric() )
2465    {
2466      applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
2467    }
2468    m_pcLoopFilter->loopFilterPic( pcPic );
2469
2470    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
2471    // Set entropy coder
2472    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
2473
2474    if ( m_bSeqFirst )
2475    {
2476      // write various parameter sets
2477      actualTotalBits += xWriteParameterSets(accessUnit, pcSlice);
2478
2479      // create prefix SEI messages at the beginning of the sequence
2480      assert(leadingSeiMessages.empty());
2481      xCreateIRAPLeadingSEIMessages(leadingSeiMessages, pcSlice->getSPS(), pcSlice->getPPS());
2482
2483      m_bSeqFirst = false;
2484    }
2485#if SVC_EXTENSION && CGS_3D_ASYMLUT
2486    else if( m_pcCfg->getCGSFlag() && pcSlice->getLayerId() && pcSlice->getCGSOverWritePPS() )
2487    {
2488      OutputNALUnit nalu(NAL_UNIT_PPS, 0, m_layerId);
2489      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2490      m_pcEntropyCoder->encodePPS(pcSlice->getPPS() , &m_Enc3DAsymLUTPPS );
2491      accessUnit.push_back(new NALUnitEBSP(nalu));
2492    }
2493#endif
2494
2495    if (m_pcCfg->getAccessUnitDelimiter())
2496    {
2497      xWriteAccessUnitDelimiter(accessUnit, pcSlice);
2498    }
2499
2500    // reset presence of BP SEI indication
2501    m_bufferingPeriodSEIPresentInAU = false;
2502    // create prefix SEI associated with a picture
2503    xCreatePerPictureSEIMessages(iGOPid, leadingSeiMessages, nestedSeiMessages, pcSlice);
2504
2505    /* use the main bitstream buffer for storing the marshalled picture */
2506    m_pcEntropyCoder->setBitstream(NULL);
2507
2508    pcSlice = pcPic->getSlice(0);
2509
2510
2511#if HIGHER_LAYER_IRAP_SKIP_FLAG
2512    if ( pcSlice->getSPS()->getUseSAO() && !( m_pcEncTop->getSkipPictureAtArcSwitch() && m_pcEncTop->getAdaptiveResolutionChange() > 0 && pcSlice->getLayerId() == 1 && pcSlice->getPOC() == m_pcEncTop->getAdaptiveResolutionChange()) )
2513#else
2514    if (pcSlice->getSPS()->getUseSAO())
2515#endif
2516    {
2517      Bool sliceEnabled[MAX_NUM_COMPONENT];
2518      TComBitCounter tempBitCounter;
2519      tempBitCounter.resetBits();
2520      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(&tempBitCounter);
2521      m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
2522      m_pcSAO->SAOProcess(pcPic, sliceEnabled, pcPic->getSlice(0)->getLambdas(), m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary());
2523      m_pcSAO->PCMLFDisableProcess(pcPic);
2524      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(NULL);
2525
2526      //assign SAO slice header
2527      for(Int s=0; s< uiNumSliceSegments; s++)
2528      {
2529        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, sliceEnabled[COMPONENT_Y]);
2530        assert(sliceEnabled[COMPONENT_Cb] == sliceEnabled[COMPONENT_Cr]);
2531        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sliceEnabled[COMPONENT_Cb]);
2532      }
2533    }
2534
2535    // pcSlice is currently slice 0.
2536    std::size_t binCountsInNalUnits   = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
2537    std::size_t numBytesInVclNalUnits = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
2538
2539    for( UInt sliceSegmentStartCtuTsAddr = 0, sliceIdxCount=0; sliceSegmentStartCtuTsAddr < pcPic->getPicSym()->getNumberOfCtusInFrame(); sliceIdxCount++, sliceSegmentStartCtuTsAddr=pcSlice->getSliceSegmentCurEndCtuTsAddr() )
2540    {
2541      pcSlice = pcPic->getSlice(sliceIdxCount);
2542      if(sliceIdxCount > 0 && pcSlice->getSliceType()!= I_SLICE)
2543      {
2544        pcSlice->checkColRefIdx(sliceIdxCount, pcPic);
2545      }
2546      pcPic->setCurrSliceIdx(sliceIdxCount);
2547      m_pcSliceEncoder->setSliceIdx(sliceIdxCount);
2548
2549      pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
2550      pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
2551
2552      for ( UInt ui = 0 ; ui < numSubstreams; ui++ )
2553      {
2554        substreamsOut[ui].clear();
2555      }
2556
2557      m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
2558      m_pcEntropyCoder->resetEntropy      ( pcSlice );
2559      /* start slice NALunit */
2560#if SVC_EXTENSION
2561      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId );
2562#else
2563      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
2564#endif
2565      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2566
2567#if SVC_EXTENSION
2568      if( pcSlice->isIRAP() )
2569      {
2570        //the inference for NoOutputPriorPicsFlag
2571        // KJS: This cannot happen at the encoder
2572        if (!m_bFirst && pcSlice->isIRAP() && m_noRaslOutputFlag)
2573        {
2574          if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
2575          {
2576            pcSlice->setNoOutputPriorPicsFlag(true);
2577          }
2578        }
2579      }
2580#else
2581      pcSlice->setNoRaslOutputFlag(false);
2582      if (pcSlice->isIRAP())
2583      {
2584        if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
2585        {
2586          pcSlice->setNoRaslOutputFlag(true);
2587        }
2588        //the inference for NoOutputPriorPicsFlag
2589        // KJS: This cannot happen at the encoder
2590        if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
2591        {
2592          if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
2593          {
2594            pcSlice->setNoOutputPriorPicsFlag(true);
2595          }
2596        }
2597      }
2598#endif
2599
2600      pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
2601
2602      tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2603      m_pcEntropyCoder->encodeSliceHeader(pcSlice);
2604      actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2605
2606      pcSlice->setFinalized(true);
2607
2608      pcSlice->clearSubstreamSizes(  );
2609      {
2610        UInt numBinsCoded = 0;
2611        m_pcSliceEncoder->encodeSlice(pcPic, &(substreamsOut[0]), numBinsCoded);
2612        binCountsInNalUnits+=numBinsCoded;
2613      }
2614
2615      {
2616        // Construct the final bitstream by concatenating substreams.
2617        // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
2618        // Complete the slice header info.
2619        m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
2620        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2621#if SVC_EXTENSION
2622        tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2623        m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2624        actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2625        m_pcEntropyCoder->encodeSliceHeaderExtn( pcSlice, actualHeadBits );
2626#else
2627        m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2628#endif
2629
2630        // Append substreams...
2631        TComOutputBitstream *pcOut = pcBitstreamRedirect;
2632        const Int numZeroSubstreamsAtStartOfSlice  = pcPic->getSubstreamForCtuAddr(pcSlice->getSliceSegmentCurStartCtuTsAddr(), false, pcSlice);
2633        const Int numSubstreamsToCode  = pcSlice->getNumberOfSubstreamSizes()+1;
2634        for ( UInt ui = 0 ; ui < numSubstreamsToCode; ui++ )
2635        {
2636          pcOut->addSubstream(&(substreamsOut[ui+numZeroSubstreamsAtStartOfSlice]));
2637        }
2638      }
2639
2640      // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
2641      // 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.
2642      Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
2643      xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
2644      accessUnit.push_back(new NALUnitEBSP(nalu));
2645      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2646      numBytesInVclNalUnits += (std::size_t)(accessUnit.back()->m_nalUnitData.str().size());
2647      bNALUAlignedWrittenToList = true;
2648
2649      if (!bNALUAlignedWrittenToList)
2650      {
2651        nalu.m_Bitstream.writeAlignZero();
2652        accessUnit.push_back(new NALUnitEBSP(nalu));
2653      }
2654
2655      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2656          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2657          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
2658         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
2659          ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
2660      {
2661          UInt numNalus = 0;
2662        UInt numRBSPBytes = 0;
2663        for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2664        {
2665          numRBSPBytes += UInt((*it)->m_nalUnitData.str().size());
2666          numNalus ++;
2667        }
2668        duData.push_back(DUData());
2669        duData.back().accumBitsDU = ( numRBSPBytes << 3 );
2670        duData.back().accumNalsDU = numNalus;
2671      }
2672    } // end iteration over slices
2673
2674    // cabac_zero_words processing
2675    cabac_zero_word_padding(pcSlice, pcPic, binCountsInNalUnits, numBytesInVclNalUnits, accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled());
2676
2677    pcPic->compressMotion();
2678
2679    //-- For time output for each slice
2680    Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
2681
2682    std::string digestStr;
2683    if (m_pcCfg->getDecodedPictureHashSEIType()!=HASHTYPE_NONE)
2684    {
2685      SEIDecodedPictureHash *decodedPictureHashSei = new SEIDecodedPictureHash();
2686      m_seiEncoder.initDecodedPictureHashSEI(decodedPictureHashSei, pcPic, digestStr, pcSlice->getSPS()->getBitDepths());
2687      trailingSeiMessages.push_back(decodedPictureHashSei);
2688    }
2689
2690#if O0164_MULTI_LAYER_HRD
2691    xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getVPS(), pcSlice->getSPS());
2692#else
2693    xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS());
2694#endif
2695
2696    m_pcCfg->setEncodedFlag(iGOPid, true);
2697
2698    xCalculateAddPSNRs( isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, dEncTime, snr_conversion, printFrameMSE );
2699
2700    printHash(m_pcCfg->getDecodedPictureHashSEIType(), digestStr);
2701
2702    if ( m_pcCfg->getUseRateCtrl() )
2703    {
2704      Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
2705      Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
2706      if ( avgLambda < 0.0 )
2707      {
2708        avgLambda = lambda;
2709      }
2710
2711      m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
2712      m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
2713
2714      m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
2715      if ( pcSlice->getSliceType() != I_SLICE )
2716      {
2717        m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
2718      }
2719      else    // for intra picture, the estimated bits are used to update the current status in the GOP
2720      {
2721        m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
2722      }
2723#if U0132_TARGET_BITS_SATURATION
2724      if (m_pcRateCtrl->getCpbSaturationEnabled())
2725      {
2726        m_pcRateCtrl->updateCpbState(actualTotalBits);
2727        printf(" [CPB %6d bits]", m_pcRateCtrl->getCpbState());
2728      }
2729#endif
2730    }
2731
2732    xCreatePictureTimingSEI(m_pcCfg->getEfficientFieldIRAPEnabled()?effFieldIRAPMap.GetIRAPGOPid():0, leadingSeiMessages, nestedSeiMessages, duInfoSeiMessages, pcSlice, isField, duData);
2733    if (m_pcCfg->getScalableNestingSEIEnabled())
2734    {
2735      xCreateScalableNestingSEI (leadingSeiMessages, nestedSeiMessages);
2736    }
2737#if O0164_MULTI_LAYER_HRD
2738    xWriteLeadingSEIMessages(leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getVPS(), pcSlice->getSPS(), duData);
2739    xWriteDuSEIMessages(duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getVPS(), pcSlice->getSPS(), duData);
2740#else
2741    xWriteLeadingSEIMessages(leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);
2742    xWriteDuSEIMessages(duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);
2743#endif
2744
2745#if SVC_EXTENSION
2746    m_prevPicHasEos = false;
2747    if (m_pcCfg->getLayerSwitchOffBegin() < m_pcCfg->getLayerSwitchOffEnd())
2748    {
2749      Int pocNext;
2750      if (iGOPid == m_iGopSize - 1)
2751      {
2752        pocNext = iPOCLast - iNumPicRcvd + m_iGopSize + m_pcCfg->getGOPEntry(0).m_POC;
2753      }
2754      else
2755      {
2756        pocNext = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid + 1).m_POC;
2757      }
2758
2759      if (pocNext > m_pcCfg->getLayerSwitchOffBegin() && pocCurr < m_pcCfg->getLayerSwitchOffEnd())
2760      {
2761        OutputNALUnit nalu(NAL_UNIT_EOS, 0, pcSlice->getLayerId());
2762        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder);
2763        accessUnit.push_back(new NALUnitEBSP(nalu));
2764        m_prevPicHasEos = true;
2765      }
2766    }
2767#endif
2768
2769    pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
2770
2771#if SVC_EXTENSION
2772    pcPicYuvRecOut->setReconstructed(true);
2773    m_pcEncTop->setFirstPicInLayerDecodedFlag(true);
2774#endif
2775
2776    pcPic->setReconMark   ( true );
2777    m_bFirst = false;
2778    m_iNumPicCoded++;
2779    m_totalCoded ++;
2780    /* logging: insert a newline at end of picture period */
2781    printf("\n");
2782    fflush(stdout);
2783
2784    if (m_pcCfg->getEfficientFieldIRAPEnabled())
2785    {
2786      iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
2787    }
2788  } // iGOPid-loop
2789
2790  delete pcBitstreamRedirect;
2791
2792#if SVC_EXTENSION
2793  assert ( m_iNumPicCoded <= 1 );
2794#else
2795  assert ( (m_iNumPicCoded == iNumPicRcvd) );
2796#endif
2797}
2798
2799Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths)
2800{
2801  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
2802
2803
2804  //--CFG_KDY
2805  const Int rateMultiplier=(isField?2:1);
2806  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2807  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2808  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2809  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2810  const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();
2811
2812  //-- all
2813  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
2814  m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2815
2816  printf( "\n\nI Slices--------------------------------------------------------\n" );
2817  m_gcAnalyzeI.printOut('i', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2818
2819  printf( "\n\nP Slices--------------------------------------------------------\n" );
2820  m_gcAnalyzeP.printOut('p', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2821
2822  printf( "\n\nB Slices--------------------------------------------------------\n" );
2823  m_gcAnalyzeB.printOut('b', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2824
2825  if (!m_pcCfg->getSummaryOutFilename().empty())
2826  {
2827    m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());
2828  }
2829
2830  if (!m_pcCfg->getSummaryPicFilenameBase().empty())
2831  {
2832    m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"I.txt");
2833    m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"P.txt");
2834    m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"B.txt");
2835  }
2836
2837  if(isField)
2838  {
2839    //-- interlaced summary
2840    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
2841    m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());
2842    // prior to the above statement, the interlace analyser does not contain the correct total number of bits.
2843
2844    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
2845    m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2846
2847    if (!m_pcCfg->getSummaryOutFilename().empty())
2848    {
2849      m_gcAnalyzeAll_in.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());
2850    }
2851  }
2852
2853  printf("\nRVM: %.3lf\n" , xCalculateRVM());
2854}
2855
2856Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist )
2857{
2858  Bool bCalcDist = false;
2859  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
2860  m_pcLoopFilter->loopFilterPic( pcPic );
2861
2862  if (!bCalcDist)
2863  {
2864    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getPicSym()->getSPS().getBitDepths());
2865  }
2866}
2867
2868// ====================================================================================================================
2869// Protected member functions
2870// ====================================================================================================================
2871
2872
2873Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, Bool isField )
2874{
2875  assert( iNumPicRcvd > 0 );
2876  //  Exception for the first frames
2877  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
2878  {
2879    m_iGopSize    = 1;
2880  }
2881  else
2882  {
2883    m_iGopSize    = m_pcCfg->getGOPSize();
2884  }
2885  assert (m_iGopSize > 0);
2886
2887  return;
2888}
2889
2890
2891Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
2892                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
2893                         Int                       iNumPicRcvd,
2894                         Int                       iTimeOffset,
2895                         TComPic*&                 rpcPic,
2896                         TComPicYuv*&              rpcPicYuvRecOut,
2897                         Int                       pocCurr,
2898                         Bool                      isField)
2899{
2900  Int i;
2901  //  Rec. output
2902  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
2903
2904  if (isField && pocCurr > 1 && m_iGopSize!=1)
2905  {
2906    iTimeOffset--;
2907  }
2908
2909  for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
2910  {
2911    iterPicYuvRec--;
2912  }
2913
2914  rpcPicYuvRecOut = *(iterPicYuvRec);
2915
2916  //  Current pic.
2917  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
2918  while (iterPic != rcListPic.end())
2919  {
2920    rpcPic = *(iterPic);
2921    rpcPic->setCurrSliceIdx(0);
2922    if (rpcPic->getPOC() == pocCurr)
2923    {
2924      break;
2925    }
2926    iterPic++;
2927  }
2928
2929  assert (rpcPic != NULL);
2930  assert (rpcPic->getPOC() == pocCurr);
2931
2932  return;
2933}
2934
2935UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1, const BitDepths &bitDepths)
2936{
2937  UInt64  uiTotalDiff = 0;
2938
2939  for(Int chan=0; chan<pcPic0 ->getNumberValidComponents(); chan++)
2940  {
2941    const ComponentID ch=ComponentID(chan);
2942    Pel*  pSrc0   = pcPic0 ->getAddr(ch);
2943    Pel*  pSrc1   = pcPic1 ->getAddr(ch);
2944    UInt  uiShift     = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepths.recon[toChannelType(ch)]-8);
2945
2946    const Int   iStride = pcPic0->getStride(ch);
2947    const Int   iWidth  = pcPic0->getWidth(ch);
2948    const Int   iHeight = pcPic0->getHeight(ch);
2949
2950    for(Int y = 0; y < iHeight; y++ )
2951    {
2952      for(Int x = 0; x < iWidth; x++ )
2953      {
2954        Intermediate_Int iTemp = pSrc0[x] - pSrc1[x];
2955        uiTotalDiff += UInt64((iTemp*iTemp) >> uiShift);
2956      }
2957      pSrc0 += iStride;
2958      pSrc1 += iStride;
2959    }
2960  }
2961
2962  return uiTotalDiff;
2963}
2964
2965Void TEncGOP::xCalculateAddPSNRs( const Bool isField, const Bool isFieldTopFieldFirst, const Int iGOPid, TComPic* pcPic, const AccessUnit&accessUnit, TComList<TComPic*> &rcListPic, const Double dEncTime, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
2966{
2967  xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
2968
2969  //In case of field coding, compute the interlaced PSNR for both fields
2970  if(isField)
2971  {
2972    Bool bothFieldsAreEncoded = false;
2973    Int correspondingFieldPOC = pcPic->getPOC();
2974    Int currentPicGOPPoc = m_pcCfg->getGOPEntry(iGOPid).m_POC;
2975    if(pcPic->getPOC() == 0)
2976    {
2977      // particular case for POC 0 and 1.
2978      // If they are not encoded first and separately from other pictures, we need to change this
2979      // POC 0 is always encoded first then POC 1 is encoded
2980      bothFieldsAreEncoded = false;
2981    }
2982    else if(pcPic->getPOC() == 1)
2983    {
2984      // if we are at POC 1, POC 0 has been encoded for sure
2985      correspondingFieldPOC = 0;
2986      bothFieldsAreEncoded = true;
2987    }
2988    else
2989    {
2990      if(pcPic->getPOC()%2 == 1)
2991      {
2992        correspondingFieldPOC -= 1; // all odd POC are associated with the preceding even POC (e.g poc 1 is associated to poc 0)
2993        currentPicGOPPoc      -= 1;
2994      }
2995      else
2996      {
2997        correspondingFieldPOC += 1; // all even POC are associated with the following odd POC (e.g poc 0 is associated to poc 1)
2998        currentPicGOPPoc      += 1;
2999      }
3000      for(Int i = 0; i < m_iGopSize; i ++)
3001      {
3002        if(m_pcCfg->getGOPEntry(i).m_POC == currentPicGOPPoc)
3003        {
3004          bothFieldsAreEncoded = m_pcCfg->getGOPEntry(i).m_isEncoded;
3005          break;
3006        }
3007      }
3008    }
3009
3010    if(bothFieldsAreEncoded)
3011    {
3012      //get complementary top field
3013      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
3014      while ((*iterPic)->getPOC() != correspondingFieldPOC)
3015      {
3016        iterPic ++;
3017      }
3018      TComPic* correspondingFieldPic = *(iterPic);
3019
3020      if( (pcPic->isTopField() && isFieldTopFieldFirst) || (!pcPic->isTopField() && !isFieldTopFieldFirst))
3021      {
3022        xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getPicYuvRec(), correspondingFieldPic->getPicYuvRec(), snr_conversion, printFrameMSE );
3023      }
3024      else
3025      {
3026        xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getPicYuvRec(), pcPic->getPicYuvRec(), snr_conversion, printFrameMSE );
3027      }
3028    }
3029  }
3030}
3031
3032Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3033{
3034  Double  dPSNR[MAX_NUM_COMPONENT];
3035
3036  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3037  {
3038    dPSNR[i]=0.0;
3039  }
3040
3041  TComPicYuv cscd;
3042  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3043  {
3044    cscd.createWithoutCUInfo(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat() );
3045    TVideoIOYuv::ColourSpaceConvert(*pcPicD, cscd, conversion, false);
3046  }
3047  TComPicYuv &picd=(conversion==IPCOLOURSPACE_UNCHANGED)?*pcPicD : cscd;
3048
3049  //===== calculate PSNR =====
3050  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3051
3052  for(Int chan=0; chan<pcPicD->getNumberValidComponents(); chan++)
3053  {
3054    const ComponentID ch=ComponentID(chan);
3055    const TComPicYuv *pOrgPicYuv =(conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg() : pcPic ->getPicYuvOrg();
3056    const Pel*  pOrg       = pOrgPicYuv->getAddr(ch);
3057    const Int   iOrgStride = pOrgPicYuv->getStride(ch);
3058    Pel*  pRec             = picd.getAddr(ch);
3059    const Int   iRecStride = picd.getStride(ch);
3060    const Int   iWidth  = pcPicD->getWidth (ch) - (m_pcEncTop->getPad(0) >> pcPic->getComponentScaleX(ch));
3061    const Int   iHeight = pcPicD->getHeight(ch) - ((m_pcEncTop->getPad(1) >> (pcPic->isField()?1:0)) >> pcPic->getComponentScaleY(ch));
3062
3063    Int   iSize   = iWidth*iHeight;
3064
3065    UInt64 uiSSDtemp=0;
3066    for(Int y = 0; y < iHeight; y++ )
3067    {
3068      for(Int x = 0; x < iWidth; x++ )
3069      {
3070        Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3071        uiSSDtemp   += iDiff * iDiff;
3072      }
3073      pOrg += iOrgStride;
3074      pRec += iRecStride;
3075    }
3076    const Int maxval = 255 << (pcPic->getPicSym()->getSPS().getBitDepth(toChannelType(ch)) - 8);
3077    const Double fRefValue = (Double) maxval * maxval * iSize;
3078    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3079    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize);
3080  }
3081
3082
3083  /* calculate the size of the access unit, excluding:
3084   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3085   *  - SEI NAL units
3086   */
3087  UInt numRBSPBytes = 0;
3088  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3089  {
3090    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3091    if (m_pcCfg->getSummaryVerboseness() > 0)
3092    {
3093      printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
3094    }
3095    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3096    {
3097      numRBSPBytes += numRBSPBytes_nal;
3098    }
3099  }
3100
3101  UInt uibits = numRBSPBytes * 8;
3102  m_vRVM_RP.push_back( uibits );
3103
3104  //===== add PSNR =====
3105  m_gcAnalyzeAll.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3106  TComSlice*  pcSlice = pcPic->getSlice(0);
3107  if (pcSlice->isIntra())
3108  {
3109    m_gcAnalyzeI.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3110  }
3111  if (pcSlice->isInterP())
3112  {
3113    m_gcAnalyzeP.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3114  }
3115  if (pcSlice->isInterB())
3116  {
3117    m_gcAnalyzeB.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3118  }
3119
3120  TChar c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
3121  if (!pcSlice->isReferenced())
3122  {
3123    c += 32;
3124  }
3125
3126#if SVC_EXTENSION
3127#if ADAPTIVE_QP_SELECTION 
3128  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, nQP %d QP %d ) %10d bits",
3129         pcSlice->getPOC(),
3130         pcSlice->getLayerId(),
3131         pcSlice->getTLayer(),
3132         c,
3133         nalUnitTypeToString( pcSlice->getNalUnitType() ),
3134         pcSlice->getSliceQpBase(),
3135         pcSlice->getSliceQp(),
3136         uibits );
3137#else
3138  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP %d ) %10d bits",
3139         pcSlice->getPOC()-pcSlice->getLastIDR(),
3140         pcSlice->getLayerId(),
3141         pcSlice->getTLayer(),
3142         c,
3143         nalUnitTypeToString( pcSlice->getNalUnitType() ),
3144         pcSlice->getSliceQp(),
3145         uibits );
3146#endif
3147#else
3148#if ADAPTIVE_QP_SELECTION
3149  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3150         pcSlice->getPOC(),
3151         pcSlice->getTLayer(),
3152         c,
3153         pcSlice->getSliceQpBase(),
3154         pcSlice->getSliceQp(),
3155         uibits );
3156#else
3157  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3158         pcSlice->getPOC()-pcSlice->getLastIDR(),
3159         pcSlice->getTLayer(),
3160         c,
3161         pcSlice->getSliceQp(),
3162         uibits );
3163#endif
3164#endif
3165
3166  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
3167  if (printFrameMSE)
3168  {
3169    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3170  }
3171  printf(" [ET %5.0f ]", dEncTime );
3172
3173  // printf(" [WP %d]", pcSlice->getUseWeightedPrediction());
3174
3175  for (Int iRefList = 0; iRefList < 2; iRefList++)
3176  {
3177    printf(" [L%d ", iRefList);
3178    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
3179    {
3180#if SVC_EXTENSION
3181      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) )
3182      {
3183        UInt refLayerId = pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId();
3184        UInt refLayerIdc = pcSlice->getReferenceLayerIdc(refLayerId);
3185        assert( pcSlice->getPic()->getPosScalingFactor(refLayerIdc, 0) );
3186        assert( pcSlice->getPic()->getPosScalingFactor(refLayerIdc, 1) );
3187
3188        printf( "%d(%d, {%1.2f, %1.2f}x)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex), refLayerId, (Double)POS_SCALING_FACTOR_1X/pcSlice->getPic()->getPosScalingFactor(refLayerIdc, 0), (Double)POS_SCALING_FACTOR_1X/pcSlice->getPic()->getPosScalingFactor(refLayerIdc, 1) );
3189      }
3190      else
3191      {
3192        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
3193      }
3194
3195      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
3196      {
3197        printf( "c" );
3198      }
3199
3200      printf( " " );
3201#else
3202      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3203#endif
3204    }
3205    printf("]");
3206  }
3207#if CGS_3D_ASYMLUT
3208  pcPic->setFrameBit( (Int)uibits );
3209  if( m_layerId && pcSlice->getPPS()->getCGSFlag() )
3210  {
3211#if R0179_ENC_OPT_3DLUT_SIZE
3212      m_Enc3DAsymLUTPicUpdate.update3DAsymLUTParam( &m_Enc3DAsymLUTPPS );
3213#else
3214    if( m_Enc3DAsymLUTPPS.getPPSBit() > 0 )
3215      m_Enc3DAsymLUTPicUpdate.copy3DAsymLUT( &m_Enc3DAsymLUTPPS );
3216#endif
3217    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
3218  }
3219#endif
3220
3221  cscd.destroy();
3222}
3223
3224Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgFirstField, TComPic* pcPicOrgSecondField,
3225                                           TComPicYuv* pcPicRecFirstField, TComPicYuv* pcPicRecSecondField,
3226                                           const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3227{
3228  const TComSPS &sps=pcPicOrgFirstField->getPicSym()->getSPS();
3229  Double  dPSNR[MAX_NUM_COMPONENT];
3230  TComPic    *apcPicOrgFields[2]={pcPicOrgFirstField, pcPicOrgSecondField};
3231  TComPicYuv *apcPicRecFields[2]={pcPicRecFirstField, pcPicRecSecondField};
3232
3233  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3234  {
3235    dPSNR[i]=0.0;
3236  }
3237
3238  TComPicYuv cscd[2 /* first/second field */];
3239  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3240  {
3241    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3242    {
3243      TComPicYuv &reconField=*(apcPicRecFields[fieldNum]);
3244      cscd[fieldNum].createWithoutCUInfo(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat() );
3245      TVideoIOYuv::ColourSpaceConvert(reconField, cscd[fieldNum], conversion, false);
3246      apcPicRecFields[fieldNum]=cscd+fieldNum;
3247    }
3248  }
3249
3250  //===== calculate PSNR =====
3251  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3252
3253  assert(apcPicRecFields[0]->getChromaFormat()==apcPicRecFields[1]->getChromaFormat());
3254  const UInt numValidComponents=apcPicRecFields[0]->getNumberValidComponents();
3255
3256  for(Int chan=0; chan<numValidComponents; chan++)
3257  {
3258    const ComponentID ch=ComponentID(chan);
3259    assert(apcPicRecFields[0]->getWidth(ch)==apcPicRecFields[1]->getWidth(ch));
3260    assert(apcPicRecFields[0]->getHeight(ch)==apcPicRecFields[1]->getHeight(ch));
3261
3262    UInt64 uiSSDtemp=0;
3263    const Int   iWidth  = apcPicRecFields[0]->getWidth (ch) - (m_pcEncTop->getPad(0) >> apcPicRecFields[0]->getComponentScaleX(ch));
3264    const Int   iHeight = apcPicRecFields[0]->getHeight(ch) - ((m_pcEncTop->getPad(1) >> 1) >> apcPicRecFields[0]->getComponentScaleY(ch));
3265
3266    Int   iSize   = iWidth*iHeight;
3267
3268    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3269    {
3270      TComPic *pcPic=apcPicOrgFields[fieldNum];
3271      TComPicYuv *pcPicD=apcPicRecFields[fieldNum];
3272
3273      const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
3274      Pel*  pRec    = pcPicD->getAddr(ch);
3275      const Int   iStride = pcPicD->getStride(ch);
3276
3277
3278      for(Int y = 0; y < iHeight; y++ )
3279      {
3280        for(Int x = 0; x < iWidth; x++ )
3281        {
3282          Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3283          uiSSDtemp   += iDiff * iDiff;
3284        }
3285        pOrg += iStride;
3286        pRec += iStride;
3287      }
3288    }
3289    const Int maxval = 255 << (sps.getBitDepth(toChannelType(ch)) - 8);
3290    const Double fRefValue = (Double) maxval * maxval * iSize*2;
3291    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3292    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize*2);
3293  }
3294
3295  UInt uibits = 0; // the number of bits for the pair is not calculated here - instead the overall total is used elsewhere.
3296
3297  //===== add PSNR =====
3298  m_gcAnalyzeAll_in.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3299
3300  printf("\n                                      Interlaced frame %d: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", pcPicOrgSecondField->getPOC()/2 , dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
3301  if (printFrameMSE)
3302  {
3303    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3304  }
3305
3306  for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3307  {
3308    cscd[fieldNum].destroy();
3309  }
3310}
3311
3312/** Function for deciding the nal_unit_type.
3313 * \param pocCurr POC of the current picture
3314 * \param lastIDR  POC of the last IDR picture
3315 * \param isField  true to indicate field coding
3316 * \returns the NAL unit type of the picture
3317 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
3318 */
3319NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
3320{
3321  if (pocCurr == 0)
3322  {
3323    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3324  }
3325
3326  if(m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pocCurr == 1)
3327  {
3328    // to avoid the picture becoming an IRAP
3329    return NAL_UNIT_CODED_SLICE_TRAIL_R;
3330  }
3331
3332  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3333  {
3334    if (m_pcCfg->getDecodingRefreshType() == 1)
3335    {
3336      return NAL_UNIT_CODED_SLICE_CRA;
3337    }
3338    else if (m_pcCfg->getDecodingRefreshType() == 2)
3339    {
3340      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3341    }
3342  }
3343
3344#if SVC_POC
3345  if( m_pocCraWithoutReset > 0 && m_associatedIRAPType == NAL_UNIT_CODED_SLICE_CRA )
3346  {
3347    if(pocCurr < m_pocCraWithoutReset)
3348#else
3349  if(m_pocCRA>0)
3350  {
3351    if(pocCurr<m_pocCRA)
3352#endif
3353    {
3354      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3355      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3356      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3357      // controlling the reference pictures used for encoding that leading picture. Such a leading
3358      // picture need not be marked as a TFD picture.
3359      return NAL_UNIT_CODED_SLICE_RASL_R;
3360    }
3361  }
3362  if (lastIDR>0)
3363  {
3364    if (pocCurr < lastIDR)
3365    {
3366      return NAL_UNIT_CODED_SLICE_RADL_R;
3367    }
3368  }
3369  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3370}
3371
3372Double TEncGOP::xCalculateRVM()
3373{
3374  Double dRVM = 0;
3375
3376  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3377  {
3378    // calculate RVM only for lowdelay configurations
3379    std::vector<Double> vRL , vB;
3380    size_t N = m_vRVM_RP.size();
3381    vRL.resize( N );
3382    vB.resize( N );
3383
3384    Int i;
3385    Double dRavg = 0 , dBavg = 0;
3386    vB[RVM_VCEGAM10_M] = 0;
3387    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3388    {
3389      vRL[i] = 0;
3390      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
3391      {
3392        vRL[i] += m_vRVM_RP[j];
3393      }
3394      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
3395      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
3396      dRavg += m_vRVM_RP[i];
3397      dBavg += vB[i];
3398    }
3399
3400    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
3401    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
3402
3403    Double dSigamB = 0;
3404    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3405    {
3406      Double tmp = vB[i] - dBavg;
3407      dSigamB += tmp * tmp;
3408    }
3409    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
3410
3411    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
3412
3413    dRVM = dSigamB / dRavg * f;
3414  }
3415
3416  return( dRVM );
3417}
3418
3419/** Attaches the input bitstream to the stream in the output NAL unit
3420    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
3421 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
3422 *  \param rNalu          target NAL unit
3423 */
3424Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* codedSliceData)
3425{
3426  // Byte-align
3427  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
3428
3429  // Perform bitstream concatenation
3430  if (codedSliceData->getNumberOfWrittenBits() > 0)
3431  {
3432    rNalu.m_Bitstream.addSubstream(codedSliceData);
3433  }
3434
3435  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
3436
3437  codedSliceData->clear();
3438}
3439
3440// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
3441// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
3442Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
3443{
3444  if(pcSlice->getRPS()->getNumberOfLongtermPictures() == 0)
3445  {
3446    return;
3447  }
3448  // we can only modify the local RPS!
3449  assert (pcSlice->getRPSidx()==-1);
3450  TComReferencePictureSet *rps = pcSlice->getLocalRPS();
3451
3452  // Arrange long-term reference pictures in the correct order of LSB and MSB,
3453  // and assign values for pocLSBLT and MSB present flag
3454  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
3455  Int longtermPicsMSB[MAX_NUM_REF_PICS];
3456  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
3457  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
3458  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
3459  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
3460  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
3461  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
3462
3463  // Get the long-term reference pictures
3464  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
3465  Int i, ctr = 0;
3466  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
3467  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3468  {
3469    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
3470    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
3471    indices[ctr]      = i;
3472    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
3473  }
3474  Int numLongPics = rps->getNumberOfLongtermPictures();
3475  assert(ctr == numLongPics);
3476
3477  // Arrange pictures in decreasing order of MSB;
3478  for(i = 0; i < numLongPics; i++)
3479  {
3480    for(Int j = 0; j < numLongPics - 1; j++)
3481    {
3482      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
3483      {
3484        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
3485        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
3486        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
3487        std::swap(indices[j]        , indices[j+1]        );
3488      }
3489    }
3490  }
3491
3492  for(i = 0; i < numLongPics; i++)
3493  {
3494    // Check if MSB present flag should be enabled.
3495    // Check if the buffer contains any pictures that have the same LSB.
3496    TComList<TComPic*>::iterator  iterPic = rcListPic.begin();
3497    TComPic*                      pcPic;
3498    while ( iterPic != rcListPic.end() )
3499    {
3500      pcPic = *iterPic;
3501      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
3502                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
3503                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
3504      {
3505        mSBPresentFlag[i] = true;
3506        break;
3507      }
3508      iterPic++;
3509    }
3510  }
3511
3512  // tempArray for usedByCurr flag
3513  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
3514  for(i = 0; i < numLongPics; i++)
3515  {
3516    tempArray[i] = rps->getUsed(indices[i]);
3517  }
3518  // Now write the final values;
3519  ctr = 0;
3520  Int currMSB = 0, currLSB = 0;
3521  // currPicPoc = currMSB + currLSB
3522  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB);
3523  currMSB = pcSlice->getPOC() - currLSB;
3524
3525  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3526  {
3527    rps->setPOC                   (i, longtermPicsPoc[ctr]);
3528    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
3529    rps->setUsed                  (i, tempArray[ctr]);
3530    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
3531    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
3532    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);
3533
3534    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
3535  }
3536  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
3537  {
3538    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
3539    {
3540      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
3541      // don't have to check the MSB present flag values for this constraint.
3542      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
3543    }
3544  }
3545}
3546
3547Void TEncGOP::applyDeblockingFilterMetric( TComPic* pcPic, UInt uiNumSlices )
3548{
3549  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
3550  Pel* Rec    = pcPicYuvRec->getAddr(COMPONENT_Y);
3551  Pel* tempRec = Rec;
3552  Int  stride = pcPicYuvRec->getStride(COMPONENT_Y);
3553  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
3554  UInt maxTBsize = (1<<log2maxTB);
3555  const UInt minBlockArtSize = 8;
3556  const UInt picWidth = pcPicYuvRec->getWidth(COMPONENT_Y);
3557  const UInt picHeight = pcPicYuvRec->getHeight(COMPONENT_Y);
3558  const UInt noCol = (picWidth>>log2maxTB);
3559  const UInt noRows = (picHeight>>log2maxTB);
3560  assert(noCol > 1);
3561  assert(noRows > 1);
3562  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
3563  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
3564  UInt colIdx = 0;
3565  UInt rowIdx = 0;
3566  Pel p0, p1, p2, q0, q1, q2;
3567
3568  Int qp = pcPic->getSlice(0)->getSliceQp();
3569  const Int bitDepthLuma=pcPic->getSlice(0)->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
3570  Int bitdepthScale = 1 << (bitDepthLuma-8);
3571  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
3572  const Int thr2 = (beta>>2);
3573  const Int thr1 = 2*bitdepthScale;
3574  UInt a = 0;
3575
3576  memset(colSAD, 0, noCol*sizeof(UInt64));
3577  memset(rowSAD, 0, noRows*sizeof(UInt64));
3578
3579  if (maxTBsize > minBlockArtSize)
3580  {
3581    // Analyze vertical artifact edges
3582    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
3583    {
3584      for(Int r = 0; r < picHeight; r++)
3585      {
3586        p2 = Rec[c-3];
3587        p1 = Rec[c-2];
3588        p0 = Rec[c-1];
3589        q0 = Rec[c];
3590        q1 = Rec[c+1];
3591        q2 = Rec[c+2];
3592        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3593        if ( thr1 < a && a < thr2)
3594        {
3595          colSAD[colIdx] += abs(p0 - q0);
3596        }
3597        Rec += stride;
3598      }
3599      colIdx++;
3600      Rec = tempRec;
3601    }
3602
3603    // Analyze horizontal artifact edges
3604    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
3605    {
3606      for(Int c = 0; c < picWidth; c++)
3607      {
3608        p2 = Rec[c + (r-3)*stride];
3609        p1 = Rec[c + (r-2)*stride];
3610        p0 = Rec[c + (r-1)*stride];
3611        q0 = Rec[c + r*stride];
3612        q1 = Rec[c + (r+1)*stride];
3613        q2 = Rec[c + (r+2)*stride];
3614        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3615        if (thr1 < a && a < thr2)
3616        {
3617          rowSAD[rowIdx] += abs(p0 - q0);
3618        }
3619      }
3620      rowIdx++;
3621    }
3622  }
3623
3624  UInt64 colSADsum = 0;
3625  UInt64 rowSADsum = 0;
3626  for(Int c = 0; c < noCol-1; c++)
3627  {
3628    colSADsum += colSAD[c];
3629  }
3630  for(Int r = 0; r < noRows-1; r++)
3631  {
3632    rowSADsum += rowSAD[r];
3633  }
3634
3635  colSADsum <<= 10;
3636  rowSADsum <<= 10;
3637  colSADsum /= (noCol-1);
3638  colSADsum /= picHeight;
3639  rowSADsum /= (noRows-1);
3640  rowSADsum /= picWidth;
3641
3642  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
3643  avgSAD >>= (bitDepthLuma-8);
3644
3645  if ( avgSAD > 2048 )
3646  {
3647    avgSAD >>= 9;
3648    Int offset = Clip3(2,6,(Int)avgSAD);
3649    for (Int i=0; i<uiNumSlices; i++)
3650    {
3651      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
3652      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
3653      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
3654      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
3655    }
3656  }
3657  else
3658  {
3659    for (Int i=0; i<uiNumSlices; i++)
3660    {
3661      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
3662      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
3663      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
3664      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
3665    }
3666  }
3667
3668  free(colSAD);
3669  free(rowSAD);
3670}
3671
3672#if SVC_EXTENSION
3673#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3674Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym)
3675{
3676  Int numCUs = picSym->getFrameWidthInCtus() * picSym->getFrameHeightInCtus();
3677
3678  for (Int i = 0; i < numCUs; i++)
3679  {
3680    picSym->setTileSetIdxMap(i, -1, 0, false);
3681  }
3682
3683  for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
3684  {
3685    const TComTile* topLeftTile     = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i));
3686    TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i));
3687    Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCtus() - topLeftTile->getTileWidthInCtus() + 1;
3688    Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCtus();
3689    Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCtus() - topLeftTile->getTileHeightInCtus() + 1;
3690    Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCtus();
3691    assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU);
3692    for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++)
3693    {
3694      for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++)
3695      {
3696        picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCtus() + k, i, m_pcCfg->getIlcIdc(i), false);
3697      }
3698    }
3699  }
3700 
3701  if (m_pcCfg->getSkippedTileSetPresentFlag())
3702  {
3703    Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage();
3704    for (Int i = 0; i < numCUs; i++)
3705    {
3706      if (picSym->getTileSetIdxMap(i) < 0)
3707      {
3708        picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true);
3709      }
3710    }
3711  }
3712}
3713#endif
3714
3715Void TEncGOP::determinePocResetIdc(Int const pocCurr, TComSlice *const slice)
3716{
3717  // If one picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 1 or 2
3718  // If BL picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 2
3719  // If BL picture is IRAP, and another picture is non-IRAP, then the poc_reset_idc is equal to 1 or 2.
3720  slice->setPocMsbNeeded(false);
3721
3722  if( slice->getSliceIdx() == 0 ) // First slice - compute, copy for other slices
3723  {
3724    Int needReset = false;
3725    Int resetDueToBL = false;
3726    if( slice->getVPS()->getMaxLayers() > 1 )
3727    {
3728      // If IRAP is refreshed in this access unit for base layer
3729      if( (m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 1 || m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2)
3730        && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3731        )
3732      {
3733        // Check if the IRAP refresh interval of any layer does not match that of the base layer
3734        for(Int i = 1; i < slice->getVPS()->getMaxLayers(); i++)
3735        {
3736          Bool refreshIntervalFlag = ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 );
3737          Bool refreshTypeFlag     = ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() );
3738          if( !(refreshIntervalFlag && refreshTypeFlag) )
3739          {
3740            needReset = true;
3741            resetDueToBL = true;
3742            break;
3743          }
3744        }
3745      }
3746    }
3747
3748    if( !needReset )// No need reset due to base layer IRAP
3749    {
3750      // Check if EL IDRs results in POC Reset
3751      for(Int i = 1; i < slice->getVPS()->getMaxLayers() && !needReset; i++)
3752      {
3753        Bool idrFlag = ( (m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() == 2) 
3754          && ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3755          );
3756        for(Int j = 0; j < slice->getVPS()->getMaxLayers(); j++)
3757        {
3758          if( j == i )
3759          {
3760            continue;
3761          }
3762
3763          Bool idrOtherPicFlag = ( (m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshType() == 2) 
3764            && ( pocCurr % m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3765            );
3766
3767          if( idrFlag != idrOtherPicFlag )
3768          {
3769            needReset = true;
3770            break;
3771          }
3772        }
3773      }
3774    }
3775    if( needReset )
3776    {
3777      if( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2 )  // BL IDR refresh, assuming BL picture present
3778      {
3779        if( resetDueToBL )
3780        {
3781          slice->setPocResetIdc( 2 ); // Full reset needed
3782
3783          if( slice->getVPS()->getVpsPocLsbAlignedFlag() && slice->getVPS()->getNumDirectRefLayers(slice->getLayerId()) == 0 )
3784          {
3785            slice->setPocMsbNeeded(true);  // Force msb writing
3786          }
3787        }
3788        else
3789        {
3790          slice->setPocResetIdc( 1 ); // Due to IDR in EL
3791        }
3792      }
3793      else
3794      {
3795        slice->setPocResetIdc( 1 ); // Only MSB reset
3796      }
3797
3798      // Start a new POC reset period
3799      if (m_layerId == 0)   // Assuming BL picture is always present at encoder; for other AU structures, need to change this
3800      {
3801        Int periodId = rand() % 64;
3802        m_lastPocPeriodId = (periodId == m_lastPocPeriodId) ? (periodId + 1) % 64 : periodId ;
3803
3804        for( UInt i = 0; i < MAX_LAYERS; i++ )
3805        {
3806          m_ppcTEncTop[i]->setPocDecrementedInDPBFlag(false);
3807        }
3808      }
3809      else
3810      {
3811        m_lastPocPeriodId = m_ppcTEncTop[0]->getGOPEncoder()->getLastPocPeriodId();
3812      }
3813      slice->setPocResetPeriodId(m_lastPocPeriodId);
3814    }
3815    else
3816    {
3817      slice->setPocResetIdc( 0 );
3818    }
3819  }
3820}
3821
3822Void TEncGOP::updatePocValuesOfPics(Int const pocCurr, TComSlice *const slice)
3823{
3824  UInt affectedLayerList[MAX_NUM_LAYER_IDS];
3825  Int  numAffectedLayers;
3826
3827  affectedLayerList[0] = m_layerId;
3828  numAffectedLayers = 1;
3829
3830  if (m_pcEncTop->getVPS()->getVpsPocLsbAlignedFlag())
3831  {
3832    for (UInt j = 0; j < m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId); j++)
3833    {
3834      affectedLayerList[j + 1] = m_pcEncTop->getVPS()->getPredictedLayerId(m_layerId, j);
3835    }
3836    numAffectedLayers = m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId) + 1;
3837  }
3838
3839  Int pocAdjustValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
3840
3841  // New POC reset period
3842  Int maxPocLsb, pocLsbVal, pocMsbDelta, pocLsbDelta, deltaPocVal;
3843
3844  maxPocLsb   = 1 << slice->getSPS()->getBitsForPOC();
3845
3846  Int adjustedPocValue = pocCurr;
3847
3848  if (m_pcEncTop->getFirstPicInLayerDecodedFlag())
3849  {
3850    pocLsbVal   = (slice->getPocResetIdc() == 3)
3851      ? slice->getPocLsbVal()
3852      : pocAdjustValue % maxPocLsb; 
3853    pocMsbDelta = pocAdjustValue - pocLsbVal;
3854    pocLsbDelta = (slice->getPocResetIdc() == 2 || ( slice->getPocResetIdc() == 3 && slice->getFullPocResetFlag() )) 
3855      ? pocLsbVal 
3856      : 0; 
3857    deltaPocVal = pocMsbDelta  + pocLsbDelta;
3858
3859    Int origDeltaPocVal = deltaPocVal;  // original value needed when updating POC adjustment value
3860
3861    // IDR picture in base layer, non-IDR picture in other layers, poc_lsb_aligned_flag = 1
3862    if( slice->getPocMsbNeeded() )
3863    {
3864      if (slice->getLayerId() == 0)
3865      {
3866        Int highestPoc = INT_MIN;
3867
3868        // Find greatest POC in DPB for layer 0
3869        for (TComList<TComPic*>::iterator iterPic = m_pcEncTop->getListPic()->begin(); iterPic != m_pcEncTop->getListPic()->end(); ++iterPic)
3870        {
3871          TComPic *dpbPic = *iterPic;
3872          if (dpbPic->getReconMark() && dpbPic->getLayerId() == 0 && dpbPic->getPOC() > highestPoc)
3873          {
3874            highestPoc = dpbPic->getPOC();
3875          }
3876        }
3877        deltaPocVal = (highestPoc - (highestPoc & (maxPocLsb - 1))) + 1*maxPocLsb;
3878        m_pcEncTop->setCurrPocMsb(deltaPocVal);
3879      }
3880      else
3881      {
3882        deltaPocVal = m_ppcTEncTop[0]->getCurrPocMsb();  // copy from base layer
3883      }
3884      slice->setPocMsbVal(deltaPocVal);
3885    }
3886
3887    for( UInt layerIdx = 0; layerIdx < numAffectedLayers; layerIdx++ )
3888    {
3889      UInt lIdx = slice->getVPS()->getLayerIdxInVps(affectedLayerList[layerIdx]);
3890
3891      if( !m_ppcTEncTop[lIdx]->getPocDecrementedInDPBFlag() )
3892      {
3893        m_ppcTEncTop[lIdx]->setPocDecrementedInDPBFlag(true);
3894
3895        // Decrement value of associatedIrapPoc of the TEncGop object
3896        m_ppcTEncTop[lIdx]->getGOPEncoder()->m_associatedIRAPPOC -= deltaPocVal;
3897
3898        // Decrememnt the value of m_pocCRA
3899        m_ppcTEncTop[lIdx]->getGOPEncoder()->m_pocCRA -= deltaPocVal;
3900
3901        TComList<TComPic*>::iterator  iterPic = m_ppcTEncTop[lIdx]->getListPic()->begin();
3902        while (iterPic != m_ppcTEncTop[lIdx]->getListPic()->end())
3903        {
3904          TComPic *dpbPic = *iterPic;
3905
3906          if( dpbPic->getReconMark() )
3907          {
3908            for( Int i = dpbPic->getNumAllocatedSlice() - 1; i >= 0; i-- )
3909            {
3910              TComSlice *dpbPicSlice = dpbPic->getSlice( i );
3911              TComReferencePictureSet *dpbPicRps = dpbPicSlice->getLocalRPS();
3912
3913              // Decrement POC of slice
3914              dpbPicSlice->setPOC( dpbPicSlice->getPOC() - deltaPocVal );
3915
3916              // Decrement POC value stored in the RPS of each such slice
3917              for( Int j = dpbPicRps->getNumberOfPictures() - 1; j >= 0; j-- )
3918              {
3919                dpbPicRps->setPOC( j, dpbPicRps->getPOC(j) - deltaPocVal );
3920              }
3921             
3922              dpbPicSlice->setRPS(dpbPicRps);
3923
3924              // Decrement value of refPOC
3925              dpbPicSlice->decrementRefPocValues( deltaPocVal );
3926
3927              // Update value of associatedIrapPoc of each slice
3928              dpbPicSlice->setAssociatedIRAPPOC( dpbPicSlice->getAssociatedIRAPPOC() - deltaPocVal );
3929
3930              if( slice->getPocMsbNeeded() )
3931              {
3932                // this delta value is needed when computing delta POCs in reference picture set initialization
3933                dpbPicSlice->setPocResetDeltaPoc(dpbPicSlice->getPocResetDeltaPoc() + (deltaPocVal - pocLsbVal));
3934              }
3935            }
3936          }
3937          iterPic++;
3938        }
3939      }
3940    }
3941
3942    // Actual POC value before reset
3943    adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
3944
3945    // Set MSB value before reset
3946    Int tempLsbVal = adjustedPocValue & (maxPocLsb - 1);
3947    if (!slice->getPocMsbNeeded())  // set poc msb normally if special msb handling is not needed
3948    {
3949      slice->setPocMsbVal(adjustedPocValue - tempLsbVal);
3950    }
3951
3952    // Set LSB value before reset - this is needed in the case of resetIdc = 2
3953    slice->setPicOrderCntLsb( tempLsbVal );
3954
3955    // Cumulative delta
3956    deltaPocVal = origDeltaPocVal;  // restore deltaPoc for correct adjustment value update
3957
3958    m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + deltaPocVal );
3959  }
3960
3961  // New LSB value, after reset
3962  adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
3963  Int newLsbVal = adjustedPocValue & (maxPocLsb - 1);
3964
3965  // Set value of POC current picture after RESET
3966  if( slice->getPocResetIdc() == 1 )
3967  {
3968    slice->setPOC( newLsbVal );
3969  }
3970  else if( slice->getPocResetIdc() == 2 )
3971  {
3972    slice->setPOC( 0 );
3973  }
3974  else if( slice->getPocResetIdc() == 3 )
3975  {
3976    Int picOrderCntMsb = slice->getCurrMsb( newLsbVal, 
3977      slice->getFullPocResetFlag() ? 0 : slice->getPocLsbVal(), 
3978      0,
3979      maxPocLsb );
3980    slice->setPOC( picOrderCntMsb + newLsbVal );
3981  }
3982  else
3983  {
3984    assert(0);
3985  }
3986}
3987
3988#if CGS_3D_ASYMLUT
3989Void TEncGOP::xDetermine3DAsymLUT( TComSlice * pSlice, TComPic * pCurPic, UInt refLayerIdc, TEncCfg * pCfg, Bool bSignalPPS )
3990{
3991  Int nCGSFlag = pSlice->getPPS()->getCGSFlag();
3992  m_Enc3DAsymLUTPPS.setPPSBit( 0 );
3993  Double dErrorUpdatedPPS = 0 , dErrorPPS = 0;
3994
3995#if R0179_ENC_OPT_3DLUT_SIZE
3996  Int nTLthres = m_pcCfg->getCGSLutSizeRDO() ? 2:7;
3997  Double dFrameLambda; 
3998#if FULL_NBIT
3999  Int    SHIFT_QP = 12 + 6 * (pSlice->getBitDepthY() - 8);
4000#else
4001  Int    SHIFT_QP = 12; 
4002#endif
4003  Int QP = pSlice->getSliceQp();
4004
4005  // set frame lambda
4006  dFrameLambda = 0.68 * pow (2, (QP  - SHIFT_QP) / 3.0) * (m_pcCfg->getGOPSize() > 1 && pSlice->isInterB()? 2 : 1);
4007
4008  if(m_pcCfg->getCGSLutSizeRDO() == 1 && (!bSignalPPS && (pSlice->getDepth() < nTLthres)))
4009  {
4010    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB(), dFrameLambda );
4011  }
4012  else if (pSlice->getDepth() >= nTLthres)
4013  {
4014    dErrorUpdatedPPS = MAX_DOUBLE;
4015  }
4016  else // if (m_pcCfg->getCGSLutSizeRDO() = 0 || bSignalPPS)
4017#endif   
4018    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() );
4019
4020
4021  if( bSignalPPS )
4022  {
4023    m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4024    pSlice->setCGSOverWritePPS( 1 ); // regular PPS update
4025  }
4026  else if( nCGSFlag )
4027  {
4028#if R0179_ENC_OPT_3DLUT_SIZE
4029    if(pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R || pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N) 
4030    {
4031      pSlice->setCGSOverWritePPS( 0 ); 
4032    }
4033    else if (pSlice->getDepth() >= nTLthres) 
4034    {
4035      pSlice->setCGSOverWritePPS( 0 ); 
4036    }
4037    else
4038    {
4039#endif   
4040      dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc );
4041      Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9;
4042
4043#if R0179_ENC_OPT_3DLUT_SIZE
4044      if( m_pcCfg->getCGSLutSizeRDO() )
4045      {
4046        dErrorPPS = dErrorPPS/m_Enc3DAsymLUTPicUpdate.getDistFactor(pSlice->getSliceType(), pSlice->getDepth()); 
4047      }
4048#endif
4049      pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS );
4050#if R0179_ENC_OPT_3DLUT_SIZE
4051    }
4052#endif
4053    if( pSlice->getCGSOverWritePPS() )
4054    {
4055      m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4056    }
4057  }
4058}
4059
4060Void TEncGOP::xDownScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest, const BitDepths& bitDepth, const Int posScalingFactorX)
4061{
4062  pcYuvSrc->setBorderExtension(false);
4063  pcYuvSrc->extendPicBorder(); // extend the border.
4064  pcYuvSrc->setBorderExtension(false);
4065
4066  Int iWidth  = pcYuvSrc->getWidth(COMPONENT_Y);
4067  Int iHeight = pcYuvSrc->getHeight(COMPONENT_Y); 
4068
4069  if(!m_temp)
4070  {
4071    xInitDs(iWidth, iHeight, m_pcCfg->getIntraPeriod() > 1, posScalingFactorX);
4072  }
4073
4074  xFilterImg(pcYuvSrc->getAddr(COMPONENT_Y),  pcYuvSrc->getStride(COMPONENT_Y),  pcYuvDest->getAddr(COMPONENT_Y),  pcYuvDest->getStride(COMPONENT_Y),  iHeight,    iWidth,    bitDepth, COMPONENT_Y);
4075  xFilterImg(pcYuvSrc->getAddr(COMPONENT_Cb), pcYuvSrc->getStride(COMPONENT_Cb), pcYuvDest->getAddr(COMPONENT_Cb), pcYuvDest->getStride(COMPONENT_Cb), iHeight>>1, iWidth>>1, bitDepth, COMPONENT_Cb);
4076  xFilterImg(pcYuvSrc->getAddr(COMPONENT_Cr), pcYuvSrc->getStride(COMPONENT_Cr), pcYuvDest->getAddr(COMPONENT_Cr), pcYuvDest->getStride(COMPONENT_Cr), iHeight>>1, iWidth>>1, bitDepth, COMPONENT_Cr); 
4077}
4078const Pel TEncGOP::m_phaseFilter0T0[CGS_FILTER_PHASES_2X][CGS_FILTER_LENGTH] =
4079{
4080  {0,  2,  -3,  -9,   6,  39,  58,  39,   6,  -9,  -3,  2,  0}, 
4081  {0,  0,   0,  -2,  8,  -20, 116,  34, -10,   2,   0,  0,  0},            //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
4082  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4083  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8, -1,  1} 
4084};
4085
4086const Pel TEncGOP::m_phaseFilter0T1[CGS_FILTER_PHASES_2X][CGS_FILTER_LENGTH] =
4087{
4088  {0,  4,  0,  -12, 0,  40,  64,  40,   0, -12,  0,  4,  0},
4089  {0,  0,  0,  -2,  8, -20, 116,  34, -10,   2,  0,  0,  0},               //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
4090  {0,  1,  0,  -7, -5,  22,  53,  53,  22,  -5, -7,  0,  1}, 
4091  {0,  0,  1,  -5, -7,  13,  47,  57,  31,  -1, -8, -1,  1} 
4092};
4093
4094const Pel TEncGOP::m_phaseFilter0T1Chroma[CGS_FILTER_PHASES_2X][CGS_FILTER_LENGTH] =
4095{
4096  {0,  0,  0,  0,  0,   0, 128,  0,   0,  0,  0,  0, 0},
4097  {0,  0,  0, -2,  8, -20, 116, 34, -10,  2,  0,  0, 0},                   //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
4098  {0,  1,  0, -7, -5,  22,  53, 53,  22, -5, -7,  0, 1}, 
4099  {0,  0,  1, -5, -7,  13,  47, 57,  31, -1, -8, -1, 1} 
4100};
4101
4102const Pel TEncGOP::m_phaseFilter1[CGS_FILTER_PHASES_1X][CGS_FILTER_LENGTH] =
4103{
4104  {0,  0, 5, -6, -10, 37, 76, 37, -10,  -6, 5, 0,  0},   
4105  {0, -1, 5, -3, -12, 29, 75, 45,  -7,  -8, 5, 0,  0},   
4106  {0, -1, 4, -1, -13, 22, 73, 52,  -3, -10, 4, 1,  0},   
4107  {0, -1, 4,  1, -13, 14, 70, 59,   2, -12, 3, 2, -1}, 
4108  {0, -1, 3,  2, -13,  8, 65, 65,   8, -13, 2, 3, -1},   
4109  {0, -1, 2,  3, -12,  2, 59, 70,  14, -13, 1, 4, -1},   
4110  {0,  0, 1,  4, -10, -3, 52, 73,  22, -13,-1, 4, -1},   
4111  {0,  0, 0,  5,  -8, -7, 45, 75,  29, -12,-3, 5, -1}   
4112};
4113
4114#if CGS_GCC_NO_VECTORIZATION 
4115#ifdef __GNUC__
4116#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
4117#if GCC_VERSION > 40600
4118__attribute__((optimize("no-tree-vectorize")))
4119#endif
4120#endif
4121#endif
4122Void TEncGOP::xFilterImg( Pel *src, Int iSrcStride, Pel *dst, Int iDstStride, Int height, Int width, const BitDepths& bitDepth, ComponentID comp )
4123{
4124  Int height2, width2;
4125
4126  Pel *srcLine = src;
4127  Pel *dstLine = dst;
4128  Int length = m_cgsFilterLength;
4129  Int shift  = bitDepth.recon[CHANNEL_TYPE_LUMA] - bitDepth.recon[CHANNEL_TYPE_CHROMA];
4130  Int shift2 = 2*7 + shift;
4131  Int roundingOffset = (1 << (shift2 - 1));
4132  Int maxVal = (1<<(bitDepth.recon[toChannelType(comp)]-shift))-1;
4133  height2 = (height * m_cgsFilterPhases) / m_iN;
4134  width2  = (width  * m_cgsFilterPhases) / m_iN;
4135
4136  m_phaseFilter = comp == COMPONENT_Y ? m_phaseFilterLuma : m_phaseFilterChroma;
4137
4138  // horizontal filtering
4139  for( Int j1 = 0; j1 < height; j1++ )
4140  {
4141    Int i0 = -m_iN;
4142    Int *tmp = m_temp[j1];
4143   
4144    for( Int i1 = 0; i1 < width2; i1++ )
4145    {
4146      i0 += m_iN;
4147      Int div_i0 = i0 / m_cgsFilterPhases;
4148
4149      Pel *srcTmp =  srcLine + ( div_i0 - (length >> 1));
4150      const Pel *filter = m_phaseFilter[i0 - div_i0 * m_cgsFilterPhases]; // phase_filter[i0 % M]
4151
4152      Int sum = 0;
4153      for(Int k = 0; k < length; k++)
4154      {
4155        sum += (*srcTmp++) * (*filter++);
4156      }
4157      *tmp++ = sum;
4158    }
4159    srcLine += iSrcStride;
4160  }
4161
4162  // pad temp (vertical)
4163  for( Int k = -(length>>1); k<0; k++ )
4164  {
4165    memcpy(m_temp[k], m_temp[0], width2*sizeof(Int));
4166  }
4167
4168  for( Int k = height; k < (height + (length>>1)); k++)
4169  {
4170    memcpy(m_temp[k], m_temp[k-1], (width2) * sizeof(Int));
4171  }
4172
4173  // vertical filtering
4174  Int j0 = comp == COMPONENT_Y ? -m_iN : (1 - m_iN);
4175 
4176  for( Int j1 = 0; j1 < height2; j1++ )
4177  {
4178    j0 += m_iN;
4179    Int div_j0 = j0 / m_cgsFilterPhases;
4180
4181    Pel* dstTmp = dstLine;
4182
4183    Int **temp = &m_temp[div_j0 - (length>>1)];
4184    const Pel *filter = m_phaseFilter[j0 - div_j0 * m_cgsFilterPhases]; // phase_filter[j0 % M]
4185
4186    for( Int i1 = 0; i1 < width2;i1++ )
4187    {
4188      Int sum=0;
4189      for( Int k = 0; k < length; k++ )
4190      {
4191        sum += temp[k][i1] * filter[k];
4192      }
4193      sum = ((sum + roundingOffset) >> shift2);
4194
4195      *dstTmp++ = Clip3<Short>(sum < 0 ? 0 : sum, maxVal, sum);
4196    }
4197    dstLine += iDstStride;
4198  }
4199}
4200
4201Void TEncGOP::xInitDs( const Int iWidth, const Int iHeight, const Bool allIntra, const Int posScalingFactorX )
4202{
4203  m_cgsFilterLength = CGS_FILTER_LENGTH;
4204
4205  if( posScalingFactorX == POS_SCALING_FACTOR_2X )
4206  {
4207    m_cgsFilterPhases = CGS_FILTER_PHASES_2X;
4208    m_iN = 8;
4209    m_phaseFilterLuma = allIntra ? m_phaseFilter0T1 : m_phaseFilter0T0;
4210    m_phaseFilterChroma = m_phaseFilter0T1Chroma;   
4211  }
4212  else
4213  {
4214    m_cgsFilterPhases = CGS_FILTER_PHASES_1X;
4215    m_iN = 12;
4216    m_phaseFilterLuma = m_phaseFilterChroma = m_phaseFilter1;
4217    m_phaseFilter = m_phaseFilter1;
4218  }
4219
4220  xCreate2DArray( &m_temp, iHeight, iWidth * m_cgsFilterPhases/m_iN, m_cgsFilterLength >> 1, 0 );
4221}
4222
4223Int TEncGOP::xCreate2DArray(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX)
4224{
4225  Int i;
4226  Int *curr = NULL;
4227  Int iHeight, iWidth;
4228
4229  iHeight = dim0+2*iPadY;
4230  iWidth = dim1+2*iPadX;
4231  (*array2D) = (Int**)malloc(iHeight*sizeof(Int*));
4232  *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth);
4233
4234  (*array2D)[0] += iPadX;
4235  curr = (*array2D)[0];
4236  for(i = 1 ; i < iHeight; i++)
4237  {
4238    curr += iWidth;
4239    (*array2D)[i] = curr;
4240  }
4241  (*array2D) = &((*array2D)[iPadY]);
4242
4243  return 0;
4244}
4245
4246Void TEncGOP::xDestroy2DArray(Int **array2D, Int iPadY, Int iPadX)
4247{
4248  if (array2D)
4249  {
4250    if (*array2D)
4251    {
4252      xFree(array2D[-iPadY]-iPadX);
4253    }
4254    else 
4255    {
4256      printf("xDestroy2DArray: trying to free unused memory\r\nPress Any Key\r\n");
4257    }
4258
4259    free (&array2D[-iPadY]);
4260  } 
4261  else
4262  {
4263    printf("xDestroy2DArray: trying to free unused memory\r\nPress Any Key\r\n");
4264  }
4265}
4266#endif
4267
4268Void TEncGOP::xCheckLayerReset(TComSlice *slice)
4269{
4270  Bool layerResetFlag;
4271  Int dolLayerId;
4272
4273  if (slice->isIRAP() && slice->getLayerId() > 0)
4274  {
4275    if (m_prevPicHasEos)
4276    {
4277      layerResetFlag = true;
4278      dolLayerId = slice->getLayerId();
4279    }
4280    else if ((slice->isCRA() && slice->getHandleCraAsBlaFlag()) || (slice->isIDR() && slice->getCrossLayerBLAFlag()) || slice->isBLA())
4281    {
4282      layerResetFlag = true;
4283      dolLayerId = slice->getLayerId();
4284    }
4285    else
4286    {
4287      layerResetFlag = false;
4288    }
4289
4290    if (layerResetFlag)
4291    {
4292      for (Int i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
4293      {
4294        Int iLayerId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
4295        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(iLayerId)]->setLayerInitializedFlag(false);
4296        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(iLayerId)]->setFirstPicInLayerDecodedFlag(false);
4297      }
4298
4299      // Each picture that is in the DPB and has nuh_layer_id equal to dolLayerId is marked as "unused for reference".
4300      for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(dolLayerId)]->getListPic()->begin(); pic != m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(dolLayerId)]->getListPic()->end(); pic++)
4301      {
4302        if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
4303        {
4304          (*pic)->getSlice(0)->setReferenced(false);
4305        }
4306      }
4307
4308      // Each picture that is in DPB and has nuh_layer_id equal to any value of IdPredictedLayer[dolLayerId][i]
4309      // for the values of i in range of 0 to NumPredictedLayers[dolLayerId] - 1, inclusive, is marked as "unused for reference"
4310      for (UInt i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
4311      {
4312        UInt predLId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
4313        for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(predLId)]->getListPic()->begin(); pic != m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(predLId)]->getListPic()->end(); pic++)
4314        {
4315          if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
4316          {
4317            (*pic)->getSlice(0)->setReferenced(false);
4318          }
4319        }
4320      }
4321    }
4322  }
4323}
4324
4325Void TEncGOP::xSetNoRaslOutputFlag(TComSlice *slice)
4326{
4327  if (slice->isIRAP())
4328  {
4329    m_noRaslOutputFlag = slice->getHandleCraAsBlaFlag();  // default value
4330    if (slice->isIDR() || slice->isBLA() || m_bFirst || m_prevPicHasEos)
4331    {
4332      m_noRaslOutputFlag = true;
4333    }
4334    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag())
4335    {
4336      Bool refLayersInitialized = true;
4337      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
4338      {
4339        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
4340        if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(refLayerId)]->getLayerInitializedFlag())
4341        {
4342          refLayersInitialized = false;
4343        }
4344      }
4345      if (refLayersInitialized)
4346      {
4347        m_noRaslOutputFlag = true;
4348      }
4349    }
4350  }
4351}
4352
4353Void TEncGOP::xSetLayerInitializedFlag(TComSlice *slice)
4354{
4355  if (slice->isIRAP() && m_noRaslOutputFlag)
4356  {
4357    if (m_layerId == 0)
4358    {
4359      m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4360    }
4361    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag() && slice->getVPS()->getNumDirectRefLayers(m_layerId) == 0)
4362    {
4363      m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4364    }
4365    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag())
4366    {
4367      Bool refLayersInitialized = true;
4368      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
4369      {
4370        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
4371        if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(refLayerId)]->getLayerInitializedFlag())
4372        {
4373          refLayersInitialized = false;
4374        }
4375      }
4376      if (refLayersInitialized)
4377      {
4378        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4379      }
4380    }
4381  }
4382}
4383#endif //SVC_EXTENSION
4384
4385//! \}
Note: See TracBrowser for help on using the repository browser.