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

Last change on this file since 1434 was 1434, checked in by seregin, 9 years ago

port rev 4588

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