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

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

port rev 4412

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